嵌入式 Stripe Apps
嵌入式 Stripe Apps 让基于 Stripe Connect 构建的平台可以在自己的仪表板里直接呈现第三方应用的功能。借助 Connect embedded components,你可以让关联账户使用 QuickBooks、Xero、Mailchimp 等应用,而无需他们跳转到 Stripe Dashboard。
概览
嵌入式应用使用两个关键的 Connect embedded components:
app-install:在你的平台界面中渲染某个 Stripe App 的安装按钮app-viewport:在你的平台界面中渲染某个应用的指定视图
这让平台运营方可以把财务、营销和运营工具直接嵌入自己的产品。
支持的应用
以下应用支持通过 Connect components 嵌入:
| 应用 | 类别 | 使用场景 |
|---|---|---|
| QuickBooks | 财务 | 把付款和发票同步到 QuickBooks |
| Xero | 财务 | 自动记账与对账 |
| Mailchimp | 营销 | 同步客户数据用于邮件营销活动 |
| 自建应用 | 任意 | 你为自己平台构建的 Stripe Apps |
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 App:
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 场景中使用嵌入式应用时,收款记录的元数据会携带结构化数据,供财务和营销类集成消费。
财务类集成
对于 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 账户无法使用嵌入式组件。