---
title: "임베디드 Stripe 앱 | Tajo"
description: "Connect 임베디드 컴포넌트로 Stripe 앱을 자체 플랫폼에 통합하기"
url: https://tajo.io/kr/docs/stripe-apps/embedded-apps/
markdown: https://tajo.io/kr/docs/stripe-apps/embedded-apps.md
lang: ko-KR
author: "Set Noa"
author_url: https://tajo.io/kr/set-noa/
robots: noindex
---

Tajo 사전 이용 신청

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

# 임베디드 Stripe 앱

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

임베디드 Stripe 앱을 사용하면 Stripe Connect 위에 구축된 플랫폼이 서드파티 앱 기능을 자체 대시보드 안에서 바로 노출할 수 있습니다. Connect 임베디드 컴포넌트를 사용하면 연결된 계정이 Stripe 대시보드를 방문하지 않고도 QuickBooks, Xero, Mailchimp 같은 앱을 이용할 수 있습니다.

Caution

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

## 개요

임베디드 앱은 두 가지 핵심 Connect 임베디드 컴포넌트를 사용합니다.

- **`app-install`**: 플랫폼 UI 안에 Stripe 앱의 설치 버튼을 렌더링합니다
- **`app-viewport`**: 플랫폼 UI 안에 특정 앱 뷰포트를 렌더링합니다

이를 통해 플랫폼 운영자는 회계, 마케팅, 운영 도구를 자사 제품에 직접 임베드할 수 있습니다.

## 지원되는 앱

다음 앱은 Connect 컴포넌트를 통한 임베딩을 지원합니다.

| 앱 | 카테고리 | 활용 사례 |
| --- | --- | --- |
| **QuickBooks** | 회계 | 결제와 인보이스를 QuickBooks로 동기화 |
| **Xero** | 회계 | 자동 부기 및 대사 처리 |
| **Mailchimp** | 마케팅 | 이메일 캠페인용 고객 데이터 동기화 |
| **Custom Apps** | 전체 | 플랫폼에 맞게 직접 만든 Stripe 앱 |

Tip

Tajo Brevo 연동은 Connect 플랫폼에 임베드할 수 있으며, 연결된 계정이 플랫폼 자체 인터페이스를 통해 Stripe 데이터를 Brevo로 동기화할 수 있습니다.

## Account Sessions API로 설정하기

앱을 임베드하려면 필요한 컴포넌트를 활성화한 Account Session을 생성해야 합니다.

### 서버 측: Account Session 생성

```javascript
const stripe = require('stripe')('sk_live_...');

// Create an Account Session for the connected account
const accountSession = await stripe.accountSessions.create({
  account: 'acct_connected_account_id',
  components: {
    // Enable app install component
    app_install: {
      enabled: true,
      features: {
        allowed_apps: [
          'com.tajo.brevo-integration',
          'com.quickbooks.stripe-app'
        ],
      },
    },
    // Enable app viewport component
    app_viewport: {
      enabled: true,
      features: {
        allowed_apps: [
          'com.tajo.brevo-integration'
        ],
      },
    },
  },
});

// Return the client secret to your frontend
res.json({ clientSecret: accountSession.client_secret });
```

### 클라이언트 측: Connect.js 초기화

```javascript
import { loadConnectAndInitialize } from '@stripe/connect-js';

// Initialize Connect.js with the account session
const stripeConnect = loadConnectAndInitialize({
  publishableKey: 'pk_live_...',
  fetchClientSecret: async () => {
    const response = await fetch('/api/account-session', {
      method: 'POST',
    });
    const { clientSecret } = await response.json();
    return clientSecret;
  },
});
```

## App Install 컴포넌트

`app-install` 컴포넌트는 연결된 계정이 Stripe 앱을 설치할 때 사용할 수 있는 설치 버튼을 렌더링합니다.

### JavaScript

