EMZETT.
Увійти

Вебхуки Stripe: надійна обробка платежів

Коротко: Stripe повідомляє вашому серверу про платежі, підписки та повернення вебхуком; ви перевіряєте підпис, відповідаєте швидко, обробляєте ідемпотентно й не покладаєтеся на сторінку повернення клієнта.

Докладніше: Після платежу клієнт повертається на ваш сайт, але браузер може бути закритий або з’єднання обірватися. Надійне лише повідомлення сервера (вебхук) від Stripe: HTTP POST із подією (checkout.session.completed, invoice.paid, customer.subscription.deleted …).

Подробиці

Процес

  1. Створіть кінцеву точку (/api/stripe/webhook) і виберіть події в Stripe (панель або CLI).
  2. Перевірте підпис за допомогою секрету вебхука та необробленого тіла запиту:
const sig = req.headers.get("stripe-signature")!;
const body = await req.text();            // сире, не розібране як JSON!
const event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!);

Без перевірки будь-хто міг би повідомляти підроблені платежі. 3. Обробіть подію (позначити замовлення оплаченим, задати статус підписки, надіслати рахунок). 4. Швидко відповідайте 2xx; довгу роботу винесіть у чергу/фонове завдання.

Надійність

  • Повтори: Stripe надсилає знову, якщо ви не відповіли 2xx (протягом кількох днів). Ваш код має бути ідемпотентним: зберігайте ідентифікатор події (event.id) і ігноруйте дублікати; перевіряйте переходи станів.
  • Порядок не гарантований: події можуть прийти в іншому порядку; за потреби запитайте об’єкт у Stripe знову.
  • Збій бази даних: тоді відповідайте 5xx, щоб Stripe повторив, а не втратив події. З безсерверними базами даних, які спершу прокидаються, залиште достатній тайм-аут.
  • Тестовий/бойовий режим мають окремі секрети та кінцеві точки.
  • Stripe CLI (stripe listen --forward-to localhost:3000/api/stripe/webhook) для локального тесту.

Безпека і право

Зберігайте секрет у таємниці, лише HTTPS, лише потрібні події. Перевіряйте суму та валюту на сервері, не беріть їх із браузера. Персональні дані зберігайте ощадливо (дані карток зберігає Stripe, а не ви: навантаження PCI низьке з Checkout/Elements). Право: повідомлення про відмову, рахунки, умови, інформація про ціну, кнопка скасування для підписок, неповнолітні та договори (згода батьків). Це не юридична консультація.

Типові помилки

  • Тіло заздалегідь розібране як JSON → перевірка підпису не проходить.
  • Неправильний секрет (тестовий і бойовий, кілька кінцевих точок).
  • Немає ідемпотентності: подвійні зарахування/листи.
  • Надто повільна відповідь → лавина повторів.
  • Довіра лише перенаправленню.
  • Події не журналюються: із журналом подій (stripe_events) помилки можна простежити пізніше. Стежте за невдалими доставками в панелі.

Див. також: Stripe, Вебхуки, HMAC, Ідемпотентність, Платіжні сервіси для неповнолітніх