Najgroźniejszy błąd integracji nie zawsze wygląda jak awaria. System może zgłosić timeout, ponowić żądanie i utworzyć u dostawcy drugie zamówienie, mimo że pierwsze powstało poprawnie. Rozwiązaniem jest idempotency: ta sama operacja powtórzona drugi raz nie może tworzyć kolejnego skutku biznesowego.
Jak powstaje podwójna wysyłka
Sklep wysyła zamówienie do integratora. Integrator przekazuje je hurtowni. Hurtownia zapisuje zamówienie, ale odpowiedź HTTP wraca z opóźnieniem. Po 30 sekundach integrator uznaje, że operacja nie powiodła się i robi retry. Jeśli dostawca nie rozpoznaje, że to ten sam request, powstaje drugi order ID.
Na pierwszy rzut oka wszystko działa. Klient dostał potwierdzenie, tracking pojawia się normalnie. Problem wychodzi dzień później, kiedy przewoźnik skanuje dwie paczki albo hurtownia pobiera podwójną kwotę.
Idempotency key powinien reprezentować operację biznesową
Każde utworzenie zamówienia po stronie dostawcy powinno mieć stabilny klucz, np. identyfikator sklepu + numer zamówienia + dostawca. Jeżeli ten sam klucz pojawi się ponownie, API powinno zwrócić istniejący wynik zamiast tworzyć nowe zamówienie.
Nie używaj losowego UUID generowanego przy każdym retry, bo wtedy każde ponowienie wygląda jak nowa operacja. Klucz musi być taki sam dla wszystkich prób wykonania tego samego biznesowego zlecenia.
Oddziel „wysłaliśmy request” od „dostawca utworzył zamówienie”
Status integracji powinien przechowywać więcej niż zielone „sent”. Minimum to: request przygotowany, wysłany, odpowiedź nieznana, potwierdzony supplier order ID, odrzucony. Stan „odpowiedź nieznana” jest krytyczny, bo oznacza, że nie wolno ślepo tworzyć nowego zamówienia.
W tym stanie system powinien najpierw zapytać dostawcę po zewnętrznym reference ID, czy zamówienie już istnieje. Dopiero brak rekordu może uzasadniać retry tworzące zamówienie.
Reconciliation wykrywa błędy, których webhook nie pokaże
Raz lub kilka razy dziennie porównuj zamówienia sklepu z zamówieniami dostawców. Jeden sklepowy order powinien mieć oczekiwaną liczbę supplier order IDs. Dwa rekordy dla tej samej pozycji i dostawcy powinny wywołać alert.
Taka kontrola powinna korzystać z poprawnego mapowania wariantów. Jeżeli integracja ma już problemy opisane przy błędnych SKU i wariantach, automatyczne porównanie może mylnie uznać dwa różne warianty za ten sam produkt albo odwrotnie.
Co zrobić, gdy duplikat już powstał
- Zatrzymaj fulfillment drugiego zamówienia, jeśli dostawca jeszcze go nie nadał.
- Zapisz oba supplier order IDs i ich statusy.
- Jeśli obie paczki wyszły, poinformuj klienta zanim sam zgłosi problem.
- Zorganizuj przechwycenie lub zwrot dodatkowej paczki.
- Rozlicz dostawcę lub integratora zgodnie z przyczyną błędu.
- Dodaj test regresyjny, który symuluje timeout po utworzeniu zamówienia.
Nie próbuj naprawić problemu wyłącznie przez „zwiększenie timeoutu”. Wolniejsza odpowiedź może wystąpić ponownie. Idempotency i reconciliation rozwiązują klasę błędów, a nie jeden przypadek.
Jakie alerty naprawdę pomagają
- Dwa supplier order IDs dla jednego sklepowego order + supplier.
- Dwa numery trackingowe z tego samego magazynu dla tej samej pozycji bez split shipment.
- Ponad jeden charge dostawcy dla tej samej referencji.
- Retry create-order po statusie „unknown”.
- Brak supplier order ID po określonym SLA.
- Różnica ilości między sklepem a dostawcą.
Przy niepewnych stanach magazynowych takie zdublowane zamówienie może dodatkowo zużyć rezerwę i spowodować overselling. Dlatego warto połączyć kontrolę retry z zasadami z artykułu o buforze stanów magazynowych.
Najczęstsze pytania
Czy webhook sam w sobie gwarantuje jedno wykonanie?
Nie. Webhooki i kolejki mogą dostarczyć to samo zdarzenie więcej niż raz. Odbiorca powinien potrafić bezpiecznie rozpoznać duplikat.
Czy numer zamówienia sklepu wystarczy jako idempotency key?
Często trzeba dodać dostawcę lub typ operacji, aby ten sam numer mógł bez kolizji obsłużyć np. osobne fulfillmenty kilku hurtowni.
Co jest ważniejsze: retry czy idempotency?
Oba mechanizmy. Retry zwiększa niezawodność, a idempotency sprawia, że ponowienie nie tworzy podwójnych skutków.

