---
title: "앱 매니페스트 레퍼런스 | Tajo"
description: "Stripe Apps 구성에 사용하는 stripe-app.json 매니페스트 파일의 전체 스키마 레퍼런스"
url: https://tajo.io/kr/docs/stripe-apps/app-manifest/
markdown: https://tajo.io/kr/docs/stripe-apps/app-manifest.md
lang: ko-KR
author: "Set Noa"
author_url: https://tajo.io/kr/set-noa/
robots: noindex
---

Tajo 사전 이용 신청

이름과 회사 이메일 주소를 입력하세요. Tajo 이용 신청을 확인할 수 있는 링크를 이메일로 보내드립니다.

# 앱 매니페스트 레퍼런스

[Set Noa](https://tajo.io/kr/set-noa/)

`stripe-app.json` 매니페스트 파일은 Stripe App의 중심 구성 파일입니다. 앱의 식별 정보, 권한, UI 뷰, 보안 정책, 설치 후 동작을 이 파일에서 선언합니다.

Caution

**상태: 예정, 아직 구축되지 않음.** Tajo에는 Stripe App이 없으므로 이 섹션의 어떤 것도 현재 설치할 수 없습니다. 이 페이지에 나오는 앱 식별자, URL, 자격 증명은 실제로 동작하는 엔드포인트가 아니라 예시용 자리표시자입니다.

## 전체 매니페스트 예시

```json
{
  "id": "com.tajo.brevo-integration",
  "version": "1.2.0",
  "name": "Tajo for Brevo",
  "icon": "./assets/icon.png",
  "distribution_type": "public",
  "sandbox_install_compatible": true,
  "stripe_api_access_type": "oauth",
  "allowed_redirect_uris": [
    "https://tajo.io/stripe/callback",
    "https://tajo.io/stripe/oauth/complete"
  ],
  "permissions": [
    {
      "permission": "customer_read",
      "purpose": "Read customer profiles to sync with Brevo contacts"
    },
    {
      "permission": "customer_write",
      "purpose": "Update customer metadata with Brevo sync status"
    },
    {
      "permission": "charge_read",
      "purpose": "Access payment history for Brevo event tracking"
    },
    {
      "permission": "product_read",
      "purpose": "Sync product catalog to Brevo for personalized campaigns"
    },
    {
      "permission": "event_read",
      "purpose": "Read events for Brevo automation triggers"
    },
    {
      "permission": "invoice_read",
      "purpose": "Track invoice lifecycle events in Brevo"
    }
  ],
  "ui_extension": {
    "views": [
      {
        "viewport": "stripe.dashboard.customer.detail",
        "component": "CustomerDetailView"
      },
      {
        "viewport": "stripe.dashboard.customer.list",
        "component": "CustomerListView"
      },
      {
        "viewport": "stripe.dashboard.home.overview",
        "component": "OverviewView"
      },
      {
        "viewport": "stripe.dashboard.drawer.default",
        "component": "DrawerView"
      },
      {
        "viewport": "stripe.dashboard.settings",
        "component": "SettingsView"
      },
      {
        "viewport": "stripe.dashboard.onboarding",
        "component": "OnboardingView"
      }
    ],
    "content_security_policy": {
      "connect-src": [
        "https://api.example.com",
        "https://api.brevo.com"
      ],
      "image-src": [
        "https://cdn.example.com",
        "https://assets.brevo.com"
      ],
      "purpose": "Connect to Tajo API for data sync and Brevo API for contact management"
    }
  },
  "post_install_action": {
    "type": "onboarding"
  },
  "constants": {
    "API_BASE_URL": "https://api.example.com/v1",
    "SYNC_INTERVAL_SECONDS": "300"
  }
}
```

## 스키마 레퍼런스

### 최상위 필드

| 필드 | 타입 | 필수 | 설명 |
| --- | --- | --- | --- |
| `id` | string | 예 | 역방향 도메인 표기법(슬러그 형식)으로 작성한 고유 앱 식별자 |
| `version` | string | 예 | 시맨틱 버전 문자열(예: `"1.2.0"`) |
| `name` | string | 예 | 마켓플레이스에 표시되는 이름(최대 35자) |
| `icon` | string | 예 | 앱 아이콘 파일의 상대 경로(300x300 PNG 또는 SVG) |
| `distribution_type` | string | 예 | 마켓플레이스 배포는 `"public"`, 내부 사용은 `"private"` |
| `sandbox_install_compatible` | boolean | 아니요 | 샌드박스/테스트 모드에 앱을 설치할 수 있는지 여부 |
| `stripe_api_access_type` | string | 아니요 | API 접근 방식: `"oauth"` 또는 `"api_key"` |
| `allowed_redirect_uris` | string\[\] | 아니요 | 설치 플로에서 허용되는 OAuth 리디렉션 URI |
| `permissions` | PermissionRequest\[\] | 예 | 권한 요청 배열 |
| `ui_extension` | UIExtensionManifest | 아니요 | UI 확장 구성 |
| `post_install_action` | PostInstallAction | 아니요 | 앱 설치 후 수행할 동작 |
| `constants` | object | 아니요 | 런타임에 앱에서 접근할 수 있는 키-값 쌍 |

### id

앱 식별자는 슬러그 형식의 문자열이며, 보통 역방향 도메인 표기법을 사용합니다.

```json
"id": "com.tajo.brevo-integration"
```

- 모든 Stripe Apps에서 전역적으로 고유해야 합니다
- 소문자, 숫자, 하이픈, 점만 사용합니다
- 앱을 생성한 뒤에는 변경할 수 없습니다
- 마켓플레이스에서 앱의 URL을 결정합니다

### version

시맨틱 버저닝을 따릅니다.

```json
"version": "1.2.0"
```

- **MAJOR**: 호환성이 깨지는 변경 또는 대규모 기능 추가
- **MINOR**: 하위 호환되는 신규 기능
- **PATCH**: 버그 수정과 소규모 개선
- 업로드할 때마다 반드시 올려야 합니다

### distribution\_type

앱을 설치할 수 있는 대상을 제어합니다.

| 값 | 설명 |
| --- | --- |
| `"public"` | Stripe App Marketplace에서 모든 사용자에게 공개됩니다 |
| `"private"` | 본인의 Stripe 계정에서만 설치할 수 있습니다 |

### stripe\_api\_access\_type

앱이 Stripe API에 인증하는 방식을 결정합니다.

| 값 | 설명 |
| --- | --- |
| `"oauth"` | 인증에 OAuth 2.0 플로를 사용합니다(공개 앱 권장) |
| `"api_key"` | 제한된 API 키를 사용합니다(비공개 앱에 적합) |

## PermissionRequest

각 권한 요청은 앱에 필요한 특정 Stripe API 권한을 선언합니다.

```json
{
  "permission": "customer_read",
  "purpose": "Read customer profiles to sync with Brevo contacts"
}
```

| 필드 | 타입 | 필수 | 설명 |
| --- | --- | --- | --- |
| `permission` | string | 예 | 권한 식별자([권한 레퍼런스](https://tajo.io/kr/docs/stripe-apps/permissions) 참고) |
| `purpose` | string | 예 | 이 권한이 필요한 이유에 대한 사람이 읽을 수 있는 설명 |

**purpose 작성 지침:**

- 판매자가 이해할 수 있도록 명확하고 구체적으로 설명합니다
- 권한이 무엇을 허용하는지가 아니라 무엇에 쓰이는지를 설명합니다
- 설명은 한 문장으로 간결하게 유지합니다
- 기술 전문 용어는 피합니다

## UIExtensionManifest

앱의 UI 컴포넌트를 구성합니다.

```json
{
  "ui_extension": {
    "views": [...],
    "content_security_policy": {...}
  }
}
```

| 필드 | 타입 | 필수 | 설명 |
| --- | --- | --- | --- |
| `views` | ViewManifest\[\] | 예 | 뷰 선언 배열 |
| `content_security_policy` | CSPRequest | 아니요 | 외부 리소스에 대한 콘텐츠 보안 정책 |

## ViewManifest

각 뷰는 React 컴포넌트를 Stripe 대시보드의 뷰포트에 매핑합니다.

```json
{
  "viewport": "stripe.dashboard.customer.detail",
  "component": "CustomerDetailView"
}
```

| 필드 | 타입 | 필수 | 설명 |
| --- | --- | --- | --- |
| `viewport` | string | 예 | 이 뷰가 렌더링되는 대시보드 위치([뷰포트 레퍼런스](https://tajo.io/kr/docs/stripe-apps/viewports) 참고) |
| `component` | string | 예 | 렌더링할 React 컴포넌트 이름(내보낸 컴포넌트 이름과 일치해야 함) |

하나의 앱에서 서로 다른 뷰포트에 여러 뷰를 선언할 수 있습니다.

```json
"views": [
  {
    "viewport": "stripe.dashboard.customer.detail",
    "component": "CustomerDetailView"
  },
  {
    "viewport": "stripe.dashboard.payment.detail",
    "component": "PaymentDetailView"
  },
  {
    "viewport": "stripe.dashboard.home.overview",
    "component": "OverviewView"
  }
]
```

## CSPRequest

콘텐츠 보안 정책은 앱이 연결할 수 있는 외부 도메인을 제어합니다.

```json
{
  "content_security_policy": {
    "connect-src": [
      "https://api.example.com",
      "https://api.brevo.com"
    ],
    "image-src": [
      "https://cdn.example.com"
    ],
    "purpose": "Connect to Tajo API for data sync and load images from CDN"
  }
}
```

| 필드 | 타입 | 필수 | 설명 |
| --- | --- | --- | --- |
| `connect-src` | string\[\] | 아니요 | 앱이 네트워크 요청을 보낼 수 있는 도메인 |
| `image-src` | string\[\] | 아니요 | 앱이 이미지를 불러올 수 있는 도메인 |
| `purpose` | string | 예 | 이러한 외부 연결이 필요한 이유에 대한 설명 |

Caution

앱이 실제로 연결해야 하는 도메인만 포함하세요. CSP 항목이 지나치게 많으면 추가 심사 대상이 될 수 있습니다.

## PostInstallAction

사용자가 앱을 설치한 직후에 일어날 동작을 구성합니다.

```json
{
  "post_install_action": {
    "type": "onboarding"
  }
}
```

| 필드 | 타입 | 필수 | 설명 |
| --- | --- | --- | --- |
| `type` | string | 예 | 동작 유형(아래 참고) |
| `url` | string | 조건부 | `external` 유형 동작에 사용할 URL |

### 동작 유형

| 유형 | 동작 |
| --- | --- |
| `"onboarding"` | 대시보드에서 앱의 온보딩 뷰를 엽니다 |
| `"settings"` | 대시보드에서 앱의 설정 뷰를 엽니다 |
| `"external"` | 사용자를 외부 URL로 리디렉션합니다(`url` 필드 필요) |

예시:

```json
// Open onboarding flow
{
  "post_install_action": {
    "type": "onboarding"
  }
}

// Open settings page
{
  "post_install_action": {
    "type": "settings"
  }
}

// Redirect to external setup
{
  "post_install_action": {
    "type": "external",
    "url": "https://app.tajo.io/stripe/setup"
  }
}
```

자세한 구현 패턴은 [설치 후 동작 가이드](https://tajo.io/kr/docs/stripe-apps/post-install)를 참고하세요.

## 상수

앱 런타임에서 접근할 수 있는 정적 키-값 쌍을 정의합니다.

```json
{
  "constants": {
    "API_BASE_URL": "https://api.example.com/v1",
    "SYNC_INTERVAL_SECONDS": "300",
    "MAX_BATCH_SIZE": "100"
  }
}
```

- 모든 값은 문자열이어야 합니다
- 상수는 빌드 시점에 앱에 포함됩니다
- 환경마다 달라지는 구성값에 상수를 사용하세요
- 시크릿이나 API 키는 **절대** 상수로 저장하지 말고 Secret Store API를 사용하세요

앱 코드에서 상수에 접근하는 방법은 다음과 같습니다.

```typescript
import { constants } from '@stripe/ui-extension-sdk/constants';

const apiUrl = constants.API_BASE_URL;
```

## 개발용 확장 매니페스트

로컬 개발 중에는 추가 필드를 사용할 수 있습니다.

```json
{
  "id": "com.tajo.brevo-integration",
  "version": "0.1.0",
  "name": "Tajo for Brevo (Dev)",
  "icon": "./assets/icon-dev.png",
  "distribution_type": "private",
  "sandbox_install_compatible": true,
  "dev": {
    "hot_reload": true,
    "port": 4242
  }
}
```

`dev` 섹션은 프로덕션 빌드와 앱 업로드 과정에서 제거됩니다. 로컬 개발 편의를 위한 설정에만 사용하세요.

## 검증

업로드하기 전에 매니페스트를 검증하세요.

```bash
# Validate manifest syntax and schema
stripe apps validate

# Check for common issues
stripe apps check
```

자주 발생하는 검증 오류는 다음과 같습니다.

| 오류 | 원인 | 해결 방법 |
| --- | --- | --- |
| `Invalid permission` | 알 수 없는 권한 식별자 | [권한 레퍼런스](https://tajo.io/kr/docs/stripe-apps/permissions)를 확인하세요 |
| `Invalid viewport` | 알 수 없는 뷰포트 식별자 | [뷰포트 레퍼런스](https://tajo.io/kr/docs/stripe-apps/viewports)를 확인하세요 |
| `Missing purpose` | purpose 필드가 없는 권한 | 각 권한에 purpose 문자열을 추가하세요 |
| `Invalid version` | 시맨틱 버전이 아닌 문자열 | `MAJOR.MINOR.PATCH` 형식을 사용하세요 |
| `Icon not found` | 아이콘 경로가 해석되지 않음 | 지정한 경로에 아이콘 파일이 있는지 확인하세요 |
