---
title: "嵌入式 Stripe Apps | Tajo"
description: "用 Connect embedded components 把 Stripe Apps 集成进你自己的平台"
url: https://tajo.io/zh-cn/docs/stripe-apps/embedded-apps/
markdown: https://tajo.io/zh-cn/docs/stripe-apps/embedded-apps.md
lang: zh-CN
author: "Set Noa"
author_url: https://tajo.io/zh-cn/set-noa/
robots: noindex
---

申请抢先体验

请输入您的名字和公司电子邮箱地址。我们会发送确认 Tajo 访问申请的链接。

# 嵌入式 Stripe Apps

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

嵌入式 Stripe Apps 让基于 Stripe Connect 构建的平台可以在自己的仪表板里直接呈现第三方应用的功能。借助 Connect embedded components，你可以让关联账户使用 QuickBooks、Xero、Mailchimp 等应用，而无需他们跳转到 Stripe Dashboard。

Caution

**状态：计划中，尚未构建。** Tajo 没有 Stripe App，因此本章中的任何内容目前都无法安装。本页中的 app 标识、URL 和凭据都是用于示意的占位值，而不是可用的线上端点。

## 概览

嵌入式应用使用两个关键的 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

```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 App：

### 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 场景中使用嵌入式应用时，收款记录的元数据会携带结构化数据，供财务和营销类集成消费。

### 财务类集成

对于 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 账户无法使用嵌入式组件。
