Automatyzacja wysyłki zaczyna się psuć zwykle nie przy setnej paczce, ale przy pierwszym wyjątku. Klient wybiera automat, który zniknął z listy punktów. Towar nie mieści się do skrytki. Przewoźnik odrzuca numer telefonu. Etykieta powstaje, ale podjazd kuriera już nie. Albo sklep zapisuje status „wysłane”, mimo że paczka została dopiero zarejestrowana w systemie przewoźnika.
Dlatego usługa integrująca sklep z kurierami i automatami paczkowymi nie powinna być traktowana jako prosty generator etykiet. Jeżeli ma być produktem dla sprzedawców, powinna przejąć cały techniczny odcinek między zamówieniem a doręczeniem: wybór punktu odbioru, walidację przesyłki, utworzenie listu przewozowego, zamówienie odbioru, przekazywanie statusów, obsługę zwrotów i reagowanie na błędy API.
Polski rynek dobrze pokazuje skalę problemu. InPost, DPD, DHL, ORLEN Paczka czy usługi dostępne przez Allegro różnią się sposobem autoryzacji, słownikami usług, identyfikatorami punktów, formatami etykiet i ograniczeniami przesyłek. Co więcej, interfejsy nie są stałe. Przykładowo Allegro w maju 2026 r. uruchomiło nowy zasób do pobierania proponowanych parametrów nadania dla konkretnego zamówienia, a wcześniejszy endpoint listujący usługi dostawy ma zostać usunięty w I kwartale 2027 r. Integracja logistyczna jest więc produktem wymagającym ciągłego utrzymania, a nie projektem, który kończy się po pierwszym wdrożeniu. (developer.allegro.pl)
Najpierw warstwa pośrednia, dopiero później kolejne integracje kurierskie
Największym błędem na początku projektu jest bezpośrednie połączenie logiki sklepu z API pierwszego przewoźnika.
Technicznie działa. Biznesowo szybko staje się problemem.
Jeżeli kod sklepu operuje pojęciami charakterystycznymi dla InPost, dodanie DPD albo DHL oznacza później przepisywanie checkoutu, panelu sprzedawcy i procesu generowania przesyłek. Lepszą konstrukcją jest własny model logistyczny, niezależny od konkretnych przewoźników.
W praktyce system powinien mieć wewnętrzne obiekty takie jak:
- carrier – przewoźnik,
- delivery_service – np. kurier, automat, punkt odbioru, pobranie,
- pickup_point – punkt lub automat z własnym identyfikatorem przewoźnika,
- shipment – przesyłka,
- parcel – pojedyncza paczka wraz z wagą i wymiarami,
- label – dokument PDF, ZPL albo inny format,
- pickup – odbiór przez kuriera,
- tracking_event – zdarzenie śledzenia,
- return – przesyłka zwrotna,
- carrier_account – dane umowy sprzedawcy z przewoźnikiem.
Dopiero pod tym modelem powinny znajdować się adaptery, przykładowo `InPostAdapter`, `DPDAdapter`, `DHLAdapter` i `OrlenAdapter`.
To rozdzielenie ma duże znaczenie. DPD udostępnia dziś m.in. REST API do tworzenia przesyłek i dokumentów przewozowych, zamawiania podjazdów oraz obsługi zwrotów, ale część innych usług nadal funkcjonuje poprzez SOAP. DHL24 WebAPI również wykorzystuje SOAP/WSDL i oferuje m.in. tworzenie przesyłek, generowanie etykiet, zamawianie kuriera oraz śledzenie. Z kolei obecne globalne API InPost jest REST-owe, korzysta z OAuth 2.1 i JSON. Budowanie wspólnej logiki bezpośrednio na tych interfejsach szybko prowadzi do kodu pełnego wyjątków zależnych od przewoźnika. (dhl24.com.pl)
Normalizacja nie może jednak usuwać funkcji specyficznych dla przewoźnika. To drugi częsty błąd. Wspólny model powinien obsługiwać 80–90% typowych operacji, a obok niego musi istnieć mechanizm rozszerzeń, np. `carrierOptions`. Inaczej po kilku miesiącach okaże się, że system nie potrafi wykorzystać usługi dostępnej tylko w jednej sieci.
Dobrym przykładem są formaty dokumentów. DHL24 pozwala generować m.in. PDF przeznaczony do zwykłego druku oraz formaty dla drukarek Zebra, w tym ZPL w wariantach przeznaczonych dla drukarek termicznych. Jeśli własne API ograniczy pole `labelFormat` wyłącznie do `PDF`, późniejsze dodanie wydruku termicznego będzie wymagało zmiany kontraktu z klientami. (dhl24.com.pl)
Podobnie trzeba potraktować punkty odbioru. Nie należy przechowywać ich jako zwykłego tekstu w rodzaju „Paczkomat przy ul. Marszałkowskiej”. Potrzebny jest przynajmniej:
identyfikator operatora + typ punktu + współrzędne + adres + aktualny status + obsługiwane usługi + godziny dostępności, jeżeli przewoźnik je udostępnia.
Identyfikatory są istotniejsze niż nazwa widoczna dla klienta. Allegro pokazuje skalę różnic: przykładowe identyfikatory punktów mogą mieć postać `ADA01N` dla InPost, `PL11033` dla DPD czy ciągu liczbowego dla DHL lub ORLEN Paczki. Nie wolno zakładać jednego formatu albo jednej długości pola. (developer.allegro.pl)
Jeszcze ważniejsze jest odświeżanie punktów. Automat może zostać wyłączony, przeniesiony albo czasowo niedostępny. Zapisanie całej bazy punktów raz na miesiąc jest kuszące, ale oznacza ryzyko oferowania klientowi lokalizacji, której przewoźnik nie chce już przyjąć.
W projekcie SaaS rozsądniejszy jest cache z kontrolowanym czasem życia, a dla szczególnie istotnych danych dodatkowe sprawdzenie punktu przed utworzeniem przesyłki.
Walidacja paczki musi nastąpić przed zakupem etykiety
Najbardziej kosztowne błędy w integracji logistycznej wyglądają niewinnie. Sprzedawca wpisuje 20 × 40 × 60 cm, wybiera niewłaściwy gabaryt i przesyłka zostaje przyjęta do systemu. Problem pojawia się później: przewoźnik dokonuje pomiaru i nalicza dopłatę.
Dlatego reguły gabarytowe powinny być częścią silnika wysyłkowego, a nie instrukcją wyświetlaną użytkownikowi.
Przy InPost różnica między gabarytami jest konkretna. Dla przesyłek paczkomatowych podstawowe maksymalne parametry wynoszą:
- gabaryt A – 8 × 38 × 64 cm, do 25 kg,
- gabaryt B – 19 × 38 × 64 cm, do 25 kg,
- gabaryt C – 41 × 38 × 64 cm, do 25 kg.
Aktualny cennik detaliczny wskazuje odpowiednio 16,49 zł, 18,49 zł i 20,49 zł brutto. W ofercie biznesowej ceny zależą od modelu współpracy; na stronie abonamentowej prezentowane są przykładowo stawki od około 12–16 zł netto za paczkę w zależności od gabarytu i wariantu umowy. To ważna różnica dla twórcy platformy: cena nie powinna być zaszyta w integracji przewoźnika, bo dwóch sprzedawców może korzystać z tego samego API przy zupełnie innych warunkach handlowych. (inpost.pl)
Jeszcze ważniejsze są dopłaty. W publicznym cenniku biznesowym InPost sama weryfikacja przekroczenia wagi lub wymiarów może kosztować kilkanaście złotych netto, a opłata za potraktowanie przesyłki jako ponadgabarytowej kolejne kilkanaście złotych. Przy skrajnym przekroczeniu parametrów opłaty liczone są już w setkach złotych. Jedno niedopilnowane pole w formularzu może więc zjeść marżę z całego zamówienia. (inpost.pl)
DPD ma inne limity. Automat DPD Pickup Station przyjmuje przesyłkę o maksymalnych wymiarach 50 × 44 × 59 cm i wadze do 20 kg. Dla punktów stacjonarnych limity zależą dodatkowo od rodzaju placówki. Przykładowo dla punktów działających w sklepach Żabka DPD podaje maksymalnie 41 × 38 × 64 cm i 20 kg, podczas gdy pozostałe punkty Pickup mogą obsługiwać przesyłki o długości do 150 cm, przy zachowaniu innych parametrów granicznych. (dpd.com)
DHL BOX 24/7 pracuje z kolejnym zestawem parametrów: maksymalna waga to 25 kg, a skrytki mają rozmiary 64 × 38 × 8 cm, 64 × 38 × 19 cm oraz 64 × 38 × 41 cm. Do dostawy do automatu potrzebne są również dane kontaktowe odbiorcy używane do powiadomień. (dhl.com)
Wniosek jest prosty: w bazie nie powinno istnieć jedno pole `maxParcelSize` przypisane do typu „locker”.
Potrzebny jest silnik reguł zależny od przewoźnika i usługi, obejmujący co najmniej:
- minimalne i maksymalne wymiary,
- wagę rzeczywistą,
- sposób liczenia wagi gabarytowej, jeśli występuje,
- maksymalną liczbę paczek,
- obsługę pobrania,
- maksymalną wartość COD,
- dopuszczalne kraje,
- towary wykluczone,
- możliwość nadania bez etykiety,
- wymagane dane odbiorcy,
- zasady ubezpieczenia,
- ograniczenia dotyczące punktów odbioru.
Walidacja powinna działać przed wywołaniem API przewoźnika. Operator może oczywiście ponownie zweryfikować parametry, ale błąd wykryty już po zakupie etykiety komplikuje anulowanie przesyłki, rozliczenia i obsługę klienta.
Osobnym problemem jest idempotencja. Użytkownik klika „Nadaj”, przeglądarka nie dostaje odpowiedzi po pięciu sekundach i ponawia operację. Bez identyfikatora idempotencyjnego można utworzyć dwie przesyłki i dwa numery przewozowe dla jednego zamówienia.
Dlatego każde żądanie utworzenia przesyłki powinno otrzymywać własny idempotency key powiązany z zamówieniem i próbą nadania. Sam timeout nie oznacza, że operacja się nie udała. Po zerwaniu połączenia należy najpierw ustalić stan poprzedniej operacji, a dopiero potem tworzyć kolejną.
Statusy, webhooki i utrzymanie integracji decydują o jakości całej usługi
Etykieta jest najbardziej widoczną częścią systemu, ale technicznie nie jest najtrudniejsza. Więcej problemów daje stan przesyłki po jej utworzeniu.
Nie wystarczy przechowywać jednego pola `status = sent`.
Realny cykl życia wygląda raczej tak:
`CREATED → LABEL_READY → HANDED_OVER → IN_TRANSIT → OUT_FOR_DELIVERY → DELIVERED`
a obok niego występują stany wyjątkowe:
`CANCELLED`, `DELIVERY_FAILED`, `RETURNING`, `RETURNED`, `PICKUP_EXPIRED`, `DAMAGED`.
Nazwy po stronie poszczególnych operatorów będą inne. Zadaniem warstwy integracyjnej jest mapowanie ich do własnego słownika, ale bez utraty oryginalnego komunikatu.
Dobrą praktyką jest więc zapis dwóch wartości: statusu znormalizowanego używanego przez sklep oraz surowego statusu przewoźnika potrzebnego do diagnostyki.
Statusów nie należy pobierać co minutę dla każdej paczki, jeśli operator udostępnia webhooki. ORLEN Paczka ma mechanizm Pusher, który przekazuje zdarzenia o zmianach statusu w czasie rzeczywistym i właśnie dzięki temu eliminuje konieczność ciągłego odpytywania API. InPost również opisuje obsługę webhooków w swojej aktualnej platformie API. Polling powinien być mechanizmem uzupełniającym — na przykład do okresowej synchronizacji przesyłek, dla których webhook nie dotarł. (orlenpaczka.pl)
Webhook również potrafi narobić bałaganu. Ten sam event może przyjść dwa razy. Zdarzenia mogą dotrzeć w innej kolejności niż zostały wygenerowane. Endpoint sklepu może przez kilka minut odpowiadać błędem.
Dlatego potrzebne są:
- deduplikacja eventów,
- kolejka komunikatów,
- automatyczne retry,
- dead-letter queue dla zdarzeń wielokrotnie odrzuconych,
- zapis czasu wystąpienia zdarzenia po stronie operatora,
- log techniczny pozwalający odtworzyć historię przesyłki.
Przy kilku tysiącach paczek dziennie kolejka przestaje być technicznym dodatkiem. Jest zabezpieczeniem przed sytuacją, w której chwilowa awaria jednego operatora blokuje nadawanie u wszystkich klientów platformy.
Trzeba również rozdzielić konto platformy od konta sprzedawcy. Są dwa podstawowe modele biznesowe.
Pierwszy: sprzedawca podłącza własną umowę z InPost, DPD czy DHL. Platforma przechowuje jego dane dostępowe i pobiera opłatę za SaaS. To najprostsze rozwiązanie pod względem rozliczeń transportu, ale wymaga bezpiecznego przechowywania credentiali oraz obsługi wielu konfiguracji klientów.
Drugi: operator platformy działa na własnej umowie z przewoźnikiem i odsprzedaje usługę logistyczną sprzedawcom. Potencjał marżowy jest większy, ale rośnie odpowiedzialność za billing, korekty przewoźnika, dopłaty gabarytowe, COD, zwroty i reklamacje. Tego modelu nie powinno się uruchamiać tylko dlatego, że daje 1–2 zł dodatkowej marży na przesyłce. Najpierw trzeba mieć system potrafiący zestawić każdą paczkę z późniejszą fakturą operatora.
W praktyce bardzo przydaje się osobna tabela `shipment_charges`, w której zapisywane są cena bazowa i późniejsze korekty. Bez niej po miesiącu trudno odpowiedzieć klientowi, dlaczego pierwotnie pokazano 14,90 zł, a rozliczenie przewoźnika wyniosło 31,20 zł.
Konieczna jest też obserwowalność. Dla każdej integracji warto mierzyć:
odsetek poprawnie utworzonych przesyłek, czas odpowiedzi API, liczbę timeoutów, liczbę błędów 4xx i 5xx, opóźnienie webhooków oraz liczbę przesyłek bez aktualizacji statusu przez określony czas.
Alert „API nie odpowiada” jest za mało precyzyjny. Znacznie bardziej użyteczny komunikat brzmi: „od 14:07 18% prób wygenerowania etykiety DPD kończy się HTTP 500, pozostałe funkcje działają poprawnie”.
Integrację trzeba ponadto traktować jak kod, który będzie regularnie zmieniany. Dobrym przykładem jest Allegro: w 2026 r. wprowadziło nowe mechanizmy obsługi propozycji nadania, zapowiedziało usunięcie starszych zasobów w I kwartale 2027 r., a inne elementy związane z dostawami zmieniały się w ciągu roku wielokrotnie. System bez testów kontraktowych i monitorowania changelogów będzie prędzej czy później działał tylko do pierwszej większej zmiany po stronie partnera. (developer.allegro.pl)
Minimalny rozsądny zestaw testów dla każdego adaptera obejmuje utworzenie przesyłki, anulowanie, wygenerowanie etykiety, błędne dane odbiorcy, przekroczony gabaryt, nieważny punkt odbioru, timeout, powtórzenie tego samego żądania oraz przetworzenie statusów przychodzących w nieprawidłowej kolejności.
Dopiero później warto dodawać bardziej efektowne funkcje: automatyczny wybór najtańszego przewoźnika, reguły „wyślij DPD powyżej 20 kg”, routing według kodu pocztowego, porównanie cen czy automatyczne rozdzielanie jednego zamówienia na kilka paczek.
To również dobre miejsce na panel administracyjny dla sprzedawcy. Powinien pokazywać nie tylko listę paczek, lecz także konkretną przyczynę błędu i możliwe działanie. Komunikat „Błąd API 400” jest bezwartościowy. „Brakuje numeru telefonu odbiorcy wymaganego przy dostawie do DHL BOX – uzupełnij telefon i ponów nadanie” pozwala magazynierowi rozwiązać problem bez kontaktu z pomocą techniczną.
Przy projektowaniu takiej platformy przydają się również materiały dotyczące praktycznej strony prowadzenia i rozwijania usług dla firm. Dodatkowe informacje można znaleźć na https://hd-biznes.com/blog.
FAQ – najczęstsze pytania przed budową integracji wysyłkowej
Czy lepiej integrować każdego kuriera osobno, czy skorzystać z brokera przesyłek?
Jeżeli celem jest szybkie uruchomienie wysyłek w jednym sklepie, broker lub gotowy system typu BaseLinker może być tańszy i szybszy niż własna integracja. Własna warstwa przewoźników zaczyna mieć sens wtedy, gdy logistyka jest częścią produktu, obsługujesz wielu sprzedawców albo potrzebujesz własnych reguł cenowych, statusów i automatyzacji.
Czy każdy sprzedawca powinien mieć własną umowę z przewoźnikiem?
Na początku to najbezpieczniejszy model. Sprzedawca korzysta ze swoich stawek i sam rozlicza transport, a platforma odpowiada za techniczną automatyzację. Model wspólnej umowy warto rozważać dopiero wtedy, gdy system potrafi rozliczać dopłaty, zwroty, pobrania i korekty na poziomie pojedynczej przesyłki.
Którego przewoźnika wdrożyć jako pierwszego?
Nie wybieraj na podstawie tego, czy jego API wydaje się najłatwiejsze. Najpierw sprawdź strukturę przesyłek przyszłych klientów. Jeśli dominują małe paczki B2C do automatów, naturalnym pierwszym kandydatem w Polsce jest InPost. Jeżeli znacząca część przesyłek jest większa, międzynarodowa albo dostarczana pod adres, trzeba od początku uwzględnić co najmniej jednego klasycznego operatora kurierskiego.
Czy trzeba przechowywać etykiety na własnym serwerze?
Nie zawsze. Jeżeli operator pozwala ponownie je pobrać, można przechowywać przede wszystkim identyfikator przesyłki i pobierać dokument na żądanie. W środowisku magazynowym wygodny jest jednak krótkotrwały cache, szczególnie przy drukowaniu dużych serii. Trzeba ustalić termin retencji i kontrolować dostęp, ponieważ dokument przewozowy zawiera dane osobowe.
PDF czy ZPL – jaki format etykiet obsłużyć?
Dla małego sklepu PDF wystarczy. Dla magazynu drukującego setki etykiet dziennie potrzebny jest ZPL lub format obsługiwany bezpośrednio przez drukarkę termiczną. Dlatego API platformy powinno przyjmować format etykiety jako parametr, zamiast zakładać PDF na stałe.
Czy wystarczy sprawdzać status przesyłki raz na godzinę?
Przy niewielkiej skali technicznie tak, ale nie jest to dobra architektura produktu SaaS. Jeżeli przewoźnik oferuje webhooki, powinny być podstawowym źródłem aktualizacji, a okresowa synchronizacja ma jedynie wykrywać brakujące zdarzenia. Ogranicza to ruch i zmniejsza opóźnienie statusów.
Jak długo powinno trwać pierwsze wdrożenie?
Sam adapter do jednego dobrze udokumentowanego API może powstać szybko, ale produkcyjna usługa obejmuje również konfigurację kont klientów, kolejki, retry, webhooki, logowanie, monitoring, walidację, panel błędów i testy. Realnego harmonogramu nie należy liczyć liczbą endpointów. Integracja z pięcioma metodami API bez infrastruktury odpornościowej jest mniej kompletna niż integracja z jednym przewoźnikiem, która prawidłowo obsługuje awarie.
Co najczęściej psuje się po uruchomieniu?
Nie samo generowanie etykiet. Najwięcej problemów powodują zmienione identyfikatory usług i punktów, błędne wymiary przesyłek, nieważne dane dostępowe klienta, zmiany dokumentacji API, niedostarczone webhooki i ponowienie operacji po timeoutach.
Od czego więc zacząć?
Od jednego diagramu procesu i jednego wspólnego modelu danych. Rozpisz drogę `zamówienie → wybór dostawy → walidacja → utworzenie przesyłki → etykieta → nadanie → tracking → doręczenie/zwrot`, a następnie sprawdź, czy żaden element tego procesu nie zawiera na stałe nazw i pól pierwszego przewoźnika. Jeżeli zawiera, usuń to sprzężenie przed dodaniem drugiej integracji. To najtańszy moment na naprawę architektury; po podłączeniu kilku operatorów ten sam błąd trzeba będzie usuwać jednocześnie z API, bazy danych, checkoutu i panelu sprzedawcy.
