Integracja InPost w sklepie internetowym – Paczkomaty i API ShipX

Remigiusz Mielcarz 5 min czytania

integracjeinpostmedusa.js

Paczkomaty to w polskim e-commerce standard, a nie wyróżnik – dla wielu klientów brak InPostu w checkoucie to powód, żeby kupić gdzie indziej. Dobra wiadomość: API ShipX jest jednym z lepiej zaprojektowanych API logistycznych na naszym rynku i integrację da się zrobić porządnie, bez wtyczek-kombajnów. Poniżej przechodzimy przez cały przepływ, którego używamy we wdrożeniach – od wyboru punktu po etykietę i statusy.

Jak to działa w całości

Zanim wejdziemy w szczegóły, pełny obraz. Integracja InPost to cztery klocki, które muszą się spiąć:

  1. Wybór punktu w checkoucie – klient wskazuje Paczkomat na mapie (Geowidget) albo wybiera kuriera.
  2. Utworzenie przesyłki – sklep wysyła do ShipX dane odbiorcy, wymiary paczki i usługę.
  3. Etykieta – po opłaceniu oferty ShipX zwraca PDF (albo ZPL pod drukarki termiczne), który drukuje magazyn.
  4. Statusy – sklep śledzi, co się dzieje z paczką, i aktualizuje zamówienie oraz maile do klienta.

Każdy z tych klocków da się spartaczyć osobno, więc przejdźmy po kolei.

Wybór Paczkomatu: Geowidget, nie własna mapa

Pierwszy odruch bywa taki, żeby pobrać listę punktów z API i wyświetlić je na własnej mapie. To ślepa uliczka – punktów jest kilkadziesiąt tysięcy, zmieniają się codziennie, a InPost i tak udostępnia gotowy, darmowy Geowidget. To web component, który osadza się jednym tagiem:

<inpost-geowidget
  token="TWÓJ_TOKEN_GEOWIDGETU"
  language="pl"
  config="parcelCollect"
  onpoint="onPointSelected"
></inpost-geowidget>

Po wybraniu punktu dostajesz zdarzenie z obiektem punktu – najważniejsze pole to name, czyli identyfikator w stylu KRA012, który za chwilę przekażemy do ShipX. W sklepach na Medusa.js trzymamy go w metadanych metody dostawy koszyka, więc backend widzi wybór klienta bez żadnej dodatkowej magii.

Dwie rzeczy, o których łatwo zapomnieć:

  • Token Geowidgetu to inny token niż ShipX – generuje się go osobno w Managerze Paczek i jest jawny (działa w przeglądarce), więc nie ma co go „ukrywać”.
  • Walidacja po stronie backendu – identyfikator punktu z frontendu traktujemy jak każde inne dane od użytkownika. Przed utworzeniem przesyłki sprawdzamy, że punkt istnieje i przyjmuje paczki.

Tworzenie przesyłki w ShipX

ShipX ma dwa środowiska: produkcyjne i sandbox. Zaczynamy zawsze od sandboxa – działa bez umowy z InPost i pozwala przećwiczyć wszystko, łącznie z błędami walidacji.

Przesyłkę tworzy się jednym żądaniem POST na endpoint organizacji:

POST /v1/organizations/{organization_id}/shipments
Authorization: Bearer TWÓJ_TOKEN_SHIPX
Content-Type: application/json
{
  "receiver": {
    "email": "klient@example.com",
    "phone": "500600700"
  },
  "parcels": [{ "template": "small" }],
  "service": "inpost_locker_standard",
  "custom_attributes": {
    "target_point": "KRA012"
  },
  "reference": "ZAM-2026-01234"
}

Kilka praktycznych uwag, które oszczędzą godzin debugowania:

  • Szablony paczek (small, medium, large) odpowiadają gabarytom A/B/C Paczkomatu. Jeśli sprzedajesz produkty o nietypowych wymiarach, podajesz dimensions i weight jawnie – ale przy Paczkomatach i tak obowiązują limity gabarytów, więc szablon jest zwykle prostszy.
  • reference to Twój przyjaciel – wpisujemy tam numer zamówienia ze sklepu. Widać go potem na etykiecie i w Managerze Paczek, co ratuje życie przy reklamacjach.
  • Telefon odbiorcy musi być polskim numerem komórkowym – na ten numer idzie SMS z kodem odbioru. Walidujcie to w checkoucie, nie dopiero w odpowiedzi błędu z ShipX.
  • Dla kuriera zamiast target_point podaje się pełny adres odbiorcy, a usługę zmienia na inpost_courier_standard. Reszta przepływu jest identyczna – to duża zaleta ShipX.

Po utworzeniu przesyłka przechodzi przez cykl ofert: ShipX wycenia usługę, a sklep kupuje wybraną ofertę. Przy prostych konfiguracjach z jedną usługą da się to zautomatyzować do zera – tworzysz przesyłkę, czekasz na status z gotową ofertą i od razu ją kupujesz.

Etykieta: PDF dla biura, ZPL dla magazynu

Po opłaceniu przesyłki (status confirmed) pobiera się etykietę:

GET /v1/shipments/{shipment_id}/label?format=pdf

Format pdf wystarcza, gdy etykiety drukuje się z przeglądarki. Przy większych wolumenach warto od razu pomyśleć o zpl – drukarki termiczne (Zebra i klony) przyjmują go bezpośrednio, bez renderowania PDF-a, co przy kilkuset paczkach dziennie robi realną różnicę.

