Ссылки установки и глубокие ссылки
Ссылки установки позволяют распространять Ваше Stripe App за пределами маркетплейса, а глубокие ссылки переводят пользователей непосредственно к конкретным представлениям внутри установленного приложения. И то, и другое необходимо для плавного онбординга и сценариев интеграции.
Ссылки установки
Ссылки установки предоставляют прямой URL, по которому продавцы могут установить Ваше приложение. Когда пользователь нажимает на ссылку установки, Stripe выполняет процесс установки, а затем перенаправляет его обратно на указанный Вами URI.
Предварительные требования
Прежде чем использовать ссылки установки, настройте 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 | Да | ID Вашего приложения (например, com.tajo.brevo-integration) |
redirect_uri | Да | Должен совпадать с одним из allowed_redirect_uris |
state | Рекомендуется | Случайная строка для защиты от CSRF |
Параметры перенаправления
После успешной установки Stripe перенаправляет пользователя на Ваш redirect_uri со следующими параметрами запроса:
| Параметр | Описание |
|---|---|
user_id | ID пользователя Stripe, устанавливающего приложение |
account_id | ID аккаунта Stripe (например, 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';
// Generate a random state value and store it in the sessionconst generateInstallLink = (req, res) => { const state = crypto.randomBytes(32).toString('hex');
// Store state in session for later verification 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());};
// Handle the redirect callbackconst handleInstallCallback = async (req, res) => { const { state, user_id, account_id, install_signature } = req.query;
// Verify state matches what we stored if (state !== req.session.stripeInstallState) { return res.status(403).json({ error: 'Invalid state parameter' }); }
// Clear the stored state delete req.session.stripeInstallState;
// Verify the install signature if (!verifyInstallSignature(install_signature, account_id)) { return res.status(403).json({ error: 'Invalid install signature' }); }
// Process the successful installation await processInstallation(user_id, account_id);
res.redirect('/dashboard/stripe-connected');};Проверка подписи
Проверьте 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 для сравнения подписей, чтобы предотвратить атаки по времени. Никогда не используйте простое сравнение строк (===).
Секрет подписи
Секрет подписи Вашего приложения доступен в Stripe Dashboard в настройках приложения. Используйте его, чтобы:
- Проверять подписи установки из обратных вызовов перенаправления
- Валидировать полезную нагрузку вебхуков от Stripe
- Аутентифицировать запросы между Вашим бэкендом и Stripe
Храните секрет подписи безопасно:
# Set as environment variableexport STRIPE_APP_SIGNING_SECRET="whsec_xxxxx"Никогда не записывайте секреты подписи прямо в исходный код и не помещайте их в систему контроля версий.
Глубокие ссылки
Глубокие ссылки переводят пользователей непосредственно к конкретному представлению внутри установленного Stripe App. Используйте их, чтобы направлять пользователей из внешних коммуникаций (писем, уведомлений, страниц поддержки) в нужный контекст приложения.
Формат URL глубокой ссылки
https://dashboard.stripe.com/MODE/acct_ID/PAGE?apps[APP_ID][TARGET]=VIEWPORT_ID| Компонент | Описание | Пример |
|---|---|---|
MODE | live или test | live |
acct_ID | ID целевого аккаунта Stripe | acct_1234567890 |
PAGE | Путь страницы Dashboard | customers/cus_xxxxx |
APP_ID | ID Вашего приложения | com.tajo.brevo-integration |
TARGET | drawer или modal | drawer |
VIEWPORT_ID | Вьюпорт, который нужно открыть | stripe.dashboard.customer.detail |
Цели drawer и modal
| Target | Поведение | Сценарий использования |
|---|---|---|
drawer | Открывает приложение в боковой панели (drawer) | Стандартное взаимодействие с приложением, контекст рядом со страницей |
modal | Открывает приложение в полноэкранном модальном окне | Сфокусированные рабочие процессы, онбординг, сложные формы |
Примеры глубоких ссылок
Открыть представление с деталями клиента в боковой панели
https://dashboard.stripe.com/live/acct_xxxxx/customers/cus_xxxxx ?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.customer.detailОткрыть настройки в модальном окне
https://dashboard.stripe.com/live/acct_xxxxx/settings ?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.settingsОткрыть процесс онбординга
https://dashboard.stripe.com/live/acct_xxxxx/dashboard ?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.onboardingОткрыть представление с деталями платежа в тестовом режиме
https://dashboard.stripe.com/test/acct_xxxxx/payments/pi_xxxxx ?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.payment.detailПрограммная генерация глубоких ссылок
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()}`;};
// Generate a link to view a customer's Brevo profileconst customerLink = generateDeepLink({ accountId: 'acct_xxxxx', page: 'customers/cus_xxxxx', viewport: 'stripe.dashboard.customer.detail',});
// Generate a link to app settingsconst settingsLink = generateDeepLink({ accountId: 'acct_xxxxx', page: 'settings', viewport: 'stripe.dashboard.settings', target: 'modal',});Использование глубоких ссылок в коммуникациях
Глубокие ссылки особенно полезны в следующих случаях:
- Уведомления по email: «Посмотреть статус синхронизации с Brevo для этого клиента»
- Ответы поддержки: «Нажмите здесь, чтобы проверить настройки интеграции»
- Письма онбординга: «Завершите настройку Brevo»
- Оповещения об ошибках: «Разберите проблему синхронизации для клиента X»
<!-- Example in an 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>Объединение ссылок установки и глубоких ссылок
Для наилучшего опыта онбординга объедините ссылки установки с глубокими ссылками, открывающимися после установки:
- Пользователь нажимает ссылку установки на Вашем сайте или в письме
- Пользователь устанавливает приложение и перенаправляется на Ваш URL обратного вызова
- Ваш обратный вызов обрабатывает установку и перенаправляет пользователя на глубокую ссылку, которая открывает вьюпорт онбординга
const handleInstallCallback = async (req, res) => { const { account_id, install_signature, state } = req.query;
// Verify state and signature // ... (verification code)
// Process installation await processInstallation(account_id);
// Redirect to the app's onboarding view via deep link const onboardingLink = generateDeepLink({ accountId: account_id, page: 'dashboard', viewport: 'stripe.dashboard.onboarding', target: 'modal', });
res.redirect(onboardingLink);};Tip
Всегда тестируйте ссылки установки и глубокие ссылки как в live-, так и в тестовом режиме, чтобы убедиться, что они корректно работают во всех окружениях.