임베디드 Stripe 앱
임베디드 Stripe 앱을 사용하면 Stripe Connect 위에 구축된 플랫폼이 서드파티 앱 기능을 자체 대시보드 안에서 바로 노출할 수 있습니다. Connect 임베디드 컴포넌트를 사용하면 연결된 계정이 Stripe 대시보드를 방문하지 않고도 QuickBooks, Xero, Mailchimp 같은 앱을 이용할 수 있습니다.
개요
임베디드 앱은 두 가지 핵심 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 생성
const stripe = require('stripe')('sk_live_...');
// Create an Account Session for the connected accountconst 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 frontendres.json({ clientSecret: accountSession.client_secret });클라이언트 측: Connect.js 초기화
import { loadConnectAndInitialize } from '@stripe/connect-js';
// Initialize Connect.js with the account sessionconst 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
// Create the app install elementconst appInstall = stripeConnect.create('app-install');
// Set the app to installappInstall.setApp('com.tajo.brevo-integration');
// Mount to a DOM elementconst container = document.getElementById('app-install-container');appInstall.mount(container);
// Listen for install eventsappInstall.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
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
// Create the app viewport elementconst appViewport = stripeConnect.create('app-viewport');
// Configure the viewportappViewport.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 elementconst container = document.getElementById('app-viewport-container');appViewport.mount(container);React
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 메타데이터는 다음 스키마를 따릅니다.
{ "metadata": { "customer_id": "cus_platform_customer_id", "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 연동 같은 앱에서는 이 메타데이터로 고객 세그먼테이션과 캠페인 타기팅이 가능합니다.
{ "metadata": { "customer_id": "cus_xxxxx", "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 앱을 임베드한 전체 플랫폼 연동 예시입니다.
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 계정은 임베디드 컴포넌트를 사용할 수 없습니다.