Перейти до вмісту
NimbusNexus

Джерела

Джерело — це URL, який ви даєте провайдеру — Stripe, GitHub чи будь-чому іншому, що підписує свої вебхуки, — щоб він міг надсилати нам. Ми перевіряємо підпис кожного запиту, перетворюємо запит на подію й доставляємо її на ваші ендпоінти точно так само, як подію, яку ви опублікували самі: ті самі підписки, ті самі повтори, та сама dead-letter черга.

Використовуйте джерело, коли хочете мати одне місце для трафіку вебхуків в обох напрямках або коли хочете, щоб кілька ваших сервісів отримували події одного провайдера й кожен не перевіряв підпис Stripe самостійно.

Як запит стає доставками

  1. Провайдер надсилає POST на URL прийому джерела, https://webhooks.nimbusnexus.net/v1/ingest/{source_id}.
  2. Ми перевіряємо підпис по точних отриманих байтах за допомогою секрету підпису джерела.
  3. Тіло має бути обʼєктом JSON. Ми читаємо з нього тип події (див. Типи подій із джерела).
  4. Подія публікується в проєкт джерела й зіставляється з підписками ваших ендпоінтів, що створює одну доставку на кожен відповідний ендпоінт.
  5. Провайдер отримує 202. Ваші ендпоінти отримують подію, підписану їхнім секретом, а не секретом провайдера.

URL прийому — єдина частина Webhooks, яка приймає запити без API-ключа: обліковими даними тут є підпис провайдера.

Провайдери та їхні підписи

ПровайдерЗаголовок, який ми перевіряємоПідписані байтиReplay-вікно
stripeStripe-Signature: t=…,v1=…{t}.{body}5 хв
githubX-Hub-Signature-256: sha256=…{body}немає (GitHub не надсилає timestamp)
genericX-Webhook-Signature: sha256=… з X-Webhook-Timestamp{timestamp}.{body}5 хв

Усі три — HMAC-SHA256. generic — та сама схема, якою ми підписуємо власні доставки, тож ендпоінт одного робочого простору Webhooks може живити джерело іншого, а будь-який відправник, який ви контролюєте, може підписувати так кількома рядками коду.

Створіть джерело

У консолі: Sources → New source (також на сторінці Overview). Або через API:

Shell
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.).

Типи подій із джерела

Кожному запиту потрібен тип події, на який можуть підписатися ендпоінти. Джерело знаходить його в такому порядку:

  1. Там, де ви сказали шукати: у заголовку запиту або за JSON-шляхом із крапками в тілі (data.object.type).
  2. Інакше — там, де його розміщує сам провайдер: у полі type тіла для Stripe і generic, у заголовку X-GitHub-Event для GitHub.
  3. Якщо жодне не дає значення, — тип за замовчуванням джерела, а якщо його немає, — 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, тож відмова на їхньому боці не губиться, але щоб побачити, чому ми відмовили, увімкніть запис для джерела й перегляньте Перехоплені запити.

Ротація секрету

Коли провайдер змінює свій секрет, надішліть новий:

Shell
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 надішліть порожнє тіло, і ми згенеруємо новий секрет.

Що далі