Skip to content
PПромтбук
RUEN
01Платежи

Интеграция Stripe

Checkout, подписки, webhook'и, идемпотентность, тест-режим — production-ready stripe.

Интегрируй 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
  • ❌ Проверять подписку только при логине
К подразделу «Платежи»
Похожие промты