Handlery a spracovanie
Endpoint si ukladá alias handlera, nikdy názov triedy. Naviažte ho v config/webhooks.php ('handlers' => ['billing' => BillingWebhookHandler::class]) alebo v boot() service providera:
// AppServiceProvider::boot() — lasts for the whole process: every request, every job a queue
// worker runs, every Octane request
Webhooks::handlers()->register('billing', BillingWebhookHandler::class);
// a closure works too
Webhooks::handlers()->register('audit', function (InboundWebhook $webhook): void {
logger()->info('webhook', ['id' => $webhook->deliveryId, 'type' => $webhook->type]);
});Alias zodpovedá ^[a-z0-9][a-z0-9_.-]{0,99}$; trieda handlera sa vytvára cez kontajner. Endpoint bez handlera správu aj tak uloží, zaradí a vyvolá WebhookReceived — stačí počúvať udalosť.
Písanie handlera
final class BillingWebhookHandler implements InboundHandler
{
public function handle(InboundWebhook $webhook): void
{
// $webhook->deliveryId public id — your own idempotency key for side effects that must never repeat
// $webhook->type the scheme's event type, else the payload's "type"
// $webhook->payload sanitized, untrusted array — validate it
// $webhook->headers the stored allowlist (inbound.store_headers)
// $webhook->endpoint the InboundEndpoint
// $webhook->isReplay, ->run, ->attempt, ->receivedAt
$invoice = $webhook->get('data.invoice.id'); // dot path into the payload, or null
$agent = $webhook->header('User-Agent'); // a stored header, case-insensitive
$team = $webhook->owner(); // the endpoint's owner, or null
}
}Obsah je dekódovaný len do polí, sanitizovaný a stále nedôveryhodný — pred použitím ho overte a žiadnu hodnotu nepoužívajte ako názov triedy, cestu k súboru, URL ani časť dopytu bez kontroly voči zoznamu povolených:
$data = Validator::make($webhook->payload, [
'data.invoice.id' => ['required', 'integer'],
])->validate();Vo fronte, raz na doručenie
- ProcessInboundDelivery beží vo fronte webhooks.queue.inbound: najprv sa vyvolá WebhookReceived, potom handler. Pokusy inbound.handler.tries (3), odstup [10, 60, 300], limit 60 s.
- Idempotentný middleware jobov zo Sentinelu zabezpečí, že dvojité zaradenie, opakovanie od odosielateľa či opätovné zaradenie pravidelným behom spustí handler raz.
- Po poslednom neúspešnom pokuse je doručenie failed s last_error_code handler_failed, bezpečným zhrnutím — krátkym názvom výnimky a krátkym kódom, napríklad QueryException (23000), nikdy jej správou, ktorá môže citovať obsah — a udalosťou WebhookProcessingFailed. Celá výnimka sa do logu dostane cez zlyhaný job.
- Doručenie, ktorého endpoint bol zmazaný pred spracovaním, zlyhá okamžite (endpoint_deleted).
- WebhookReceived sa vyvolá pri každom pokuse behu: $webhook->attempt a isFirstAttempt() ich rozlíšia.
- Stavy: received → queued → processing → processed | failed. Joby nesú tagy pre Horizon (webhooks, webhooks:inbound, webhooks:delivery:{id}, webhooks:run:{n}).
Presne jedno spracovanie platí pre všetky bežné cesty. Ak sa worker ukončí potom, čo handler skončil, no predtým, ako Sentinel zaznamenal dokončenie, nájom vyprší a handler sa spustí znova — pre vedľajšie efekty, ktoré sa nesmú zopakovať, použite $webhook->deliveryId ako vlastný kľúč idempotencie.
Replay
Webhooks::inbound()->replay($delivery); // runs + 1, isReplay = true, same stored payloadReplay otvorí nový beh nad uloženým obsahom označený isReplay. Vymazaný obsah vyhodí PayloadPrunedException; doručenie, ktoré sa práve spracúva, vyhodí DeliveryInProgressException — ibaže jeho posledný pokus začal pred dlhším časom ako limit handlera + 30 s + najdlhší odstup + 90 s (jeho worker skončil); také už replay umožní. Z konzoly: webhooks:replay {verejné id}.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.