Install Links & Deep Links

Install links 让您可以在 marketplace 之外分发 Stripe App,而 deep links 将用户直接导航到已安装应用的特定视图。两者对于流畅的 onboarding 和集成流程都至关重要。

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"
]
}
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_idStripe 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_xxxxx

CSRF 保护

始终使用 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:

Terminal window
# 设置为环境变量
export STRIPE_APP_SIGNING_SECRET="whsec_xxxxx"

永远不要在源代码中硬编码 signing secrets 或将其提交到版本控制。

Deep links 将用户直接导航到已安装 Stripe App 中的特定视图。使用它们将用户从外部通信(电子邮件、通知、支持页面)引导到相关的应用上下文。

https://dashboard.stripe.com/MODE/acct_ID/PAGE?apps[APP_ID][TARGET]=VIEWPORT_ID
组件描述示例
MODElivetestlive
acct_ID目标 Stripe account IDacct_1234567890
PAGEDashboard 页面路径customers/cus_xxxxx
APP_ID您的 app IDcom.tajo.brevo-integration
TARGETdrawermodaldrawer
VIEWPORT_ID要打开的 viewportstripe.dashboard.customer.detail

Drawer 与 Modal Targets

Target行为使用场景
drawer在侧边面板(drawer)中打开应用默认应用交互,与页面并排的上下文
modal在全屏 modal overlay 中打开应用专注工作流、onboarding、复杂表单

在 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
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 在以下场景特别有用:

  • 电子邮件通知:“查看此客户的 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>

为了获得最佳 onboarding 体验,将 install links 与 post-install deep links 结合使用:

  1. 用户从您的网站或电子邮件点击 install link
  2. 用户安装应用并被重定向到您的回调 URL
  3. 您的回调处理安装并将用户重定向到打开 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,以确保它们在所有环境中正确工作。

Subscribe to updates

developer-docs

Drop your email or phone number — we'll send you what matters next.

AI 助手

你好!关于文档有任何问题都可以问我。

免费开始使用Brevo