Otwartoźródłowy klient PHP dla API Cargoboard: wiążące ceny frachtu, rezerwacje, etykiety i potwierdzenia, śledzenie w czasie rzeczywistym z webhookami, faktury oraz dane ADR, od drobnicy po całe pojazdy w 32 krajach Europy.
Cargoboard to cyfrowy spedytor: zamiast wysyłać zapytanie ofertowe i czekać, aż ktoś odpowie, przesyłasz dane ładunku i w tej samej odpowiedzi dostajesz wiążącą cenę - a potem rezerwujesz dokładnie tę cenę. Obsługiwane są przesyłki drobnicowe, ładunki częściowe rozliczane metrami ładunkowymi, całopojazdowe, całe pojazdy oraz paczki, w 32 krajach Europy.
cargoboard-php to otwartoźródłowy klient PHP pokrywający wszystkie endpointy publicznego API, a do tego payload webhooka Track & Trace oraz linki do śledzenia dla klienta końcowego. Jest otypowany do poziomu PHPStan 8, waliduje żądanie według udokumentowanych reguł Cargoboard, zanim je wyśle, i został sprawdzony od początku do końca na żywym sandboxie: wycena, rezerwacja, odczyt zlecenia, śledzenie, PDF-y etykiet i potwierdzenia oraz anulowanie.
Wersja 1.1 dołożyła to, czego można się nauczyć wyłącznie prowadząc integrację na produkcji - i dokładnie stamtąd pochodzi: z uwag integratora pracującego na żywym koncie, przy czym każde stwierdzenie zostało ponownie zweryfikowane wobec definicji OpenAPI Cargoboard, zanim trafiło do kodu.
Wszystkie publikowane endpointy Cargoboard, ukryte za typowanymi obiektami żądań i odpowiedzi.
Wycena zwraca wiążącą cenę z rozbiciem na pozycje kosztowe - fracht, dopłaty, opłaty drogowe - więc można klientowi pokazać, za co płaci, a następnie zarezerwować to samo ID wyceny bez ponownego przeliczania.
Drobnica i LTL na palety lub kartony, ładunki częściowe rozliczane metrami ładunkowymi oraz pięć klas całych pojazdów, od busa firanki po ciężarówkę 40-tonową - każda z limitem ładowności i dozwolonymi produktami pilnowanymi lokalnie.
To samo żądanie, wysłane z jednym nagłówkiem, jest wyceniane i rezerwowane jako paczka, a nie fracht. Przełączenie trybu włącza też zestaw reguł paczkowych: 32 kg wagi rzeczywistej i objętościowej, limity boków i obwodu, dwadzieścia paczek na odbiór dziennie, zakaz towarów niebezpiecznych.
Około jedna trzecia zdarzeń w żywym strumieniu nie ma żadnej treści - niesie za to uszczegółowione okna odbioru i doręczenia. describe() renderuje każde zdarzenie jako linijkę przeznaczoną dla człowieka, a strumień jest deduplikowany po identyfikatorze zdarzenia.
Dane ADR wyszukiwane po numerze UN i konwertowane wprost na deklarację przy pozycji ładunku, wraz z instrukcjami pakowania, przepisami szczególnymi i sprawdzeniem przepisu szczególnego 188.
Payload Track & Trace jest parsowany do tej samej postaci co zdarzenia z API, a adresy stron śledzenia dla klienta końcowego budowane są automatycznie - łącznie z wariantem pomijającym captchę.
Wycena potrzebuje kodu pocztowego i kraju; rezerwacja - nazw, ulic, miast i daty odbioru. Ten sam obiekt żądania jest walidowany według właściwego zestawu, więc brakujące pole rezerwacji kończy się komunikatem przy konkretnym polu, a nie odpowiedzią HTTP 422.
Parsowanie jest celowo pobłażliwe: nierozpoznana wartość enuma staje się nullem i zachowuje surowy ciąg, więc nowy kod statusu wymyślony po stronie Cargoboard nie położy działającej integracji.
Każda wycena i rezerwacja jest najpierw sprawdzana lokalnie, a komunikaty poprzedzone są tymi samymi ścieżkami pól, których Cargoboard używa we własnych odpowiedziach 422. Reguły obejmują obowiązkowe pola adresowe zależne od trybu, odbiory i doręczenia od poniedziałku do piątku, spójność okna odbioru, daty doręczenia dostępne wyłącznie dla produktów FIX, treść i wymiary pozycji, geometrię metrów ładunkowych, limity ładowności pojazdów wraz z wymaganymi produktami, ubezpieczenie wymagające zadeklarowanej wartości towaru, wartości wyłącznie w euro, deklaracje towarów niebezpiecznych oraz pełny zestaw reguł paczkowych.
Część reguł Cargoboard egzekwuje w oddziale, a nie kodem HTTP. Odbiorca prywatny zarezerwowany bez umówionej dostawy ani zgody na pozostawienie towaru zostanie przez API przyjęty - a kłopot pojawi się w dniu doręczenia. Odrzucenie takiej rezerwacji lokalnie oznaczałoby, że biblioteka poprawia API, więc te przypadki wracają jako ostrzeżenia: logowane przy każdej wycenie i rezerwacji, nigdy rzucane jako wyjątek.
$errors = $client->validateLocally($request); // blokuje wywolanie
$warnings = $client->warningsFor($request); // logowane, nigdy rzucane
message: null i niesie zamiast tego uszczegółowione okna odbioru i doręczenia - najbardziej użyteczną informację w całym strumieniu. Oczywisty łańcuch wartości domyślnych wypisze dla nich wszystkich goły numer statusu.Cargoboard nie ma też endpointu aktualizacji. Zarezerwowanego zlecenia nie da się zmienić - można je tylko anulować i zarezerwować ponownie albo poprawić przez wsparcie. Warto zaprojektować się wokół tego przed pierwszym zleceniem, a nie po nim.
composer require very-code-com/cargoboard-php
$client = CargoboardClient::sandbox('your-api-key');
$request = new ShipmentRequest(
product: Product::Standard,
shipper: new Shipper(
address: new Address('40239', CountryCode::DE, 'Duesseldorf', 'Examplestreet 12a'),
name: 'Producer ABC GmbH & Co. KG',
pickupOn: '2026-09-01',
),
consignee: new Consignee(
address: new Address('41061', CountryCode::DE, 'Moenchengladbach', 'Examplestreet 5'),
name: 'Consignee ABC AG',
),
lines: [new Line('Werkzeugmaschine', 1, PackageType::EuroPallet, 120, 80, 120, 200.0)],
);
$quotation = $client->quote($request); // 90.85 EUR, 1-2 dni
$order = $client->bookQuotation($quotation->id, $request);
file_put_contents('labels.pdf', $client->fetchLabels($order->id));
foreach ($client->fetchTracking($order->id)->timeline() as $event) {
printf("%-5s %s\n", $event->code, $event->describe());
// 540 Estimates updated: collection 18.08. 07:00-15:00, delivery 19.08. 06:00 - 21.08. 14:00
}
Na sandboxie nic nie jest realizowane i żadna ciężarówka nie rusza w trasę, choć potwierdzenie i tak przychodzi mailem, więc dane da się sprawdzić. Na produkcji każda rezerwacja to prawdziwy, płatny transport.
Hierarchia wyjątków jest celowo drobnoziarnista - uwierzytelnianie, oczekiwanie na synchronizację danych ADR, brak zasobu, konflikt, dane nie do przetworzenia, limit zapytań z podpowiedzią czasu ponowienia oraz błędy serwera, które same wiedzą, czy warto je powtórzyć - żeby wywołujący mógł złapać dokładnie ten przypadek, na który ma odpowiedź.
Continuous integration uruchamia testy jednostkowe na PHP 8.2, 8.3 i 8.4 plus przebieg na najniższych wersjach zależności, potwierdzający, że deklarowana dolna granica faktycznie działa, a do tego PHPStan poziom 8, audyt zależności wobec bazy podatności i bramkę pokrycia kodu odrzucającą wynik poniżej 85%. Nocny workflow integracyjny rezerwuje, śledzi i anuluje prawdziwe zlecenie sandboxowe od początku do końca.
Jedna wskazówka diagnostyczna warta powtórzenia za README: jeśli klucz, który "powinien działać", zwraca 403, najpierw przepisz go znak po znaku. Cargoboard odpowiada identycznym 403 na klucz z literówką, brakujący nagłówek, klucz z niewłaściwego środowiska, nieaktywowane konto i endpoint, do którego klucz nie ma uprawnień. Ani status, ani ciało odpowiedzi, ani nagłówki tego nie rozróżniają.
Dla zespołów PHP, które wożą palety, a nie paczki - producenta wysyłającego maszyny, dystrybutora prowadzącego frachty LTL po Europie, systemu ERP potrzebującego wiążącej ceny wewnątrz koszyka albo procesu zamówień. Sprawdzi się wszędzie tam, gdzie wycena i rezerwacja frachtu mają być zwykłym, otypowanym wywołaniem usługi, z już obsłużonymi i opisanymi nieudokumentowanymi zachowaniami przewoźnika.