15 gru 2024·7 min czytania

Lista kontrolna idempotentnych webhooków płatności dla bezpiecznych aktualizacji rozliczeń

Lista kontrolna idempotentnych webhooków płatności — jak deduplikować zdarzenia, obsługiwać ponowne wysyłki i bezpiecznie aktualizować faktury, subskrypcje oraz uprawnienia.

Lista kontrolna idempotentnych webhooków płatności dla bezpiecznych aktualizacji rozliczeń

Dlaczego webhooki płatności powodują duplikaty aktualizacji

Webhook płatności to komunikat, który dostawca płatności wysyła do backendu, gdy coś ważnego się wydarzy — np. opłata zakończona sukcesem, faktura opłacona, odnowienie subskrypcji czy zwrot. To w zasadzie dostawca mówiący: „To się wydarzyło. Zaktualizuj swoje rekordy.”

Duplikaty pojawiają się, ponieważ dostawa webhooków jest zaprojektowana jako niezawodna, nie jako dokładnie raz. Jeśli twój serwer jest wolny, przekracza timeout, zwraca błąd lub jest chwilowo niedostępny, dostawca zwykle ponowi to samo zdarzenie. Możesz też dostać dwa różne zdarzenia odnoszące się do tej samej akcji w świecie rzeczywistym (na przykład zdarzenie faktury i zdarzenie płatności związane z jedną opłatą). Zdarzenia mogą też przychodzić poza kolejnością, zwłaszcza przy szybkich follow-upach jak zwroty.

Jeśli handler nie jest idempotentny, może zastosować to samo zdarzenie dwa razy, co przekłada się na problemy widoczne od razu dla klientów i zespołów finansów:

  • Faktura oznaczona jako opłacona dwa razy, tworząc zdublowane wpisy księgowe
  • Odnowienie zastosowane dwukrotnie, przedłużające dostęp za bardzo
  • Uprawnienia przyznane dwa razy (dodatkowe kredyty, miejsca lub funkcje)
  • Zwroty lub chargebacki nieodwracające dostępu prawidłowo

To nie tylko „dobra praktyka”. To różnica między rozliczeniami, które wydają się wiarygodne, a takimi, które generują zgłoszenia do supportu.

Celem tej listy kontrolnej jest prosta zasada: traktuj każde przychodzące zdarzenie jako „zastosować co najwyżej raz”. Będziesz przechowywać stabilny identyfikator każdego zdarzenia, bezpiecznie obsługiwać ponowne wysyłki i aktualizować faktury, subskrypcje oraz uprawnienia w kontrolowany sposób. Jeśli budujesz backend w narzędziu no-code takim jak AppMaster, te same zasady nadal obowiązują: potrzebujesz jasnego modelu danych i powtarzalnego flow handlera, który pozostaje poprawny przy ponowieniach.

Podstawy idempotencji, które możesz zastosować do webhooków

Idempotencja oznacza, że przetworzenie tego samego wejścia wielokrotnie daje ten sam stan końcowy. W terminach rozliczeń: jedna faktura jest opłacona raz, jedna subskrypcja aktualizuje się raz, a dostęp jest przyznany raz, nawet jeśli webhook dostarczono dwukrotnie.

Dostawcy ponawiają, gdy twój endpoint timeoutuje, zwraca 5xx lub sieć upada. Te ponowienia powtarzają to samo zdarzenie. To różni się od odrębnego zdarzenia, które reprezentuje rzeczywistą zmianę, jak zwrot dni później. Nowe zdarzenia mają różne ID.

Aby to działało, potrzebujesz dwóch rzeczy: stabilnych identyfikatorów i małej „pamięci” tego, co już widziałeś.

Jakie ID są ważne (i co przechowywać)

Większość platform płatniczych ma ID zdarzenia, które jest unikalne dla eventu webhook. Niektóre zawierają też request ID, idempotency key lub unikalne ID obiektu płatności (jak charge lub payment intent) w ładunku.

Zapisz to, co pomaga odpowiedzieć na pytanie: „Czy już zastosowałem to dokładne zdarzenie?”

Praktyczne minimum:

  • ID zdarzenia (klucz unikalny)
  • Typ zdarzenia (przydatny do debugowania)
  • Znacznik czasu otrzymania
  • Status przetwarzania (processed/failed)
  • Referencja do dotkniętego klienta, faktury lub subskrypcji

