1. Strona główna
  2. Aktualności
  3. Integracje API
Integracje API

Integracje API Laravel z ERP, e-commerce i systemem B2B

Integracje API w Laravel z ERP i B2B w praktyce: kolejki i joby, retry z backoffem, idempotencja, dziennik integracji, monitoring oraz testy kontraktowe.

Integracje API Laravel z ERP, e-commerce i systemem B2B

Stabilna integracja API w Laravel z ERP, e-commerce i systemem B2B opiera się na kilku elementach: każda operacja wymiany danych jest osobnym jobem w kolejce, ma ograniczoną liczbę prób z rosnącym odstępem (backoff), jest idempotentna, czyli jej powtórzenie nie tworzy duplikatu, zostawia ślad w logach i dzienniku operacji, a całość jest monitorowana i pokryta testami kontraktowymi. Taki zestaw sprawia, że chwilowa awaria ERP albo limit zapytań u partnera nie kończy się zgubionym zamówieniem. W tym artykule pokazujemy, jak to zbudować w praktyce w aktualnych wersjach frameworka (Laravel 12 i 13, PHP 8.3/8.4).

Architektura: nic nie dzieje się w żądaniu użytkownika

Pierwsza zasada: kontroler przyjmujący zamówienie z portalu nie woła API ERP. Zapisuje zamówienie w bazie i wysyła job do kolejki. Przykładowy przepływ:

  1. klient składa zamówienie – rekord zapisuje się w transakcji,
  2. po zatwierdzeniu transakcji do kolejki trafia job `PushOrderToErp` (dispatch z `afterCommit`, żeby worker nie wystartował przed zapisem danych),
  3. worker wysyła zamówienie do ERP przez klienta HTTP,
  4. odpowiedź (numer dokumentu w ERP) zapisuje się przy zamówieniu, a status zmienia na „przekazane”,
  5. przy błędzie job wraca do kolejki z opóźnieniem albo – po wyczerpaniu prób – trafia do tabeli nieudanych jobów i generuje alert.

Synchronizacje w drugą stronę (stany, ceny, statusy) uruchamia scheduler jako komendy cykliczne. Każdą warto oznaczyć `withoutOverlapping()`, żeby długi import nie nakładał się na kolejny, a na kilku serwerach – `onOneServer()`.

Kolejki i joby

Do integracji najlepiej sprawdza się kolejka na Redisie z Horizonem, który daje podgląd obciążenia, czasów wykonania i nieudanych jobów. Kilka praktyk:

  • osobne kolejki dla różnych priorytetów – zamówienia nie mogą czekać za nocnym importem dziesiątek tysięcy cen,
  • małe joby – zamiast jednego joba „zsynchronizuj cały katalog” lepiej wiele jobów po paczce rekordów, spiętych w `Bus::batch()` z obsługą zakończenia i błędu,
  • timeout joba krótszy niż `retry_after` kolejki – inaczej ten sam job może zostać uruchomiony równolegle drugi raz,
  • przekazywanie identyfikatorów, nie całych obiektów – job pobiera aktualny stan z bazy w momencie wykonania.

Retry i backoff

Laravel pozwala określić w jobie liczbę prób (`$tries`), odstępy między nimi (`$backoff`, także jako tablicę rosnących wartości) albo termin, po którym job przestaje być ponawiany (`retryUntil()`). Ważne jest rozróżnienie typów błędów:

  • błędy przejściowe (timeout, 502/503, 429 – przekroczony limit) – ponawiamy z rosnącym odstępem,
  • błędy danych (422, brak kontrahenta, nieprawidłowy indeks) – nie ponawiamy, tylko oznaczamy rekord jako wymagający poprawy i od razu kończymy job metodą `fail()`,
  • błędy autoryzacji (401/403) – zatrzymujemy całą kolejkę danej integracji i alarmujemy, bo kolejne próby i tak się nie udadzą.

