Интегрируй Stripe ({{model}}).
Архитектура
Client ─→ POST /api/checkout
←─ Stripe Checkout URL
Client ─→ Stripe Checkout (hosted)
Stripe ─→ POST /api/webhook/stripe
└→ обновить пользователя в DB
1. Checkout Session
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
line_items: [{ price: 'price_xxx', quantity: 1 }],
customer_email: user.email,
client_reference_id: user.id,
success_url: `${SITE}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${SITE}/pricing`,
metadata: { user_id: user.id },
});
return { url: session.url };
Принципы
- НЕ принимай карты сам — используй Stripe Checkout
- НЕ передавай price-значения с клиента
- Используй
client_reference_idдля связи с DB
2. Webhook handling
const event = stripe.webhooks.constructEvent(
rawBody, sig, WEBHOOK_SECRET
);
switch (event.type) {
case 'checkout.session.completed':
await activateSubscription(event.data.object);
case 'invoice.payment_failed':
await markAccountUnpaid(...);
case 'customer.subscription.deleted':
await deactivateSubscription(...);
}
Правила
- Верифицируй подпись (Stripe-Signature)
- Идемпотентность: логируй event.id, не обрабатывай повторно
- Быстро 200 Stripe-у (< 5 сек). Долгую работу → в очередь
3. Test mode
- Отдельные test/live ключи
- Card 4242 4242 4242 4242 — success
- Card 4000 0000 0000 0002 — decline
- Stripe CLI для webhook testing
4. Customer Portal
Не строй свой UI. Используй:
const portal = await stripe.billingPortal.sessions.create({
customer: customer.id,
return_url: `${SITE}/account`,
});
5. Tax
- Stripe Tax:
automatic_tax: { enabled: true } - Без него — нарушение VAT для EU
Чек-лист
- Webhook подпись верифицируется
- Идемпотентность
- Test-mode покрыт
- PCI compliance: НИГДЕ не храним card data
- Receipts отправляются
Анти-паттерны
- ❌ Хранить card numbers
- ❌ Возвращать 500 в webhook → infinite retries
- ❌ Проверять подписку только при логине
Похожие промты
site / development
Интеграция стороннего сервиса
План подключения сервиса (Stripe, Supabase, etc.) с учётом ошибок, секретов и тестового режима.
integrationapithird-party
Открыть
Средний30-60 мин
site / payments
Subscription-флоу: upgrade, downgrade, cancel
Что происходит при смене плана, отмене, паузе — UX + биллинг.
paymentssubscription
Открыть
Продвинутый30-60 мин
site / payments
Billing-страница
Что показывать: план, история, способ оплаты, инвойсы, отмена.
paymentsbillingui
Открыть
Средний30-60 мин