Spolehlivá integrace

Jak správně zpracovávat webhooky

Webhook může přijít pozdě, dvakrát nebo ve špatnou chvíli. Připrav endpoint tak, aby to ustál.

20 minut · Symfony a Messenger

Nejdřív stručně

Co je webhook?

Webhook je HTTP požadavek, který ti jiná služba pošle při události. Třeba když zákazník zaplatí objednávku.

Endpoint nebere jako důkaz. Nejdřív ověř podpis. Pak událost bezpečně ulož nebo pošli do fronty. Až potom vrať úspěšnou odpověď.

Připrav si

Co budeš potřebovat

Začni malým a bezpečným základem.

  • Veřejnou HTTPS adresu pro endpoint. Lokální počítač sám o sobě poskytovatel obvykle nedosáhne.
  • Dokumentaci poskytovatele: formát události, hlavičku s podpisem a jeho testovací režim. HTTP hlavičku nevynechávej.
  • Tajný podpisový klíč uložený v proměnné prostředí, ne ve zdrojovém kódu.
  • Databázi nebo frontu zpráv, kam rychle předáš další práci.

Krok 1

Postav endpoint, který vydrží opakování

Nejdůležitější pravidlo: ověř, zapiš, zařaď práci, odpověz. Nedělej vše přímo v HTTP požadavku.

1. Přijmi jen potřebný požadavek

  1. Vytvoř samostatnou POST cestu. Nedávej ji do běžného formuláře ani na ni nenavazuj přihlášení uživatele.
  2. Přečti si surové tělo požadavku. Podpis se často počítá právě z něj, ne z upraveného pole v PHP.
  3. Zkontroluj typ události a její identifikátor. Neznámé typy zaloguj a bezpečně ignoruj.
#[Route('/webhooks/payment', methods: ['POST'])]
Symfony: routing

2. Ověř podpis dřív než data použiješ

  1. Použij přesný postup z dokumentace poskytovatele. Často jde o HMAC podpis a časové razítko.
  2. Porovnávej podpis bezpečně. Při chybě vrať 400 nebo 401 a událost nezpracovávej.
  3. Podpisový klíč nikdy neposílej do prohlížeče, logu ani chybové odpovědi.
hash_equals($expectedSignature, $receivedSignature)
PHP: hash_equals

3. Událost zpracuj mimo odpověď

  1. Ulož ID události s unikátním omezením. Tím zajistíš idempotenci: stejná událost nic nezmění podruhé.
  2. Do fronty pošli jen data potřebná pro další krok. Velký původní payload si případně ulož zvlášť pro dohledání.
  3. Po úspěšném uložení vrať rychle stav 200 nebo 204. Dlouhou práci nechej consumeru.
php bin/console messenger:consume async -vv
Symfony Messenger

Krok 2

Ověř si celý tok

Nečekej na první skutečnou platbu. Použij testovací událost od poskytovatele.

  1. Pošli testovací událost

    V administraci služby najdi test webhooku. Očekávej rychlou odpověď 2xx a záznam o přijetí.

  2. Pošli ji ještě jednou

    Ve výpisu uvidíš druhý pokus, ale objednávka nebo platba se nesmí změnit podruhé. To je kontrola idempotence.

  3. Zkontroluj frontu a výsledek

    Worker musí úlohu dokončit. Při chybě máš vidět důvod a bezpečný plán dalšího pokusu.

    php bin/console messenger:failed:show

Když to zlobí

Nejčastější chyby

Poskytovatel opakuje stejnou událost

To je běžné chování po výpadku nebo pomalé odpovědi. Ukládej jedinečné ID události a zpracuj ho jen jednou. Pomůže ti idempotence.

Podpis nesouhlasí

Porovnej použitý tajný klíč, surové tělo požadavku a název hlavičky. Neobcházej ověření jen proto, aby test prošel.

Endpoint odpovídá pomalu nebo 500

Vrať úspěch až po bezpečném uložení události. Odeslání e-mailu, volání API a další pomalou práci přesuň do fronty zpráv.

Nezdařená úloha se ztratí

Nastav omezené opakování, logování a failed transport. Nekonečné opakování může zhoršit chybu i náklady.

Hotovo

Webhook má pevný základ.

Webhook teď ověřuješ, zpracováváš jen jednou a dlouhou práci necháváš na frontě.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.