Джерела
Джерело — це URL, який ви даєте провайдеру — Stripe, GitHub чи будь-чому іншому, що підписує свої вебхуки, — щоб він міг надсилати нам. Ми перевіряємо підпис кожного запиту, перетворюємо запит на подію й доставляємо її на ваші ендпоінти точно так само, як подію, яку ви опублікували самі: ті самі підписки, ті самі повтори, та сама dead-letter черга.
Використовуйте джерело, коли хочете мати одне місце для трафіку вебхуків в обох напрямках або коли хочете, щоб кілька ваших сервісів отримували події одного провайдера й кожен не перевіряв підпис Stripe самостійно.
Як запит стає доставками
- Провайдер надсилає POST на URL прийому джерела,
https://webhooks.nimbusnexus.net/v1/ingest/{source_id}. - Ми перевіряємо підпис по точних отриманих байтах за допомогою секрету підпису джерела.
- Тіло має бути обʼєктом JSON. Ми читаємо з нього тип події (див. Типи подій із джерела).
- Подія публікується в проєкт джерела й зіставляється з підписками ваших ендпоінтів, що створює одну доставку на кожен відповідний ендпоінт.
- Провайдер отримує
202. Ваші ендпоінти отримують подію, підписану їхнім секретом, а не секретом провайдера.
URL прийому — єдина частина Webhooks, яка приймає запити без API-ключа: обліковими даними тут є підпис провайдера.
Провайдери та їхні підписи
| Провайдер | Заголовок, який ми перевіряємо | Підписані байти | Replay-вікно |
|---|---|---|---|
stripe | Stripe-Signature: t=…,v1=… | {t}.{body} | 5 хв |
github | X-Hub-Signature-256: sha256=… | {body} | немає (GitHub не надсилає timestamp) |
generic | X-Webhook-Signature: sha256=… з X-Webhook-Timestamp | {timestamp}.{body} | 5 хв |
Усі три — HMAC-SHA256. generic — та сама схема, якою ми підписуємо власні доставки, тож ендпоінт одного робочого простору Webhooks може живити джерело іншого, а будь-який відправник, який ви контролюєте, може підписувати так кількома рядками коду.
Створіть джерело
У консолі: Sources → New source (також на сторінці Overview). Або через API:
curl -sX POST https://webhooks.nimbusnexus.net/v1/sources \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "stripe",
"name": "Stripe live",
"secret": "whsec_…",
"event_type_prefix": "stripe."
}'- Stripe і GitHub: вставте секрет підпису, який показує вам провайдер. Джерело, створене без нього, спочатку вимкнене; додайте секрет пізніше через
rotate-secretі ввімкніть джерело. - Generic: не передавайте
secret, і ми згенеруємо його самі; він повертається один раз у цій відповіді.
Відповідь містить ingest_url. Вставте його в налаштування вебхуків провайдера й додайте ендпоінт, підписаний на типи, які ви очікуєте (вище — prefix stripe.).
Типи подій із джерела
Кожному запиту потрібен тип події, на який можуть підписатися ендпоінти. Джерело знаходить його в такому порядку:
- Там, де ви сказали шукати: у заголовку запиту або за JSON-шляхом із крапками в тілі (
data.object.type). - Інакше — там, де його розміщує сам провайдер: у полі
typeтіла для Stripe і generic, у заголовкуX-GitHub-Eventдля GitHub. - Якщо жодне не дає значення, — тип за замовчуванням джерела, а якщо його немає, —
webhook.received.
Префікс джерела додається на початок (stripe. + invoice.paid → stripe.invoice.paid), що розділяє типи двох провайдерів в одному проєкті. Якщо у вашому списку типів подій є webhook.received, джерело отримало запити без типу, який воно змогло б прочитати: задайте для цього джерела тип за замовчуванням або JSON-шлях.
Власний ідентифікатор події провайдера (evt_… у Stripe, ідентифікатор доставки в GitHub) є ключем ідемпотентності, тож коли провайдер повторює подію, яку ми вже прийняли, він знову отримує 202, і нічого не доставляється двічі.
Що бачить провайдер
| Статус | Коли |
|---|---|
202 | Прийнято й опубліковано. |
400 | Тіло не є JSON або не є обʼєктом JSON. |
401 | Підпис не пройшов перевірку: відсутній, некоректний, не той секрет або поза replay-вікном. Одна відповідь для всіх цих випадків — навмисно. |
402 | Робочий простір вичерпав місячний обсяг доставок. |
404 | Такого джерела немає, або джерело вимкнене. |
409 | Ідентифікатор події провайдера вже прийнято з іншим тілом. |
413 | Запит перевищує 512 KiB або payload перевищує 256 KiB. |
422 | Тип не зареєстровано, а політика типів подій — Strict, або payload не відповідає JSON Schema типу. |
429 | Забагато запитів: 600 на хвилину на джерело до перевірки підпису, а потім — частота публікацій вашого плану. |
Провайдери повторюють запит у відповідь на будь-що, крім 2xx, тож відмова на їхньому боці не губиться, але щоб побачити, чому ми відмовили, увімкніть запис для джерела й перегляньте Перехоплені запити.
Ротація секрету
Коли провайдер змінює свій секрет, надішліть новий:
curl -sX POST https://webhooks.nimbusnexus.net/v1/sources/src_…/rotate-secret \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"secret": "whsec_new…"}'Попередній секрет і далі проходить перевірку протягом 24 годин, тож поки провайдер переходить на новий, приймаються запити, підписані будь-яким із двох. Для джерела generic надішліть порожнє тіло, і ми згенеруємо новий секрет.
Що далі
- Перехоплені запити — сирі запити, які отримало джерело, включно з відхиленими.
- Джерела в довіднику API — усі операції з джерелами з викликами SDK і CLI.
- Типи подій — каталог типів і що відбувається з невідомим типом.
- Доставки та повтори — що відбувається після публікації події.
- Огляд Webhooks — обʼєкти і як вони повʼязані між собою.