Duplikaty w integracjach: dlaczego to samo zamówienie ląduje w ERP dwa razy

· 7 min czytania · Zespół SilverData

Jeden z najbardziej upierdliwych efektów ubocznych integracji między systemami to duplikaty. Ta sama faktura zaksięgowana dwa razy, to samo zamówienie wysyłane dwa razy, ten sam klient w CRM w trzech kartotekach. Wygląda banalnie — dopóki nie zaczniesz liczyć godzin marnowanych na sprzątanie i pieniędzy na dodatkowe kuriery.

Duplikaty nie biorą się z tego, że „system się głupio pomylił". Biorą się z bardzo konkretnego mechanizmu, o którym nikt nie mówi na demo. I na szczęście da się je wyeliminować bez wymiany całej integracji — pod warunkiem, że rozumiesz, skąd tak naprawdę wychodzą.

Dlaczego integracje robią duplikaty

Klasyczna integracja między dwoma systemami — powiedzmy sklepem internetowym i ERP — działa mniej więcej tak: sklep wysyła do ERP komunikat „mam nowe zamówienie nr 12345". ERP potwierdza „przyjąłem". Jedno zamówienie, jedno potwierdzenie, koniec tematu.

Problem zaczyna się, kiedy potwierdzenie nie dotrze. Sieć chrupnęła na sekundę, ERP przez chwilę nie odpowiadał, timeout, cokolwiek. Sklep nie wie, czy zamówienie zostało przyjęte, czy nie. Ma dwa wyjścia: albo uznać, że nie zostało (i wysłać jeszcze raz), albo uznać, że zostało (i zostawić w spokoju). Prawie zawsze wybiera to pierwsze — bo lepiej wysłać dwa razy niż zgubić zamówienie klienta.

I tu robi się duplikat. ERP tak naprawdę przyjął pierwszą próbę — tylko odpowiedź nie dotarła. Druga próba trafia do niego jak zupełnie nowe zamówienie. Nic go nie powstrzymuje przed zapisaniem obu.

Ten sam mechanizm potrafi zadziałać na dowolnym styku systemów: bank → ERP, ERP → WMS, kurier → sklep, POS → księga. Wszędzie tam, gdzie „ktoś wysyła, ktoś odbiera, a między nimi jest sieć", która czasami się dławi.

Klucz idempotencyjny — koncept w trzech zdaniach

Rozwiązanie ma techniczną nazwę — idempotencja — i brzmi trudniej niż jest w praktyce. Chodzi o to, żeby wysłać tę samą operację dziesięć razy i mieć pewność, że efekt będzie taki, jakbyś wysłał ją raz. Jak włącznik światła: pierwsze naciśnięcie zapala, kolejne dziewięć nic nie zmieniają.

W praktyce robi się to tak: nadawca (sklep, kurier, bank) dokleja do każdej operacji unikalny numer — nazywamy go kluczem idempotencyjnym. Odbiorca (ERP, WMS) zapamiętuje, że taki klucz już widział. Jeśli przyjdzie drugi raz — po prostu odpowiada „mam, dzięki" i nic nie duplikuje. Ten sam mechanizm stosuje np. Stripe czy PayU do transakcji płatniczych.

To jedna z tych rzeczy, które trzeba zaprojektować przy budowie integracji — dopisanie tego po fakcie kosztuje więcej. Ale wykonalne jest zawsze.

Przykład: hurtownia części motoryzacyjnych

U jednego z naszych klientów — 22-osobowej hurtowni części motoryzacyjnych z Wielkopolski — sytuacja wyglądała tak. Comarch Optima jako ERP, BaseLinker jako most do Allegro i sklepu Shoper, prosty WMS na magazynie. Zamówienia z Allegro szły do Optimy przez BaseLinker, a z Optimy schodziły na magazyn do wysyłki.

Średnio 14 duplikatów zamówień miesięcznie. Nie tragedia w skali obrotu, ale konkretny problem operacyjny. Księgowa spędzała ok. 6 godzin miesięcznie na wyszukiwaniu i stornowaniu duplikatów. Magazynier co jakiś czas wysyłał tę samą paczkę dwa razy — koszt kuriera plus czas na odzyskanie towaru od klienta plus rozmowa telefoniczna „bardzo przepraszamy". Klienci dwa razy widzieli obciążenie karty i chwytali za telefon. W skali roku uzbierało się kilkanaście godzin pracy zarządu poświęconych na przeprosiny.

Diagnoza zajęła nam pół dnia z logów. BaseLinker wysyłał zamówienia do Optimy przez pośrednika (własne middleware, które ktoś napisał 4 lata wcześniej i odszedł z firmy). Middleware przy timeoutach powtarzało próbę — bez żadnego znacznika, że to ta sama operacja. Optima z chęcią przyjmowała drugą kopię.

Poprawka była nudna: do middleware dodaliśmy klucz idempotencyjny oparty o id_zamowienia_BaseLinker + data_utworzenia. Optima dostała prosty widok bazodanowy, który sprawdzał, czy taki klucz już przeszedł. Do tego — jako bezpiecznik na wcześniejsze grzechy — nocny job szukający identycznych zamówień w oknie 24 godzin i wysyłający alert.

Przez kolejne 3 miesiące — 0 duplikatów. Nudne, ale skuteczne.

Co możesz zrobić w tym tygodniu

Nawet jeśli nie masz jeszcze budżetu na zmianę integracji, można ograniczyć szkody prostymi krokami:

Kiedy zawołać kogoś od integracji

Jeśli po tych krokach nadal wpadają duplikaty — albo integracja robi cały ciąg pochodnych szkód (podwójne rezerwacje magazynowe, podwójne wysyłki, podwójne noty korygujące) — to znak, że warto dołożyć klucz idempotencyjny na dobre. To nie jest rewolucja: dla większości integracji między popularnymi systemami (Comarch Optima, enova365, Subiekt GT, Microsoft Dynamics AX, BaseLinker, Shoper, WooCommerce) da się to zrobić w kilka dni roboczych, bez dotykania samych systemów źródłowych.

Duplikaty są nudne. Ale koszt ich obsługi rośnie wraz z obrotem — i w pewnym momencie kosztują więcej niż zbudowanie integracji od nowa.

Idempotencja to jedna z tych rzeczy, o których nie mówi się na demo, a które decydują, czy Twoja integracja rok później będzie zbawieniem, czy stałym źródłem korekt.

← Wróć na blog