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.
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
- Vytvoř samostatnou POST cestu. Nedávej ji do běžného formuláře ani na ni nenavazuj přihlášení uživatele.
- 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.
- 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š
- Použij přesný postup z dokumentace poskytovatele. Často jde o HMAC podpis a časové razítko.
- Porovnávej podpis bezpečně. Při chybě vrať 400 nebo 401 a událost nezpracovávej.
- 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ěď
- Ulož ID události s unikátním omezením. Tím zajistíš idempotenci: stejná událost nic nezmění podruhé.
- Do fronty pošli jen data potřebná pro další krok. Velký původní payload si případně ulož zvlášť pro dohledání.
- 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.
-
Pošli testovací událost
V administraci služby najdi test webhooku. Očekávej rychlou odpověď 2xx a záznam o přijetí.
-
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.
-
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ě.