```javascript
// Create the app install element
const appInstall = stripeConnect.create('app-install');

// Set the app to install
appInstall.setApp('com.tajo.brevo-integration');

// Mount to a DOM element
const container = document.getElementById('app-install-container');
appInstall.mount(container);

// Listen for install events
appInstall.on('app_installed', (event) => {
  console.log('App installed:', event.app_id);
  // Show the app viewport after installation
  showAppViewport();
});

appInstall.on('app_uninstalled', (event) => {
  console.log('App uninstalled:', event.app_id);
});
```

### React

```tsx
import {
  ConnectAppInstall,
  ConnectComponentsProvider,
} from '@stripe/react-connect-js';

const AppInstallButton = () => {
  return (
    <ConnectComponentsProvider connectInstance={stripeConnect}>
      <ConnectAppInstall
        app="com.tajo.brevo-integration"
        onAppInstalled={(event) => {
          console.log('App installed:', event.app_id);
        }}
        onAppUninstalled={(event) => {
          console.log('App uninstalled:', event.app_id);
        }}
      />
    </ConnectComponentsProvider>
  );
};
```

## App Viewport 컴포넌트

`app-viewport` 컴포넌트는 플랫폼 안에 특정 앱 뷰포트를 렌더링합니다.

### JavaScript

```javascript
// Create the app viewport element
const appViewport = stripeConnect.create('app-viewport');

// Configure the viewport
appViewport.setApp('com.tajo.brevo-integration');
appViewport.setViewport('stripe.dashboard.customer.detail');

// Pass object context (e.g., customer ID)
appViewport.setObjectContext({
  id: 'cus_xxxxx',
  object: 'customer',
});

// Mount to a DOM element
const container = document.getElementById('app-viewport-container');
appViewport.mount(container);
```

### React

```tsx
import {
  ConnectAppViewport,
  ConnectComponentsProvider,
} from '@stripe/react-connect-js';

const BrevoCustomerView = ({ customerId }: { customerId: string }) => {
  return (
    <ConnectComponentsProvider connectInstance={stripeConnect}>
      <ConnectAppViewport
        app="com.tajo.brevo-integration"
        viewport="stripe.dashboard.customer.detail"
        objectContext={{
          id: customerId,
          object: 'customer',
        }}
      />
    </ConnectComponentsProvider>
  );
};
```

## Destination Charge 메타데이터 스키마

Connect 플랫폼에서 흔한 destination charge와 임베디드 앱을 함께 사용하면, charge 메타데이터가 회계 및 마케팅 연동에서 활용할 수 있는 구조화된 데이터를 담습니다.

### 회계 연동

QuickBooks나 Xero 같은 앱의 경우 destination charge 메타데이터는 다음 스키마를 따릅니다.

```json
{
  "metadata": {
    "customer_id": "cus_platform_customer_id",
    "customer_email": "customer@example.com",
    "product_name": "Premium Subscription",
    "product_id": "prod_xxxxx",
    "quantity": "1",
    "unit_amount": "4999",
    "currency": "usd",
    "platform_fee": "500",
    "platform_fee_currency": "usd",
    "tax_amount": "450",
    "tax_rate_id": "txr_xxxxx",
    "invoice_id": "inv_xxxxx",
    "order_id": "order_12345"
  }
}
```

| 필드 | 타입 | 설명 |
| --- | --- | --- |
| `customer_id` | string | 플랫폼의 고객 식별자 |
| `customer_email` | string | 인보이스 및 영수증 대조용 고객 이메일 |
| `product_name` | string | 라인 아이템에 표시할 상품 이름 |
| `product_id` | string | Stripe 상품 ID |
| `quantity` | string | 항목 수량 |
| `unit_amount` | string | 통화 최소 단위 기준 단가 (센트) |
| `currency` | string | 세 자리 ISO 통화 코드 |
| `platform_fee` | string | 통화 최소 단위 기준 애플리케이션 수수료 금액 |
| `platform_fee_currency` | string | 플랫폼 수수료의 통화 |
| `tax_amount` | string | 통화 최소 단위 기준 세액 |
| `tax_rate_id` | string | 적용된 Stripe 세율 ID |
| `invoice_id` | string | 연결된 인보이스 ID |
| `order_id` | string | 플랫폼 내부 주문 식별자 |