Kluczowy ruch to zapisanie ID zdarzenia w tabeli z unikalnym ograniczeniem. Wtedy handler może zrobić to bezpiecznie: wstawić ID zdarzenia najpierw; jeśli już istnieje, zatrzymać się i zwrócić 200.

Jak długo przechowywać rekordy deduplikujące

Przechowuj rekordy wystarczająco długo, by pokryć późne ponowienia i dochodzenia. Typowe okno to 30–90 dni. Jeśli masz chargebacki, spory lub dłuższe cykle subskrypcyjne, przechowuj je dłużej (6–12 miesięcy) i okresowo usuwaj stare wiersze, żeby tabela pozostała szybka.

W wygenerowanym backendzie jak AppMaster, mapuje się to czysto na prosty model WebhookEvents z polem unikalnym na ID zdarzenia i Business Process, który wychodzi wcześnie, gdy wykryje duplikat.

Zaprojektuj prosty model danych do deduplikacji zdarzeń

Dobry handler webhooków to w większości problem danych. Jeśli potrafisz zapisać każde zdarzenie dostawcy dokładnie raz, wszystko co potem następuje staje się bezpieczniejsze.

Zacznij od jednej tabeli, która działa jak dziennik potwierdzeń. W PostgreSQL (w tym kiedy modelujesz w AppMaster Data Designer) trzymaj ją małą i ścisłą, tak aby duplikaty kończyły się błędem szybko.

Minimum, którego potrzebujesz

Oto praktyczne minimum dla tabeli webhook_events:

  • provider (tekst, np. "stripe")
  • provider_event_id (tekst, wymagane)
  • status (tekst, np. "received", "processed", "failed")
  • processed_at (timestamp, nullable)
  • raw_payload (jsonb lub tekst)

Dodaj unikalne ograniczenie na (provider, provider_event_id). Ta jedna reguła to główna straż deduplikacji.

Będziesz też potrzebować identyfikatorów biznesowych, których używasz do wyszukiwania rekordów do aktualizacji. Różnią się one od ID zdarzenia webhook.

Przykłady to customer_id, invoice_id i subscription_id. Trzymaj je jako tekst, ponieważ dostawcy często używają ID nienumerycznych.

Surowy payload vs. sparsowane pola

Zapisz surowy payload, aby móc debugować i przetworzyć ponownie później. Parsowane pola ułatwiają zapytania i raportowanie, ale przechowuj tylko to, czego rzeczywiście używasz.

Proste podejście:

  • Zawsze zapisuj raw_payload
  • Dodatkowo zapisuj kilka sparsowanych ID, które często zapytujesz (customer, invoice, subscription)
  • Zapisuj znormalizowany event_type (tekst) do filtrowania

Jeśli invoice.paid przyjdzie dwa razy, unikalne ograniczenie zablokuje drugą wstawkę. Nadal masz surowy payload do audytu, a sparsowane ID faktury ułatwia znalezienie rekordu faktury, który zaktualizowałeś za pierwszym razem.

Krok po kroku: bezpieczny flow handlera webhooków

Bezpieczny handler jest nudny z premedytacją. Zachowuje się tak samo za każdym razem, nawet gdy dostawca ponawia to samo zdarzenie lub dostarcza zdarzenia poza kolejnością.

5-etapowy flow, którego trzymaj się zawsze

  1. Zweryfikuj podpis i sparsuj payload. Odrzuć żądania, które nie przejdą walidacji podpisu, mają nieoczekiwany typ zdarzenia lub nie można ich sparsować.

  2. Zapisz rekord zdarzenia zanim dotkniesz danych rozliczeniowych. Zapisz provider event ID, typ, czas utworzenia i surowy payload (lub jego hash). Jeśli ID zdarzenia już istnieje, traktuj je jako duplikat i przerwij.

  3. Zamapuj zdarzenie na pojedynczy rekord „właściciela”. Zdecyduj, co aktualizujesz: fakturę, subskrypcję czy klienta. Przechowuj zewnętrzne ID na swoich rekordach, aby móc je bezpośrednio wyszukać.

  4. Zastosuj bezpieczną zmianę stanu. Przesuwaj stan tylko w przód. Nie cofnij opłaconej faktury dlatego, że przyszło późne „invoice.updated”. Zapisz, co zastosowałeś (stary stan, nowy stan, znacznik czasu, ID zdarzenia) do audytu.

  5. Odpowiedz szybko i zaloguj wynik. Zwróć sukces, gdy zdarzenie jest bezpiecznie zapisane i albo przetworzone, albo zignorowane. Zaloguj, czy zostało przetworzone, zdeduplikowane czy odrzucone i dlaczego.