We wdrożeniach B2B podpinamy pobieranie etykiety pod zmianę statusu zamówienia: magazyn oznacza zamówienie jako spakowane, system tworzy przesyłkę, kupuje ofertę, pobiera etykietę i odsyła ją do wydruku. Nikt niczego nie przeklikuje ręcznie – i o to chodzi.

Statusy: skąd sklep wie, że paczka jedzie

ShipX wystawia słownik statusów (endpoint /v1/statuses) i pozwala śledzić przesyłkę po numerze trackingowym. W praktyce sprawdzają się dwa podejścia:

PodejścieJak działaKiedy wybrać
PollingCykliczne odpytywanie o statusy aktywnych przesyłekMniejsze wolumeny, prostota
WebhookiInPost wypycha zmiany statusów na Twój endpointDuże wolumeny, aktualizacje niemal na żywo

Niezależnie od podejścia: mapujcie statusy InPostu na własne, prostsze statusy zamówienia. Klienta nie interesuje różnica między „przyjęta w oddziale” a „w drodze do regionu” – interesuje go „nadana”, „czeka w Paczkomacie” i „odebrana”. Mail z kodem odbioru wysyła InPost, ale dobry sklep i tak pokazuje status w koncie klienta.

Jak to wygląda w Medusa.js

W Medusa v2 logistykę spina się przez moduł fulfillmentu – provider implementuje kilka metod (utworzenie przesyłki, anulowanie, pobranie dokumentów), a resztą steruje rdzeń platformy. Szkielet wygląda tak:

class InpostFulfillmentProvider extends AbstractFulfillmentProviderService {
  static identifier = "inpost";

  async createFulfillment(data, items, order, fulfillment) {
    const shipment = await this.shipx.createShipment({
      receiver: mapReceiver(order),
      parcels: mapParcels(items),
      service: data.service, // locker albo courier
      targetPoint: data.target_point,
      reference: order.display_id,
    });
    return { data: { shipment_id: shipment.id } };
  }

  async getFulfillmentDocuments(data) {
    return this.shipx.getLabel(data.shipment_id, "zpl");
  }
}

To celowo szkic, nie gotowiec – sedno w tym, że integracja logistyczna w Medusie jest modułem, nie wtyczką z marketplace’u. Macie pełną kontrolę nad tym, kiedy przesyłka powstaje, co trafia do reference i jak wygląda obsługa błędów. Na tej samej zasadzie zbudowaliśmy wysyłkę w naszym pokazowym sklepie demo.koda.plus – można tam poklikać pełny checkout z wyborem Paczkomatu.

Najczęstsze wtopy z wdrożeń

  • Brak obsługi błędów walidacji – ShipX potrafi odrzucić przesyłkę (np. zły telefon). Sklep musi to pokazać obsłudze, a nie połknąć.
  • Etykieta generowana przy złożeniu zamówienia – za wcześnie. Paczka może się nie spakować tego dnia, a niektóre oferty mają termin ważności. Etykieta powinna powstawać, gdy magazyn faktycznie pakuje.
  • Jeden token na sandbox i produkcję – to dwa osobne środowiska z osobnymi tokenami. Trzymajcie je w zmiennych środowiskowych i nigdy w repozytorium.
  • Punkt wybrany raz na zawsze – Paczkomat bywa przepełniony albo czasowo niedostępny. Warto obsłużyć redirect przesyłki i komunikat dla klienta, zamiast udawać, że problem nie istnieje.

Jeśli zamiast składać to wszystko samodzielnie wolicie mieć logistykę spiętą z resztą sklepu – od checkoutu, przez ERP, po maile – to dokładnie ten zakres robimy przy sklepach i hurtowniach na Medusa.js.

Najczęstsze
pytania

  • Czy do integracji z InPost potrzebuję podpisanej umowy?

    Do produkcyjnej wysyłki tak – token API generuje się w Managerze Paczek, który dostajesz po podpisaniu umowy z InPost. Do developmentu wystarczy darmowe środowisko sandbox ShipX, które działa bez umowy i pozwala przećwiczyć cały proces.

  • Czy Paczkomaty i kurier InPost to to samo API?

    Tak. ShipX obsługuje i Paczkomaty (usługa inpost_locker_standard), i kuriera (inpost_courier_standard). Różnica sprowadza się do nazwy usługi i tego, że przy Paczkomacie trzeba przekazać identyfikator punktu docelowego wybranego przez klienta.

  • Jak przetestować integrację bez wysyłania prawdziwych paczek?

    InPost udostępnia sandbox ShipX z osobnym tokenem i osobną bazą punktów. Tworzysz w nim przesyłki, kupujesz oferty i pobierasz etykiety dokładnie tak samo jak na produkcji – nic fizycznie nie jedzie, a Ty testujesz pełny przepływ razem ze statusami.

  • Ile trwa wdrożenie InPost w sklepie na Medusa.js?

    Sam moduł fulfillmentu z wyborem Paczkomatu, generowaniem etykiet i śledzeniem statusów to zwykle kilka dni pracy. Więcej czasu zajmuje dopięcie procesu po stronie magazynu: kto drukuje etykiety, kiedy zamówienie zmienia status i co widzi klient w mailu.

Bezpłatne, 15-minutowe spotkanie

Opowiedz nam o swoim projekcie,
resztę dopasujemy pod Ciebie

15 minut rozmowy wystarczy, abyśmy wiedzieli, czy pasujemy do Twojego projektu.
Zaczynamy od Twoich potrzeb, nie od gotowego rozwiązania.

Skontaktuj się z nami

Remigiusz w granatowej koszuli i okularach
Korzystam z iMessage Korzystam z WhatsApp
Adrian w szarym golfie i okularach
Korzystam z iMessage Korzystam z WhatsApp