### 마케팅 연동

Mailchimp나 Tajo Brevo 연동 같은 앱에서는 이 메타데이터로 고객 세그먼테이션과 캠페인 타기팅이 가능합니다.

```json
{
  "metadata": {
    "customer_id": "cus_xxxxx",
    "customer_email": "customer@example.com",
    "customer_name": "Jane Smith",
    "product_category": "subscription",
    "product_name": "Pro Plan",
    "purchase_value": "4999",
    "currency": "usd",
    "is_first_purchase": "true",
    "referral_source": "partner_campaign",
    "subscription_interval": "monthly",
    "lifetime_value": "29994"
  }
}
```

이 메타데이터로 다음과 같은 Brevo 자동화를 구성할 수 있습니다.

- 첫 구매 고객을 위한 **웰컴 시리즈** (`is_first_purchase: "true"`)
- `product_category`와 `purchase_value` 기반의 **업셀 캠페인**
- `subscription_interval` 기반의 구독 고객 **리텐션 플로**
- 이탈한 고액 `lifetime_value` 고객을 겨냥한 **윈백 캠페인**

## 플랫폼 연동 예시

Tajo Brevo 앱을 임베드한 전체 플랫폼 연동 예시입니다.

```tsx
import { useState, useEffect } from 'react';
import {
  ConnectAppInstall,
  ConnectAppViewport,
  ConnectComponentsProvider,
} from '@stripe/react-connect-js';
import { loadConnectAndInitialize } from '@stripe/connect-js';

const TajoBrevoPlatformIntegration = ({ connectedAccountId, customerId }) => {
  const [stripeConnect, setStripeConnect] = useState(null);
  const [isInstalled, setIsInstalled] = useState(false);

  useEffect(() => {
    const instance = loadConnectAndInitialize({
      publishableKey: 'pk_live_...',
      fetchClientSecret: async () => {
        const res = await fetch('/api/account-session', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ accountId: connectedAccountId }),
        });
        const { clientSecret } = await res.json();
        return clientSecret;
      },
    });
    setStripeConnect(instance);
  }, [connectedAccountId]);

  if (!stripeConnect) return <div>Loading...</div>;

  return (
    <ConnectComponentsProvider connectInstance={stripeConnect}>
      {!isInstalled ? (
        <div>
          <h3>Connect Brevo via Tajo</h3>
          <p>Install the Tajo integration to sync customer data with Brevo.</p>
          <ConnectAppInstall
            app="com.tajo.brevo-integration"
            onAppInstalled={() => setIsInstalled(true)}
          />
        </div>
      ) : (
        <div>
          <h3>Brevo Customer Profile</h3>
          <ConnectAppViewport
            app="com.tajo.brevo-integration"
            viewport="stripe.dashboard.customer.detail"
            objectContext={{
              id: customerId,
              object: 'customer',
            }}
          />
        </div>
      )}
    </ConnectComponentsProvider>
  );
};
```

## 보안 고려사항

플랫폼에 앱을 임베드할 때 유의할 점입니다.

- **Account Session 만료**: 필요할 때마다 새 세션을 생성하고, client secret은 캐시하지 마세요
- **범위 제어**: `allowed_apps`로 설치 가능한 앱을 제한하세요
- **데이터 격리**: 연결된 각 계정의 데이터는 격리되며, 플랫폼은 앱 데이터에 접근할 수 없습니다
- **CSP 헤더**: 플랫폼의 콘텐츠 보안 정책이 `https://connect-js.stripe.com`으로의 연결을 허용하는지 확인하세요

Caution

임베디드 앱 컴포넌트를 사용하려면 Account Sessions API에 접근할 수 있는 Connect 연동이 필요합니다. 표준 Stripe 계정은 임베디드 컴포넌트를 사용할 수 없습니다.