W AppMaster zwykle staje się to tabelą bazy danych dla zdarzeń webhook oraz Business Process, który sprawdza „widziany ID zdarzenia?” i potem wykonuje minimalne kroki aktualizacji.

Obsługa ponowień, timeoutów i dostaw poza kolejnością

Dodaj pulpit operacyjny webhooków
Stwórz narzędzia wewnętrzne do przeglądania ID zdarzeń, statusów przetwarzania i nieudanych prób.
Zbuduj aplikację

Dostawcy ponawiają webhooki, gdy nie otrzymają szybkiej odpowiedzi sukcesu. Mogą też wysyłać zdarzenia poza kolejnością. Twój handler musi być bezpieczny, gdy ta sama aktualizacja przychodzi dwa razy lub gdy nowsza aktualizacja przychodzi wcześniej.

Jedna praktyczna zasada: odpowiadaj szybko, wykonuj pracę później. Traktuj żądanie webhook jako potwierdzenie odbioru, a nie miejsce na ciężką logikę. Jeśli w żądaniu wywołujesz zewnętrzne API, generujesz PDFy lub przeliczysz rozliczenia synchronnie, zwiększasz ryzyko timeoutów i kolejnych ponowień.

Poza kolejnością: trzymaj najnowszą prawdę

Dostawa poza kolejnością jest normalna. Zanim zastosujesz jakąkolwiek zmianę, użyj dwóch kontroli:

  • Porównaj znaczniki czasu: zastosuj zdarzenie tylko jeśli jest nowsze niż to, które masz zapisane dla danego obiektu (faktura, subskrypcja, uprawnienie).
  • Użyj priorytetu statusów, gdy znaczniki czasu są zbliżone lub niejasne: paid > open, canceled > active, refunded > paid.

Jeśli już zarejestrowałeś fakturę jako opłaconą, a później przychodzi stare „open”, zignoruj je. Jeśli dostałeś „canceled”, a potem pojawi się starszy „active”, zachowaj canceled.

Ignoruj vs. kolejkuj

Ignoruj zdarzenie, gdy możesz udowodnić, że jest przestarzałe lub już zastosowane (to samo ID zdarzenia, starszy znacznik czasu, niższy priorytet statusu). Kolekuj zdarzenie, gdy zależy od danych, których jeszcze nie masz — np. aktualizacja subskrypcji przychodzi zanim istnieje rekord klienta.

Praktyczny wzorzec:

  • Zapisz zdarzenie natychmiast ze stanem przetwarzania (received, processing, done, failed)
  • Jeśli brakuje zależności, oznacz jako waiting i retryuj w tle
  • Ustaw limit ponowień i alarmuj po powtarzających się niepowodzeniach

W AppMaster to dobrze pasuje do tabeli webhook events i Business Process, który potwierdza odbiór szybko i przetwarza kolejkowane zdarzenia asynchronicznie.

Bezpieczne aktualizacje faktur, subskrypcji i uprawnień

Gdy już masz deduplikację, kolejne ryzyko to rozdzielony stan rozliczeń: faktura mówi opłacona, ale subskrypcja jest nadal zaległa, albo uprawnienia przyznano dwukrotnie i nigdy nie cofnięto. Traktuj każdy webhook jako przejście stanu i stosuj je w jednej atomowej aktualizacji.

Faktury: zmiany statusu monotoniczne

Faktury mogą przechodzić przez stany jak paid, voided i refunded. Mogą też występować płatności częściowe. Nie „przełączaj” faktury na podstawie ostatniego przychodzącego zdarzenia. Przechowuj obecny status oraz kluczowe sumy (amount_paid, amount_refunded) i pozwól tylko na bezpieczne przejścia naprzód.

Praktyczne zasady:

  • Oznacz fakturę jako opłaconą tylko raz, przy pierwszym wystąpieniu zdarzenia paid.
  • Przy zwrotach zwiększ amount_refunded aż do sumy faktury; nigdy jej nie zmniejszaj.
  • Jeśli faktura jest voided, zatrzymaj działania realizacyjne, ale zachowaj rekord do audytu.
  • Przy płatnościach częściowych aktualizuj kwoty bez przyznawania korzyści „w pełni opłacone”.

