Webhooki — jak je projektować i obsługiwać bez utraty zdarzeń
Webhook to powiadomienie wysyłane przez zewnętrzny system w chwili, gdy coś się wydarzy: płatność została zaksięgowana, przesyłka zmieniła status, klient podpisał dokument. Zamiast co minutę pytać „czy coś się zmieniło", aplikacja czeka, aż ktoś ją powiadomi. To wygodne i wydajne — pod warunkiem, że odbiór jest zaprojektowany z założeniem, iż powiadomienie może przyjść dwa razy, w złej kolejności, od kogoś podszywającego się pod nadawcę albo wcale.
Krótka odpowiedź: poprawna obsługa webhooka to pięć zasad: zweryfikuj podpis nadawcy, odpowiedz natychmiast i przetwarzaj w tle, obsłuż powtórzenia tego samego zdarzenia, nie ufaj kolejności przychodzenia oraz miej mechanizm uzgadniania na wypadek zdarzeń, które nie dotarły.
Webhook jest sygnałem, że coś się zmieniło — nie ostatecznym źródłem prawdy. Przy zdarzeniach finansowych warto potwierdzić stan bezpośrednim zapytaniem do systemu nadawcy.
Webhook a odpytywanie
Alternatywą dla webhooka jest odpytywanie — aplikacja regularnie pyta zewnętrzny system o zmiany. Rozwiązanie proste i przewidywalne, ale nieefektywne: większość zapytań zwraca „nic nowego", a zmiana wykrywana jest z opóźnieniem równym odstępowi między zapytaniami.
| Zagadnienie | Odpytywanie | Webhook |
|---|---|---|
| Opóźnienie wykrycia zmiany | Do odstępu między zapytaniami | Zwykle sekundy |
| Obciążenie | Stałe, niezależne od liczby zmian | Proporcjonalne do zdarzeń |
| Wymaga publicznego adresu | Nie | Tak |
| Ryzyko utraty zdarzenia | Niskie | Istnieje — przy awarii odbiorcy |
| Kontrola nad tempem | Po stronie odbiorcy | Po stronie nadawcy |
| Złożoność zabezpieczeń | Niska | Wymaga weryfikacji nadawcy |
W praktyce najlepiej sprawdza się połączenie obu: webhook zapewnia szybkość, a rzadkie odpytywanie wyłapuje zdarzenia, które z jakiegoś powodu nie dotarły.
Weryfikacja nadawcy
Adres odbierający webhooki jest publiczny. Każdy, kto go pozna, może wysłać spreparowane zdarzenie „płatność zaksięgowana" i — przy braku weryfikacji — doprowadzić do wysyłki niezapłaconego towaru.
Standardowym zabezpieczeniem jest podpis: nadawca oblicza skrót treści powiadomienia z użyciem wspólnego sekretu i dołącza go w nagłówku. Odbiorca liczy ten sam skrót i porównuje.
- Weryfikuj podpis przed jakimkolwiek przetwarzaniem — przed zapisem do bazy, przed parsowaniem treści.
- Licz skrót z surowej treści, dokładnie w takiej postaci, w jakiej przyszła. Ponowne zakodowanie zmienia bajty i podpis przestaje się zgadzać.
- Porównuj w stałym czasie, żeby nie ujawniać informacji przez różnice w czasie odpowiedzi.
- Sprawdzaj znacznik czasu i odrzucaj powiadomienia starsze niż kilka minut — chroni to przed ponownym odtworzeniem przechwyconego zdarzenia.
- Trzymaj sekret poza kodem, w konfiguracji środowiska, z możliwością jego wymiany.
Uwaga praktyczna: najczęstszy błąd przy wdrożeniu to weryfikacja podpisu z treści już przetworzonej przez framework — sparsowanej i ponownie zserializowanej. Kolejność pól albo białe znaki się zmieniają, podpis się nie zgadza, a zniecierpliwiony programista wyłącza weryfikację „tymczasowo". To tymczasowe rozwiązanie zostaje na lata.
Odpowiedz szybko, przetwarzaj później
Nadawca czeka na odpowiedź ograniczony czas. Jeśli jej nie dostanie, uzna dostarczenie za nieudane i ponowi wysyłkę. Odbiorca, który w trakcie żądania wysyła maile, generuje dokumenty i wywołuje inne usługi, regularnie przekracza ten czas — i dostaje to samo zdarzenie ponownie, choć poprzednie zostało przetworzone.
Właściwy wzorzec: zweryfikuj podpis, zapisz zdarzenie do bazy, odpowiedz sukcesem. Właściwe przetwarzanie przekaż do kolejki zadań. Zapis zdarzenia przed odpowiedzią gwarantuje, że nawet awaria przetwarzania nie oznacza jego utraty.
Powtórzenia — nie wyjątek, lecz norma
Nadawcy gwarantują zwykle dostarczenie „co najmniej raz". Oznacza to, że to samo zdarzenie może przyjść dwa albo trzy razy i odbiorca musi sobie z tym poradzić.
- Zapisuj identyfikator zdarzenia nadany przez nadawcę i odrzucaj te, które już przetworzono.
- Zabezpiecz to na poziomie bazy ograniczeniem unikalności, a nie tylko sprawdzeniem w kodzie — dwa równoległe żądania mogą oba przejść sprawdzenie.
- Projektuj operacje odporne na powtórzenie. Oznaczenie zamówienia jako opłaconego drugi raz nie powinno wysyłać drugiego potwierdzenia.
- Odpowiadaj sukcesem także na duplikat. Błąd skłoni nadawcę do kolejnych ponowień.
Kolejność zdarzeń
Zdarzenia nie muszą przychodzić w kolejności, w jakiej zaszły. „Zamówienie anulowane" może dotrzeć przed „zamówienie opłacone", jeśli pierwsze powiadomienie wymagało ponowienia.
| Podejście | Jak działa | Kiedy stosować |
|---|---|---|
| Znacznik czasu zdarzenia | Ignorowanie zdarzeń starszych niż ostatnio przetworzone | Gdy liczy się tylko najnowszy stan |
| Numer wersji obiektu | Przetwarzanie tylko przy wyższej wersji | Gdy nadawca udostępnia wersjonowanie |
| Pobranie aktualnego stanu | Webhook jako sygnał, stan pobierany zapytaniem | Przy zdarzeniach krytycznych i finansowych |
| Maszyna stanów | Dozwolone tylko określone przejścia | Przy procesach o jasno opisanym cyklu życia |
Przy zdarzeniach finansowych najbezpieczniejsze jest trzecie podejście: powiadomienie mówi tylko, że coś się zmieniło, a aplikacja pyta system płatności o aktualny, rozstrzygający stan transakcji.
Zdarzenia, które nie dotarły
Nadawca ponawia wysyłkę przez określony czas, po czym się poddaje. Jeśli Twoja aplikacja była w tym czasie niedostępna — przez awarię, wdrożenie albo błąd konfiguracji — część zdarzeń przepada.
- Uzgadnianie cykliczne. Raz na kilka godzin pobierz listę zmian z systemu nadawcy i porównaj ze swoim stanem.
- Panel nadawcy. Większość systemów pokazuje historię dostarczeń i pozwala ponowić wysyłkę ręcznie — warto wiedzieć, gdzie to jest, zanim będzie potrzebne.
- Alert przy braku zdarzeń. Jeśli zwykle przychodzi ich kilkadziesiąt dziennie, a od sześciu godzin nie przyszło żadne, coś jest nie tak.
- Monitoring odpowiedzi błędnych po stronie odbiorcy — seria błędów to sygnał, zanim nadawca przestanie ponawiać.
Jeśli to Ty wysyłasz webhooki
Gdy Twój system powiadamia partnerów, obowiązują te same zasady od drugiej strony.
- Podpisuj każde powiadomienie i udostępnij partnerom sposób weryfikacji.
- Nadawaj unikalny identyfikator każdemu zdarzeniu, żeby odbiorca mógł wykryć powtórzenie.
- Ponawiaj z rosnącym odstępem i po wyczerpaniu prób oznacz dostarczenie jako nieudane.
- Udostępnij historię dostarczeń i możliwość ręcznego ponowienia.
- Wersjonuj format powiadomień — zmiana struktury to zmiana niezgodna wstecz, jak opisaliśmy w materiale o wersjonowaniu API.
- Nie wysyłaj wrażliwych danych w treści — lepiej przekazać identyfikator, a szczegóły udostępnić po uwierzytelnionym zapytaniu.
Testowanie
Webhooki trudno testować, bo wymagają publicznego adresu i zdarzenia wywołanego w systemie zewnętrznym. Warto przygotować się z wyprzedzeniem: zapisuj przykładowe prawdziwe powiadomienia jako materiał testowy, przygotuj narzędzie do ich ponownego wysłania na środowisko lokalne i sprawdź zachowanie przy duplikacie, zdarzeniu w złej kolejności oraz błędnym podpisie. Te trzy przypadki są najczęstszym źródłem błędów produkcyjnych.
Integracje z systemami płatności i przewoźników omawialiśmy przy okazji integracji z InPost, a szerzej o budowie systemów powiązanych z otoczeniem przeczytasz na stronie aplikacje webowe.
Webhooki a wdrożenia i awarie
Najwięcej zdarzeń ginie nie przez błędy w kodzie, lecz w momentach, gdy aplikacja jest chwilowo niedostępna — podczas wdrożenia, restartu serwera albo migracji na nową infrastrukturę.
Wdrożenie bez przerwy
Jeśli nowa wersja aplikacji uruchamia się, zanim stara przestanie przyjmować żądania, webhooki są obsługiwane bez przerwy. Jeśli wdrożenie polega na zatrzymaniu i ponownym uruchomieniu, przez kilkadziesiąt sekund nadawca dostaje błędy — i zaczyna ponawiać. Zwykle kończy się to dobrze, ale przy dłuższym wdrożeniu część zdarzeń może wyczerpać limit prób.
Zmiana adresu odbioru
Przeniesienie aplikacji na inną domenę albo zmiana ścieżki wymaga aktualizacji adresu w panelu każdego nadawcy. To krok regularnie pomijany przy migracjach, bo konfiguracja webhooków leży poza kodem aplikacji. Warto prowadzić listę wszystkich systemów wysyłających powiadomienia wraz z miejscem, w którym ustawia się adres.
Rotacja sekretu
Sekret służący do weryfikacji podpisu powinien dać się wymienić bez przerwy w działaniu. Najprostszy sposób: przez okres przejściowy aplikacja akceptuje podpisy liczone zarówno starym, jak i nowym sekretem, a po zmianie konfiguracji u nadawcy stary zostaje usunięty.
Dziennik odebranych zdarzeń
Zapis każdego przychodzącego powiadomienia — z datą, nagłówkami, wynikiem weryfikacji podpisu i statusem przetworzenia — jest bezcenny przy diagnozie. Pozwala odpowiedzieć na pytania, które przy integracjach padają najczęściej: czy zdarzenie w ogóle dotarło, czy zostało odrzucone, czy przetworzono je dwa razy.
Warto przechowywać taki dziennik przez kilka tygodni i udostępnić go w panelu administracyjnym, z możliwością ręcznego ponowienia przetwarzania pojedynczego zdarzenia. Treść powiadomień bywa jednak wrażliwa, więc dane osobowe i finansowe powinny być w dzienniku maskowane.
Na koniec praktyczna wskazówka: zanim uruchomisz integrację produkcyjnie, poproś nadawcę o wysłanie kilku zdarzeń testowych i celowo zwróć raz błąd. Zobaczysz, jak zachowuje się jego mechanizm ponowień i ile czasu masz na przywrócenie działania — to informacja, której zwykle brakuje w dokumentacji.
Podsumowanie
Webhook jest wygodnym sposobem otrzymywania informacji o zmianach, ale zaprojektowanym przy założeniu, że sieć jest zawodna. Poprawna obsługa wymaga weryfikacji podpisu, szybkiej odpowiedzi z przetwarzaniem w tle, odporności na powtórzenia, niezależności od kolejności i mechanizmu uzgadniania dla zdarzeń, które nie dotarły.
Jeśli masz już działającą integrację, sprawdź dwie rzeczy: czy podpis jest faktycznie weryfikowany i czy wysłanie tego samego zdarzenia dwa razy daje taki sam efekt jak raz. W zdecydowanej większości przeglądanych systemów przynajmniej jeden z tych punktów wymaga poprawki — a oba są przyczyną najbardziej kosztownych błędów.
Najczęstsze pytania
To powiadomienie wysyłane przez zewnętrzny system na wskazany adres w momencie, gdy wydarzy się określone zdarzenie — na przykład zaksięgowanie płatności lub zmiana statusu przesyłki. Zastępuje ciągłe odpytywanie o zmiany, dzięki czemu informacja dociera szybciej i przy mniejszym obciążeniu.
Weryfikując podpis dołączony przez nadawcę, liczony z surowej treści powiadomienia i wspólnego sekretu, porównując go w stałym czasie oraz odrzucając powiadomienia ze zbyt starym znacznikiem czasu. Weryfikacja musi nastąpić przed jakimkolwiek przetwarzaniem treści.
Traktować to jako normę, nie błąd. Zapisywać identyfikator zdarzenia z ograniczeniem unikalności w bazie, pomijać zdarzenia już przetworzone, odpowiadać sukcesem także na duplikat i projektować operacje tak, by ich powtórzenie nie wywoływało podwójnych skutków.
Bo nadawca czeka na odpowiedź ograniczony czas i po jego przekroczeniu ponawia wysyłkę. Właściwy wzorzec to weryfikacja podpisu, zapis zdarzenia i natychmiastowa odpowiedź, a właściwe przetwarzanie w kolejce zadań. Zapis przed odpowiedzią chroni też przed utratą zdarzenia.
Przez cykliczne uzgadnianie stanu z systemem nadawcy, alert przy nietypowym braku zdarzeń, monitoring błędnych odpowiedzi oraz znajomość panelu nadawcy pozwalającego ręcznie ponowić dostarczenie. Webhook warto traktować jako szybki sygnał, a nie jedyne źródło informacji o zmianach.
Convert Studio realizuje projekty z tego obszaru dla firm w całej Polsce. Zobacz: Aplikacje webowe → · Lokalizacje →
Bezpłatna wycena Twojego projektu
Opisz w kilku zdaniach, co chcesz zbudować — stronę, aplikację czy sklep. Odpowiadamy w ciągu 24 godzin roboczych konkretną propozycją zakresu i harmonogramu. Konsultacja i wycena są bezpłatne, bez zobowiązań.