Install Links & Deep Links

Install links cho phép bạn phân phối Stripe App bên ngoài marketplace, trong khi deep links điều hướng người dùng trực tiếp đến các views cụ thể trong app đã cài đặt của bạn. Cả hai đều thiết yếu cho trải nghiệm onboarding và luồng tích hợp mượt mà.

Install links cung cấp URL trực tiếp mà merchants có thể sử dụng để cài đặt app của bạn. Khi người dùng nhấp vào install link, Stripe xử lý luồng cài đặt rồi chuyển hướng về URI đã chỉ định của bạn.

Điều Kiện Tiên Quyết

Trước khi sử dụng install links, hãy cấu hình allowed_redirect_uris trong app manifest:

{
"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
Tham SốBắt BuộcMô Tả
client_idApp ID của bạn (ví dụ: com.tajo.brevo-integration)
redirect_uriPhải khớp với một trong allowed_redirect_uris của bạn
stateKhuyến nghịChuỗi ngẫu nhiên để bảo vệ CSRF

Tham Số Redirect

Sau khi cài đặt thành công, Stripe chuyển hướng người dùng đến redirect_uri của bạn với các tham số query này:

Tham SốMô Tả
user_idStripe user ID của tài khoản cài đặt
account_idStripe account ID (ví dụ: acct_xxxxx)
stateGiá trị state bạn đã cung cấp (để xác minh CSRF)
install_signatureChữ ký HMAC để xác minh cài đặt hợp lệ

Ví dụ URL redirect:

https://tajo.io/stripe/callback
?user_id=usr_xxxxx
&account_id=acct_xxxxx
&state=abc123random
&install_signature=sig_xxxxx

Bảo Vệ CSRF

Luôn sử dụng tham số state để ngăn chặn tấn công cross-site request forgery:

import crypto from 'crypto';
// Tạo giá trị state ngẫu nhiên và lưu trong session
const generateInstallLink = (req, res) => {
const state = crypto.randomBytes(32).toString('hex');
// Lưu state trong session để xác minh sau
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());
};
// Xử lý redirect callback
const handleInstallCallback = (req, res) => {
const { state, user_id, account_id, install_signature } = req.query;
// Xác minh state khớp với những gì đã lưu
if (state !== req.session.stripeInstallState) {
return res.status(403).json({ error: 'Invalid state parameter' });
}
// Xóa state đã lưu
delete req.session.stripeInstallState;
// Xác minh install signature
if (!verifyInstallSignature(install_signature, account_id)) {
return res.status(403).json({ error: 'Invalid install signature' });
}
// Xử lý cài đặt thành công
await processInstallation(user_id, account_id);
res.redirect('/dashboard/stripe-connected');
};

Xác Minh Chữ Ký

Xác minh install_signature sử dụng signing secret của app:

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

Luôn sử dụng crypto.timingSafeEqual để so sánh chữ ký nhằm ngăn chặn timing attacks. Không bao giờ sử dụng so sánh chuỗi đơn giản (===).

Signing Secret

Signing secret của app có trong Stripe Dashboard dưới phần cài đặt app. Sử dụng nó để:

  • Xác minh install signatures từ redirect callbacks
  • Xác thực webhook payloads từ Stripe
  • Xác thực các requests giữa backend và Stripe

Lưu trữ signing secret an toàn:

Terminal window
# Đặt làm biến môi trường
export STRIPE_APP_SIGNING_SECRET="whsec_xxxxx"

Không bao giờ hardcode signing secrets trong source code hoặc commit vào version control.

Deep links điều hướng người dùng trực tiếp đến một view cụ thể trong Stripe App đã cài đặt. Sử dụng chúng để hướng người dùng từ các thông tin liên lạc bên ngoài (email, thông báo, trang hỗ trợ) đến context app liên quan.

https://dashboard.stripe.com/MODE/acct_ID/PAGE?apps[APP_ID][TARGET]=VIEWPORT_ID
Thành PhầnMô TảVí Dụ
MODElive hoặc testlive
acct_IDStripe account ID đíchacct_1234567890
PAGEĐường dẫn trang Dashboardcustomers/cus_xxxxx
APP_IDApp ID của bạncom.tajo.brevo-integration
TARGETdrawer hoặc modaldrawer
VIEWPORT_IDViewport để mởstripe.dashboard.customer.detail

Drawer So Với Modal Targets

TargetHành ViTrường Hợp Sử Dụng
drawerMở app trong side panel (drawer)Tương tác app mặc định, context bên cạnh trang
modalMở app trong modal overlay toàn màn hìnhLuồng tập trung, onboarding, forms phức tạp

Mở customer detail view trong drawer

https://dashboard.stripe.com/live/acct_xxxxx/customers/cus_xxxxx
?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.customer.detail

Mở settings trong modal

https://dashboard.stripe.com/live/acct_xxxxx/settings
?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.settings

Mở 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()}`;
};
// Tạo link để xem Brevo profile của khách hàng
const customerLink = generateDeepLink({
accountId: 'acct_xxxxx',
page: 'customers/cus_xxxxx',
viewport: 'stripe.dashboard.customer.detail',
});
// Tạo link đến app settings
const settingsLink = generateDeepLink({
accountId: 'acct_xxxxx',
page: 'settings',
viewport: 'stripe.dashboard.settings',
target: 'modal',
});

Deep links đặc biệt hữu ích trong:

  • Email notifications: “Xem trạng thái Brevo sync cho khách hàng này”
  • Phản hồi hỗ trợ: “Nhấp vào đây để kiểm tra cài đặt tích hợp của bạn”
  • Email onboarding: “Hoàn thành thiết lập Brevo của bạn”
  • Cảnh báo lỗi: “Xem xét vấn đề sync cho khách hàng X”
<!-- Ví dụ trong email template -->
<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>

Để có trải nghiệm onboarding tốt nhất, kết hợp install links với post-install deep links:

  1. Người dùng nhấp vào install link từ website hoặc email của bạn
  2. Người dùng cài đặt app và được chuyển hướng đến callback URL của bạn
  3. Callback của bạn xử lý cài đặt và chuyển hướng người dùng đến deep link mở onboarding viewport
const handleInstallCallback = async (req, res) => {
const { account_id, install_signature, state } = req.query;
// Xác minh state và signature
// ... (verification code)
// Xử lý cài đặt
await processInstallation(account_id);
// Chuyển hướng đến onboarding view của app qua deep link
const onboardingLink = generateDeepLink({
accountId: account_id,
page: 'dashboard',
viewport: 'stripe.dashboard.onboarding',
target: 'modal',
});
res.redirect(onboardingLink);
};

Tip

Luôn kiểm thử install links và deep links trong cả chế độ live và test để đảm bảo chúng hoạt động chính xác trong mọi môi trường.

Subscribe to updates

developer-docs

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

Trợ lý AI

Xin chào! Hãy hỏi tôi về tài liệu.

Bắt đầu miễn phí với Brevo