Subskrypcje i uprawnienia: przyznawaj raz, odbieraj raz

Subskrypcje obejmują odnowienia, anulowania i okresy karencji. Trzymaj status subskrypcji oraz granice okresu (current_period_start/end), a następnie wyprowadzaj okna uprawnień z tych danych. Uprawnienia powinny być jawne jako rekordy, a nie pojedyncze booleany.

Dla kontroli dostępu:

  • Jedno przyznanie uprawnienia na użytkownika/produkt/okres
  • Jeden rekord cofnięcia gdy dostęp się kończy (anulowanie, zwrot, chargeback)
  • Ślad audytowy, który zapisuje, który webhook spowodował każdą zmianę

Użyj jednej transakcji, aby uniknąć rozdzielonych stanów

Zastosuj aktualizacje faktury, subskrypcji i uprawnień w jednej transakcji bazodanowej. Odczytaj bieżące wiersze, sprawdź czy to zdarzenie już było zastosowane, potem zapisz wszystkie zmiany razem. Jeśli coś zawiedzie, wycofaj, żeby nie skończyć z „faktura opłacona, brak dostępu” czy odwrotnie.

W AppMaster często mapuje się to na pojedynczy Business Process flow, który aktualizuje PostgreSQL w jednym kontrolowanym kroku i zapisuje wpis audytu razem ze zmianą biznesową.

Kontrole bezpieczeństwa i ochrony danych dla endpointów webhook

Obsłuż ponowne wysyłki poprawnie
Stwórz backend, który poradzi sobie z ponownymi wysyłkami bez podwójnych aktualizacji i rozbieżnych stanów rozliczeń.
Utwórz backend

Bezpieczeństwo webhooków jest częścią poprawności. Jeśli atakujący może trafić w twój endpoint, może próbować tworzyć fałszywe stany "opłacone". Nawet przy deduplikacji musisz udowodnić, że zdarzenie jest prawdziwe i chronić dane klientów.

Zweryfikuj nadawcę zanim dotkniesz danych rozliczeniowych

Weryfikuj podpis dla każdego żądania. Dla Stripe zwykle oznacza to sprawdzenie nagłówka Stripe-Signature, używając surowego ciała żądania (nie przekształconego JSON), i odrzucanie zdarzeń ze starym znacznikiem czasu. Traktuj brak nagłówków jako twardą porażkę.

Weryfikuj podstawy wcześnie: poprawna metoda HTTP, Content-Type i wymagane pola (id zdarzenia, typ i ID obiektu, którego użyjesz do zlokalizowania faktury lub subskrypcji). Jeśli budujesz to w AppMaster, trzymaj sekret podpisu w zmiennych środowiskowych lub bezpiecznej konfiguracji, nigdy w bazie danych ani kodzie klienckim.

Krótka lista bezpieczeństwa:

  • Odrzucaj żądania bez ważnego podpisu i świeżego znacznika czasu
  • Wymagaj oczekiwanych nagłówków i typu treści
  • Używaj dostępu do bazy o najmniejszych uprawnieniach dla handlera webhooków
  • Przechowuj sekrety poza tabelami (env/config), rotuj w miarę potrzeby
  • Zwracaj 2xx dopiero po bezpiecznym zapisaniu zdarzenia

Loguj użytecznie, nie wyciekając sekretów

Loguj tyle, by debugować ponowienia i spory, ale unikaj wrażliwych wartości. Przechowuj bezpieczny podzbiór PII: provider customer ID, wewnętrzne ID użytkownika i ewentualnie maskowany email (np. a***@domain.com). Nigdy nie zapisuj pełnych danych karty, pełnych adresów ani surowych nagłówków autoryzacji.

Loguj, co pomaga odtworzyć wydarzenia:

  • Provider event id, typ, czas utworzenia
  • Wynik weryfikacji (signature ok/failed) bez zapisywania samego podpisu
  • Decyzja deduplikacji (nowe vs już przetworzone)
  • Wewnętrzne ID rekordów dotkniętych (invoice/subscription/entitlement)
  • Powód błędu i liczba ponowień (jeśli kolejkujesz ponowienia)

Dodaj podstawową ochronę przed nadużyciami: limituj liczbę żądań po IP i (gdy to możliwe) po ID klienta, i rozważ dopuszczenie tylko znanych zakresów IP dostawcy, jeśli twoja konfiguracja to wspiera.

