Одержувач вебхука може бути недоступним, повільним чи повертати помилку - доставка мусить це пережити.
Архітектура відправлення:
- подія фіксується в базі в тій самій транзакції, що й зміна даних (запис «вебхук до відправки»). Інакше при падінні після коміту подія загубиться - патерн outbox;
- джоба в черзі надсилає запит;
- результат кожної спроби записується в журнал доставок.
final class DeliverWebhook implements ShouldQueue
{
public $tries = 8;
public function __construct(public WebhookDelivery $delivery) {}
public function backoff(): array
{
return [10, 60, 300, 1800, 3600, 7200, 21600]; // секунди: до кількох годин
}
public function handle(): void
{
$response = Http::timeout(5)
->withHeaders($this->delivery->signatureHeaders())
->post($this->delivery->endpoint->url, $this->delivery->payload);
$this->delivery->recordAttempt($response->status());
if ($response->failed()) {
throw new WebhookDeliveryFailed($response->status());
}
}
}
Правила повторів:
- наростаюча затримка (експоненційна, з випадковим розкидом) - щоб не «добити» сервер одержувача, який відновлюється, і щоб тисячі вебхуків не повторювалися синхронно;
- повторювати мережеві помилки, тайм-аути, 5xx і 429 (з урахуванням
Retry-After); 4xx на кшталт 400, 404, 410 - зазвичай ні: повтор не допоможе; - загальний горизонт - години чи дні (Stripe повторює до трьох днів), після чого доставка позначається невдалою.
Журнал доставок у кабінеті клієнта: подія, URL, час, код відповіді, фрагмент тіла відповіді, кількість спроб, кнопка «надіслати повторно». Найкорисніша функція для підтримки - більшість звернень «вебхук не прийшов» вирішуються переглядом журналу.
Захист від «мертвих» одержувачів: якщо ендпойнт падає днями, його автоматично вимикають і повідомляють власника листом - інакше черга забивається безнадійними спробами.
Ізоляція: вебхуки - в окремій черзі з власними воркерами, щоб повільні одержувачі не затримували решту фонових задач застосунку.
Готові інструменти: spatie/laravel-webhook-server (черга, підпис, повтори, події WebhookCallFailedEvent), або зовнішні сервіси доставки вебхуків, якщо обсяги великі.
Важливо для одержувачів: доставка «щонайменше один раз» означає дублікати - документуйте, що обробка має бути ідемпотентною за id події.
Докладніше в документації: Stripe: автоматичні повтори вебхуків