Надійне приймання вебхуків Stripe
Цей гайд ставить Railhook між Stripe і вашим застосунком. Stripe надсилає вебхуки на джерело Railhook, яке перевіряє підпис, зберігає кожну подію в тому вигляді, в якому вона надійшла, і пересилає її на ваш сервіс. Коли ваш сервіс недоступний, нічого не губиться: пересилання повторюються, а те, що все одно не вдалося, можна відтворити пізніше.
Чому самих повторів Stripe недостатньо
Section titled “Чому самих повторів Stripe недостатньо”Stripe повторює спроби. У live-режимі він пробує доставити невдалу подію до трьох днів з експоненційною затримкою; у пісочниці — тричі за кілька годин. Після цього Dashboard може повторно надіслати подію протягом 15 днів, а Stripe CLI — протягом 30. Stripe також зазначає, що події можуть надходити не по порядку і що ендпоінт може отримати ту саму подію більше одного разу. (Stripe: Receive Stripe events in your webhook endpoint)
Що це залишає на вас:
- Ваш обробник має відповідати швидко. Stripe просить повернути
2xxдо будь-якої складної логіки, інакше доставка сплине за таймаутом і вважатиметься невдалою. Railhook відповідає Stripe, щойно подію збережено, а ваш сервіс може працювати стільки, скільки дозволяє таймаут призначення. - Відновлення — по одній події. Після довшого збою повторне надсилання з Dashboard означає клацати подію за подією. Railhook відтворює всі збережені події за проміжок часу одним викликом.
- Дублікати доходять до вашого коду. Railhook розпізнає ідентифікатор
evt_…: на повторну доставку тієї самої події він відповідає202зі збереженою копією й не пересилає її вдруге.
Підключення Stripe
Section titled “Підключення Stripe”Знадобляться проєкт Railhook і API-ключ. Усе нижче також можна зробити в розділі Вхідні панелі керування.
export RAILHOOK_URL=https://railhook.io # or your own instanceexport RAILHOOK_API_KEY=...export PROJECT_ID=...-
Створіть джерело. Stripe показує секрет підпису лише після реєстрації адреси, тож спершу створіть джерело без секрету. З
verificationModeзі значеннямPROVIDERі без секрету воно відхиляє кожен запит із401, доки ви його не додасте, тож тим часом нічого неперевіреного не зберігається.Terminal window curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources" \-H "X-API-Key: $RAILHOOK_API_KEY" \-H "Content-Type: application/json" \-d '{"name":"Stripe","providerType":"STRIPE","verificationMode":"PROVIDER"}'Збережіть
idіingressUrlіз відповіді. -
Зареєструйте адресу в Stripe. У Workbench відкрийте Webhooks і натисніть Create an event destination. Оберіть Your account, позначте типи подій, які обробляєте, оберіть Webhook endpoint і вставте
ingressUrlяк Endpoint URL. -
Передайте Railhook секрет підпису. На сторінці ендпоінта в Stripe натисніть Reveal secret і скопіюйте значення, що починається з
whsec_. Задайте його джерелу:Terminal window curl -X PUT "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources/$SOURCE_ID" \-H "X-API-Key: $RAILHOOK_API_KEY" \-H "Content-Type: application/json" \-d '{"name":"Stripe","hmacSecret":"whsec_..."}'Змінюються лише надіслані поля; секрет лише для запису, API його ніколи не повертає.
-
Додайте призначення. Це адреса вашого сервісу, який має отримувати події:
Terminal window curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources/$SOURCE_ID/destinations" \-H "X-API-Key: $RAILHOOK_API_KEY" \-H "Content-Type: application/json" \-d '{"url":"https://api.example.com/webhooks/stripe","authType":"BEARER","authConfig":"{\"token\":\"...\"}","enabled":true}' -
Надішліть тестову подію зі Stripe або виконайте
stripe trigger payment_intent.succeeded. Вона з’явиться в розділі Вхідні → Отримані, з одним пересиланням на кожне призначення.
Як перевіряється підпис
Section titled “Як перевіряється підпис”Railhook читає Stripe-Signature, обчислює шістнадцятковий HMAC-SHA256 від <t>.<raw body> із секретом whsec_ і порівнює його з кожним значенням v1. t має бути в межах 300 секунд від годинника Railhook. Поки ви змінюєте секрет у Stripe, він надсилає по одному v1 на кожен активний секрет; запит проходить перевірку, якщо збігається будь-який із них, тож задайте джерелу новий секрет одразу після зміни. Запит, що не пройшов перевірку, отримує 401 і не зберігається, а Stripe його повторює.
Що отримує ваш сервіс
Section titled “Що отримує ваш сервіс”Тіло точно таке, яким його надіслав Stripe, байт у байт, з його Content-Type. Stripe-Signature не пересилається: ваш сервіс автентифікує Railhook за обліковими даними призначення, тож секрет Stripe йому взагалі не потрібен. Кожен запит містить Idempotency-Key, незмінний між спробами, і X-Forward-Attempt. Див. Призначення.
Пересилання повторюється на 408, 429, будь-який 5xx, таймаут чи помилку з’єднання — до 5 спроб. Будь-який інший 4xx одразу переносить його в «Невдалі пересилання», звідки його можна повторити, виправивши сервіс.
Локальна розробка з CLI
Section titled “Локальна розробка з CLI”Спрямуйте призначення на свою машину через тунель, і тестові події Stripe дійдуть до коду у вашому редакторі вже після перевірки в Railhook.
-
Встановіть CLI й увійдіть, як описано в CLI, а потім відкрийте тунель до порту вашого застосунку:
Terminal window railhook listen 3000 -
Додайте джерелу друге призначення з виведеною публічною адресою й вашим маршрутом у кінці, наприклад
https://<host>/tunnel/<slug>/webhooks/stripe. Шлях після адреси тунелю зберігається, тож запит потрапить наhttp://localhost:3000/webhooks/stripe. -
Згенеруйте подію в пісочниці Stripe. Коли закриєте тунель, вимкніть або видаліть це призначення, щоб його пересилання не накопичувалися в «Невдалих пересиланнях».
Повтор подій після збою
Section titled “Повтор подій після збою”Якщо ваш сервіс лежав довше, ніж тривали повтори, відтворіть те, що надійшло за цей час. Це створює нові пересилання на кожне призначення джерела, знову зі спроби 1:
curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-events/bulk-replay" \ -H "X-API-Key: $RAILHOOK_API_KEY" \ -H "Content-Type: application/json" \ -d '{"sourceId":"'"$SOURCE_ID"'","from":"2026-09-18T10:00:00Z","to":"2026-09-18T14:00:00Z","verified":true}'Обробник усе одно має бути ідемпотентним за ідентифікатором події Stripe, бо повтор надсилає й ті події, які ваш сервіс, можливо, вже обробив. Повтор сягає так далеко, як довго зберігаються події: 7 днів у Railhook Cloud і скільки налаштуєте на власному сервері. Див. Повтор.