Typowe błędy powodujące podwójne opłaty lub podwójny dostęp

Uczyń logikę webhooków powtarzalną
Zamień 5-etapowy proces obsługi webhooków w wizualny Business Process, który można testować i odtwarzać.
Rozpocznij

Większość błędów rozliczeniowych to nie kwestia matematyki. Dzieją się, gdy traktujesz dostawę webhooka jak pojedyncze, niezawodne przesłanie.

Błędy prowadzące do zduplikowanych aktualizacji:

  • Deduplikacja po znaczniku czasu lub kwocie zamiast po ID zdarzenia. Różne zdarzenia mogą mieć tę samą kwotę, a ponowienia mogą przyjść minutami później. Używaj unikalnego ID dostawcy.
  • Aktualizacja bazy przed weryfikacją podpisu. Najpierw weryfikuj, potem parsuj, potem działaj.
  • Traktowanie każdego zdarzenia jako jedynego źródła prawdy bez sprawdzenia bieżącego stanu. Nie oznaczaj faktury jako opłaconej, jeśli jest już opłacona, zwrócona lub voided.
  • Tworzenie wielu uprawnień dla tego samego zakupu. Ponowienia mogą tworzyć zduplikowane wiersze. Preferuj upsert jak „upewnij się, że uprawnienie istnieje dla subscription_id”, potem aktualizuj daty/limity.
  • Zawalenie webhooka, bo usługa powiadomień jest niedostępna. Email, SMS, Slack czy Telegram nie powinny blokować rozliczeń. Kolekuj powiadomienia i i tak zwróć sukces po bezpiecznym zapisaniu zmian rozliczeniowych.

Prosty przykład: przychodzi event odnowienia dwukrotnie. Pierwsza dostawa tworzy wiersz uprawnienia. Ponowne wysłanie tworzy drugi wiersz i aplikacja widzi „dwa aktywne uprawnienia”, przyznając dodatkowe miejsca lub kredyty.

W AppMaster naprawa to głównie kwestia flow: najpierw weryfikuj, wstaw rekord zdarzenia z unikalnym ograniczeniem, zastosuj aktualizacje rozliczeń ze sprawdzeniami stanu i przenieś efekty uboczne (maile, paragony) do kroków asynchronicznych, aby nie wywoływały lawiny ponowień.

Realistyczny przykład: zduplikowane odnowienie + późniejszy zwrot

Ten scenariusz wygląda groźnie, ale jest do opanowania, jeśli handler jest bezpieczny do ponownego uruchomienia.

Klient ma miesięczny plan. Stripe wysyła event odnowienia (np. invoice.paid). Twój serwer go odbiera, aktualizuje bazę, ale trwa za długo z odpowiedzią 200 (cold start, zajęta baza). Stripe zakłada, że się nie powiodło i ponawia to samo zdarzenie.

Przy pierwszej dostawie przyznajesz dostęp. Przy ponownym dostarczeniu wykrywasz to samo zdarzenie i nic nie robisz. Później przychodzi zdarzenie zwrotu (np. charge.refunded) i raz odbierasz dostęp.

Prosty sposób modelowania stanu w DB (tabele do zbudowania w AppMaster Data Designer):

  • webhook_events(event_id UNIQUE, type, processed_at, status)
  • invoices(invoice_id UNIQUE, subscription_id, status, paid_at, refunded_at)
  • entitlements(customer_id, product, active, valid_until, source_invoice_id)

Jak powinna wyglądać baza po kolejnych zdarzeniach

Po Zdarzeniu A (odnowienie, pierwsza dostawa): webhook_events ma nowy wiersz dla event_id=evt_123 z status=processed. invoices jest oznaczona jako opłacona. entitlements.active=true i valid_until przesuwa się o jeden okres rozliczeniowy.

Po Zdarzeniu A ponownie (odnowienie, retry): wstawienie do webhook_events się nie powiedzie (unikalne event_id) lub handler zauważy, że już było przetworzone. Brak zmian w invoices lub entitlements.

Po Zdarzeniu B (zwrot): nowy wiersz w webhook_events dla event_id=evt_456. invoices.refunded_at jest ustawione i status=refunded. entitlements.active=false (lub valid_until ustawione na teraz) używając source_invoice_id do cofnięcia dostępu raz.

Ważny szczegół to timing: check deduplikacji dzieje się przed jakimkolwiek zapisem przyznania lub cofnięcia uprawnień.

