Install Links & Deep Links
Install links 让您可以在 marketplace 之外分发 Stripe App,而 deep links 将用户直接导航到已安装应用的特定视图。两者对于流畅的 onboarding 和集成流程都至关重要。
Install Links
Install links 提供直接 URL,商家可以使用它来安装您的应用。当用户点击 install link 时,Stripe 处理安装流程,然后重定向回您指定的 URI。
前提条件
在使用 install links 之前,请在 app manifest 中配置 allowed_redirect_uris:
{ "id": "com.tajo.brevo-integration", "allowed_redirect_uris": [ "https://tajo.io/stripe/callback", "https://tajo.io/stripe/oauth/complete" ]}Install Link 格式
https://marketplace.stripe.com/oauth/v2/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&state=STATE_VALUE| 参数 | 必需 | 描述 |
|---|---|---|
client_id | 是 | 您的 app ID(例如 com.tajo.brevo-integration) |
redirect_uri | 是 | 必须匹配您 allowed_redirect_uris 中的一个 |
state | 建议 | 用于 CSRF 保护的随机字符串 |
Redirect 参数
安装成功后,Stripe 将用户重定向到您的 redirect_uri,附带以下查询参数:
| 参数 | 描述 |
|---|---|
user_id | 安装账户的 Stripe user ID |
account_id | Stripe account ID(例如 acct_xxxxx) |
state | 您提供的 state 值(用于 CSRF 验证) |
install_signature | 验证安装合法性的 HMAC 签名 |
示例重定向 URL:
https://tajo.io/stripe/callback ?user_id=usr_xxxxx &account_id=acct_xxxxx &state=abc123random &install_signature=sig_xxxxxCSRF 保护
始终使用 state 参数来防止跨站请求伪造攻击:
import crypto from 'crypto';
// 生成随机 state 值并存储在 session 中const generateInstallLink = (req, res) => { const state = crypto.randomBytes(32).toString('hex');
// 在 session 中存储 state 以便后续验证 req.session.stripeInstallState = state;
const installUrl = new URL('https://marketplace.stripe.com/oauth/v2/authorize'); installUrl.searchParams.set('client_id', 'com.tajo.brevo-integration'); installUrl.searchParams.set('redirect_uri', 'https://tajo.io/stripe/callback'); installUrl.searchParams.set('state', state);
res.redirect(installUrl.toString());};
// 处理重定向回调const handleInstallCallback = (req, res) => { const { state, user_id, account_id, install_signature } = req.query;
// 验证 state 与存储的匹配 if (state !== req.session.stripeInstallState) { return res.status(403).json({ error: 'Invalid state parameter' }); }
// 清除存储的 state delete req.session.stripeInstallState;
// 验证 install signature if (!verifyInstallSignature(install_signature, account_id)) { return res.status(403).json({ error: 'Invalid install signature' }); }
// 处理安装成功 await processInstallation(user_id, account_id);
res.redirect('/dashboard/stripe-connected');};签名验证
使用应用的 signing secret 验证 install_signature:
import crypto from 'crypto';
const verifyInstallSignature = (signature, accountId) => { const signingSecret = process.env.STRIPE_APP_SIGNING_SECRET;
const expectedSignature = crypto .createHmac('sha256', signingSecret) .update(accountId) .digest('hex');
return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) );};Caution
始终使用 crypto.timingSafeEqual 进行签名比较以防止计时攻击。永远不要使用简单的字符串相等比较(===)。
Signing Secret
您应用的 signing secret 可在 Stripe Dashboard 的应用设置下找到。使用它来:
- 验证来自 redirect callbacks 的 install signatures
- 验证来自 Stripe 的 webhook payloads
- 验证后端与 Stripe 之间的请求
安全存储 signing secret:
# 设置为环境变量export STRIPE_APP_SIGNING_SECRET="whsec_xxxxx"永远不要在源代码中硬编码 signing secrets 或将其提交到版本控制。
Deep Links
Deep links 将用户直接导航到已安装 Stripe App 中的特定视图。使用它们将用户从外部通信(电子邮件、通知、支持页面)引导到相关的应用上下文。
Deep Link URL 格式
https://dashboard.stripe.com/MODE/acct_ID/PAGE?apps[APP_ID][TARGET]=VIEWPORT_ID| 组件 | 描述 | 示例 |
|---|---|---|
MODE | live 或 test | live |
acct_ID | 目标 Stripe account ID | acct_1234567890 |
PAGE | Dashboard 页面路径 | customers/cus_xxxxx |
APP_ID | 您的 app ID | com.tajo.brevo-integration |
TARGET | drawer 或 modal | drawer |
VIEWPORT_ID | 要打开的 viewport | stripe.dashboard.customer.detail |
Drawer 与 Modal Targets
| Target | 行为 | 使用场景 |
|---|---|---|
drawer | 在侧边面板(drawer)中打开应用 | 默认应用交互,与页面并排的上下文 |
modal | 在全屏 modal overlay 中打开应用 | 专注工作流、onboarding、复杂表单 |
Deep Link 示例
在 drawer 中打开 customer detail view
https://dashboard.stripe.com/live/acct_xxxxx/customers/cus_xxxxx ?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.customer.detail在 modal 中打开 settings
https://dashboard.stripe.com/live/acct_xxxxx/settings ?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.settings打开 onboarding flow
https://dashboard.stripe.com/live/acct_xxxxx/dashboard ?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.onboarding以编程方式生成 Deep Links
const generateDeepLink = ({ accountId, mode = 'live', page, appId = 'com.tajo.brevo-integration', target = 'drawer', viewport,}) => { const baseUrl = `https://dashboard.stripe.com/${mode}/${accountId}/${page}`; const params = new URLSearchParams(); params.set(`apps[${appId}][${target}]`, viewport);
return `${baseUrl}?${params.toString()}`;};
// 生成查看客户 Brevo 档案的链接const customerLink = generateDeepLink({ accountId: 'acct_xxxxx', page: 'customers/cus_xxxxx', viewport: 'stripe.dashboard.customer.detail',});
// 生成 app settings 链接const settingsLink = generateDeepLink({ accountId: 'acct_xxxxx', page: 'settings', viewport: 'stripe.dashboard.settings', target: 'modal',});在通信中使用 Deep Links
Deep links 在以下场景特别有用:
- 电子邮件通知:“查看此客户的 Brevo 同步状态”
- 支持回复:“点击此处检查您的集成设置”
- Onboarding 邮件:“完成您的 Brevo 设置”
- 错误警报:“查看客户 X 的同步问题”
<!-- 电子邮件模板示例 --><a href="https://dashboard.stripe.com/live/acct_xxxxx/customers/cus_xxxxx?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.customer.detail"> View Brevo Profile in Stripe</a>结合 Install Links 和 Deep Links
为了获得最佳 onboarding 体验,将 install links 与 post-install deep links 结合使用:
- 用户从您的网站或电子邮件点击 install link
- 用户安装应用并被重定向到您的回调 URL
- 您的回调处理安装并将用户重定向到打开 onboarding viewport 的 deep link
const handleInstallCallback = async (req, res) => { const { account_id, install_signature, state } = req.query;
// 验证 state 和 signature // ... (verification code)
// 处理安装 await processInstallation(account_id);
// 通过 deep link 重定向到应用的 onboarding view const onboardingLink = generateDeepLink({ accountId: account_id, page: 'dashboard', viewport: 'stripe.dashboard.onboarding', target: 'modal', });
res.redirect(onboardingLink);};Tip
在 live 和 test 模式下都测试 install links 和 deep links,以确保它们在所有环境中正确工作。