Przydatne są middleware jobów: `RateLimited` pilnuje limitu zapytań do API partnera, `ThrottlesExceptions` wstrzymuje próby, gdy zewnętrzny system seryjnie zwraca błędy, a `WithoutOverlapping` z kluczem, np. identyfikatorem zamówienia, zapobiega równoległemu przetwarzaniu tego samego rekordu. Sam klient HTTP ma też metodę `retry()` do krótkich ponowień w obrębie jednego wykonania.

Idempotencja

Ponowienia są bezpieczne tylko wtedy, gdy powtórzenie operacji nie zmienia wyniku. W praktyce:

  • klucz idempotencji – każde zamówienie ma stały identyfikator z portalu, przekazywany do ERP (np. jako numer obcy). Przed utworzeniem dokumentu job sprawdza, czy dokument z tym numerem już istnieje,
  • zapis stanu przed i po – job najpierw oznacza operację jako „w trakcie”, a po sukcesie zapisuje numer z ERP. Gdy worker padnie w połowie, kolejna próba wie, że trzeba najpierw sprawdzić stan po drugiej stronie,
  • webhooki przychodzące – każde zdarzenie od partnera zapisujemy z jego identyfikatorem w tabeli z unikalnym indeksem; duplikat jest ignorowany,
  • `ShouldBeUnique` – dla jobów synchronizacji jednego zasobu, żeby w kolejce nie stało kilka identycznych zadań.

Logi i dziennik integracji

Logi aplikacji (kanały Monolog) to za mało, bo służą programistom. Potrzebny jest też dziennik integracji w bazie, widoczny w panelu dla osób z obsługi:

  • typ operacji, kierunek, identyfikator rekordu,
  • status: oczekuje, w trakcie, sukces, błąd danych, błąd techniczny,
  • liczba prób, czas ostatniej próby, treść błędu w zrozumiałej formie,
  • skrócony zapis żądania i odpowiedzi (bez danych wrażliwych i tokenów),
  • przycisk „ponów” i „oznacz jako rozwiązane”.

Warto dodać identyfikator korelacji przekazywany przez wszystkie kroki – od żądania w portalu, przez job, po log odpowiedzi ERP – żeby jedno zamówienie dało się prześledzić w kilka sekund.

Monitoring i alerty

  • zdarzenie `JobFailed` i metoda `failed()` w jobie – powiadomienie na Slacka lub e-mail z linkiem do rekordu,
  • alert na brak aktywności – jeśli od określonego czasu nie przyszła żadna synchronizacja stanów, coś jest nie tak, nawet jeśli nie ma błędów,
  • metryki kolejek – długość kolejki i czas oczekiwania w Horizonie, z progiem alarmowym,
  • raport dzienny – ile operacji, ile błędów danych do poprawy, ile ponowień,
  • Laravel Pulse albo zewnętrzny APM do obserwacji wolnych zapytań i endpointów.

Testy kontraktowe

Integracja psuje się najczęściej wtedy, gdy druga strona zmienia format danych. Chronią przed tym:

  1. testy z `Http::fake()` – symulują odpowiedzi ERP, w tym błędy 429, 500 i timeouty, i sprawdzają, że job zachowa się poprawnie,
  2. zapisane przykładowe odpowiedzi (fixtures) z prawdziwego API, na których testujemy mapowanie,
  3. walidacja kontraktu – struktura odpowiedzi sprawdzana względem schematu (np. OpenAPI lub JSON Schema), jeśli partner go udostępnia,
  4. test dymny na środowisku testowym partnera uruchamiany cyklicznie – wykrywa zmianę API, zanim zrobi to produkcja,
  5. `Http::preventStrayRequests()` w testach – żaden test nie wyśle przypadkiem prawdziwego żądania.

Struktura kodu