Szybka lista kontrolna przed uruchomieniem

Szybsze prototypowanie rozliczeń Stripe
Podłącz Stripe i testuj powtórne dostawy bez pisania szablonowego kodu od zera.
Wypróbuj

Zanim włączysz live webhooki, chcesz mieć dowód, że jedno zdarzenie w rzeczywistym świecie aktualizuje rekordy rozliczeń dokładnie raz, nawet jeśli dostawca wyśle je dwa (lub dziesięć) razy.

Użyj tej listy, by zweryfikować setup end-to-end:

  • Potwierdź, że każde przychodzące zdarzenie jest najpierw zapisywane (raw payload, event id, typ, czas utworzenia i wynik weryfikacji podpisu), nawet jeśli późniejsze kroki zawodzą.
  • Zweryfikuj, że duplikaty są wykrywane wcześnie (to samo provider event id) i handler wychodzi bez zmiany faktur, subskrypcji lub uprawnień.
  • Udowodnij, że aktualizacja biznesowa jest jednorazowa: jedna zmiana statusu faktury, jedna zmiana stanu subskrypcji, jedno przyznanie lub cofnięcie uprawnień.
  • Upewnij się, że błędy są zapisywane z wystarczającym szczegółem do bezpiecznego odtworzenia (komunikat o błędzie, krok, który zawiódł, status ponowienia).
  • Przetestuj, że handler zwraca odpowiedź szybko: potwierdź odbiór po zapisaniu i unikaj ciężkiej pracy w czasie obsługi żądania.

Nie potrzebujesz dużego setupu observability na start, ale potrzebujesz sygnałów. Śledź to z logów lub prostych dashboardów:

  • Skok powtórzeń dostaw (często normalny, ale duże skoki mogą sygnalizować timeouty lub problemy dostawcy)
  • Wysoki współczynnik błędów wg typu zdarzenia (np. invoice payment failed)
  • Rosnące zaległości zdarzeń w kolejce retry
  • Kontrole niezgodności (opłacona faktura, brak uprawnień; cofnięta subskrypcja, aktywny dostęp)
  • Nagły wzrost czasu przetwarzania

Jeśli budujesz to w AppMaster, trzymaj przechowywanie zdarzeń w dedykowanej tabeli w Data Designer i uczynienie „oznacz jako przetworzone” jednym, atomowym punktem decyzyjnym w Business Process.

Kolejne kroki: testuj, monitoruj i buduj w no-code backendzie

Testowanie to miejsce, gdzie idempotencja się sprawdza. Nie uruchamiaj tylko ścieżki szczęśliwej. Odtwarzaj to samo zdarzenie wielokrotnie, wysyłaj zdarzenia poza kolejnością i wymuszaj timeouty, aby dostawca ponawiał. Druga, trzecia i dziesiąta dostawa nie powinny nic zmieniać.

Planuj backfilling wcześnie. Prędzej czy później będziesz chciał ponownie przetworzyć przeszłe zdarzenia po poprawce błędu, zmianie schematu lub incydencie dostawcy. Jeśli handler jest naprawdę idempotentny, backfill staje się „odtworzeniem zdarzeń przez ten sam pipeline” bez tworzenia duplikatów.

Support potrzebuje też małego runbooka, żeby problemy nie zamieniały się w domysły:

  • Znajdź ID zdarzenia i sprawdź, czy jest zarejestrowane jako przetworzone.
  • Sprawdź rekord faktury lub subskrypcji i potwierdź oczekiwany stan i znaczniki czasu.
  • Przejrzyj rekord uprawnień (jaki dostęp przyznano, kiedy i dlaczego).
  • W razie potrzeby uruchom przetwarzanie dla pojedynczego ID zdarzenia w bezpiecznym trybie reprocess.
  • Jeśli dane są niespójne, zastosuj jedną korektę i ją nagraj.

Jeśli chcesz to wdrożyć bez pisania dużo boilerplate, AppMaster pozwala zamodelować główne tabele i zbudować flow webhooków w wizualnym Business Process, generując jednocześnie realny kod źródłowy dla backendu.

Wypróbuj zbudować handler webhooków end-to-end w no-code generowanym backendzie i upewnij się, że jest bezpieczny przy ponowieniach zanim zwiększysz ruch i przychody.

FAQ

Dlaczego mój dostawca płatności wysyła ten sam webhook więcej niż raz?

Powtarzalne dostawy webhooków są normalne, bo dostawcy optymalizują mechanizm na zasadzie przynajmniej raz. Jeśli twój endpoint się nie odezwie, zwróci 5xx lub połączenie zostanie zerwane, dostawca będzie ponawiać wysyłkę tego samego zdarzenia, aż otrzyma potwierdzenie sukcesu.

Jaki jest najlepszy sposób na deduplikację zdarzeń webhook?

Użyj unikalnego ID zdarzenia dostawcy (identyfikatora zdarzenia webhook), a nie kwoty, znacznika czasu czy emaila klienta. Zapisz to ID z kontraintem unikalności, aby ponowne wysyłki były wykrywane natychmiast i bezpiecznie ignorowane.

Czy powinienem zapisać zdarzenie przed aktualizacją rekordów rozliczeń?

Zapisz rekord zdarzenia najpierw, zanim zaktualizujesz faktury, subskrypcje lub uprawnienia. Jeśli wstawienie rekordu zakończy się niepowodzeniem, bo ID zdarzenia już istnieje, przerwij przetwarzanie i zwróć sukces, by ponowne wysyłki nie tworzyły podwójnych aktualizacji.

Jak długo powinienem trzymać rekordy deduplikacji webhooków?

Przechowuj je wystarczająco długo, by pokryć opóźnione ponowienia i wsparcie dochodzeń. Praktycznym domyślnym oknem jest 30–90 dni, a dłużej (np. 6–12 miesięcy) gdy masz spory, chargebacki lub długie cykle subskrypcji; potem usuwaj stare wiersze, by utrzymać wydajność zapytań.

Czy naprawdę potrzebuję weryfikacji podpisu jeśli już dedupuję zdarzenia?

Weryfikuj podpis przed dotykaniem danych rozliczeniowych, potem parsuj i waliduj wymagane pola. Jeśli weryfikacja podpisu się nie powiedzie, odrzuć żądanie i nie zapisuj zmian rozliczeń — deduplikacja nie ochroni przed sfałszowanymi zdarzeniami 'opłacono'.

Jak obsługiwać timeouty webhooków bez tworzenia duplikatów?

Najpierw potwierdzaj odbiór szybko po bezpiecznym zapisaniu zdarzenia, a cięższe zadania przenoś do przetwarzania w tle. Wolne handlery zwiększają liczbę timeoutów, co generuje więcej ponowień i zwiększa ryzyko duplikatów, jeśli coś nie jest w pełni idempotentne.

Co zrobić, gdy zdarzenia przychodzą poza kolejnością?

Stosuj zasadę: zmieniaj stan tylko w przód i ignoruj przestarzałe zdarzenia. Używaj znaczników czasu, gdy są dostępne, oraz prostego priorytetu statusów (np. refunded nie powinno być nadpisane przez paid, a canceled nie przez active).

Jak uniknąć przyznawania dostępu dwa razy, gdy webhook odnowienia jest powtarzany?

Nie twórz nowego wiersza uprawnień przy każdym zdarzeniu. Stosuj regułę upsert typu „zagwarantuj jedno uprawnienie na użytkownika/produkt/okres (lub na subskrypcję)”, potem aktualizuj daty/limity i zapisuj, które ID zdarzenia spowodowało zmianę do audytu.

Dlaczego aktualizacje faktury i uprawnień powinny być w jednej transakcji?

Zapisz zmiany faktury, subskrypcji i uprawnień w jednej transakcji bazodanowej, żeby wszystkie zapisy powiodły się albo zostały wycofane razem. To zapobiega rozdzielonym stanom jak „faktura opłacona” bez przyznanego dostępu lub odwrotnie.

Czy mogę to zaimplementować bezpiecznie w AppMaster bez pisania kodu backendu?

Tak. To dobre dopasowanie: utwórz model WebhookEvents z unikalnym ID zdarzenia, a następnie zbuduj Business Process, który sprawdza „już widziane?” i wychodzi wcześniej. Zamodeluj faktury/subskrypcje/uprawnienia w Data Designer tak, by ponowne wysyłki i replaye nie tworzyły duplikatów.

Łatwy do uruchomienia
Stworzyć coś niesamowitego

Eksperymentuj z AppMaster z darmowym planem.
Kiedy będziesz gotowy, możesz wybrać odpowiednią subskrypcję.

Rozpocznij