Dobrze sprawdza się podział na warstwy: klient API (tylko komunikacja), mapper (tłumaczenie formatów), serwis (logika biznesowa, idempotencja) i job (orkiestracja, ponowienia). Dzięki temu wymiana ERP albo zmiana wersji API dotyka jednej warstwy, a nie całego systemu. Konfiguracja – adresy, klucze, limity – trafia do plików konfiguracyjnych i zmiennych środowiskowych, a nie do kodu.

Bezpieczeństwo połączeń

Klucze i tokeny do API partnerów przechowuj poza repozytorium, a tokeny OAuth odświeżaj w osobnym, zabezpieczonym blokadą mechanizmie, żeby kilka workerów nie próbowało robić tego jednocześnie. Webhooki przychodzące weryfikuj podpisem lub sekretem, a endpointy dla partnerów zabezpiecz osobnymi tokenami o ograniczonych uprawnieniach (np. przez Sanctum). W logach maskuj dane osobowe i dane uwierzytelniające.

Typowe błędy

  • wywołanie API ERP bezpośrednio w kontrolerze,
  • nieskończone ponawianie błędów danych,
  • brak klucza idempotencji i duplikaty zamówień po timeoutach,
  • jeden gigantyczny job importu, którego nie da się wznowić,
  • logi bez identyfikatora rekordu.

Pułapki biznesowe, które warto sprawdzić przed kodowaniem, zebraliśmy w artykule o najczęstszych pułapkach integracji ERP z platformą B2B, a wzorce dla danych produktowych – w tekście o Laravel API dla e-commerce B2B i PIM.

Następny krok

Jeśli masz już integrację, sprawdź trzy rzeczy: czy zamówienia idą przez kolejkę, czy ponowienie może stworzyć duplikat i czy osoba z obsługi widzi błąd bez pytania programisty. Jeśli choć jedna odpowiedź brzmi „nie”, warto to poprawić przed kolejnym sezonem. Zobacz, jak budujemy Integracje API Laravel, i napisz do nas, jeśli chcesz przegląd istniejącego rozwiązania.

FAQ

Najczęstsze pytania

Dlaczego nie wysyłać zamówienia do ERP bezpośrednio w kontrolerze?

Bo każda przerwa lub spowolnienie ERP zablokuje klienta albo zgubi zamówienie. Zapis w bazie i job w kolejce oddzielają działanie portalu od dostępności ERP i pozwalają bezpiecznie ponawiać operację.

Które błędy integracji warto ponawiać automatycznie?

Błędy przejściowe, takie jak timeouty, odpowiedzi 5xx i 429. Błędów danych, np. 422 czy brakującego kontrahenta, nie należy ponawiać, tylko oznaczyć rekord do poprawy.

Jak zapobiec duplikatom zamówień przy ponowieniach?

Stosuj stały klucz idempotencji, np. numer zamówienia z portalu przekazywany do ERP, i przed utworzeniem dokumentu sprawdzaj, czy już istnieje. Dla webhooków zapisuj identyfikator zdarzenia z unikalnym indeksem.

Po co testy kontraktowe w integracji z ERP?

Wykrywają zmiany formatu danych po stronie partnera, zanim zepsują produkcję. Łączy się w nich symulowane odpowiedzi, zapisane przykłady z prawdziwego API i cykliczny test na środowisku testowym partnera.

Jak przełożyć ten temat na projekt

W JiraSoft patrzymy na takie zagadnienia przez pryzmat realnego systemu: danych, backendu, integracji API, procesów B2B, widoczności w Google oraz przygotowania treści pod odpowiedzi AI. Dlatego artykuł jest punktem wyjścia do rozmowy o konkretnym workflow, a nie tylko ogólną notatką technologiczną.

Zamień ten temat w konkretny projekt

Wyślij obecną sytuację, stack i cel biznesowy. Zaproponujemy pierwszy krok wdrożeniowy.

Umów bezpłatną rozmowę +48 887 883 084

#kodKtóryDowozi

Bez szumu. Konkretne wdrożenia. Software, który działa na produkcji.

Porozmawiajmy o projekcie