very-code-com / furgonetka-api-php
PHP client for the Furgonetka.pl REST API: OAuth2, price comparison, shipments, labels, pickups, tracking, pickup points, returns, address book, notifications and webhooks. One API for DPD, InPost, DHL, UPS, GLS, FedEx, Poczta Polska, ORLEN Paczka and more.
Package info
github.com/very-code-com/furgonetka-api-php
pkg:composer/very-code-com/furgonetka-api-php
Requires
- php: ^8.2
- ext-curl: *
- ext-json: *
- ext-libxml: *
- ext-mbstring: *
- ext-simplexml: *
- psr/log: ^2.0|^3.0
Requires (Dev)
- ext-zlib: *
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^10.5|^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-29 14:24:06 UTC
README
PHP client library for the Furgonetka.pl REST API.
Compare prices of DPD, InPost, DHL, UPS, GLS, FedEx, Poczta Polska, ORLEN Paczka and others behind one API of the courier broker Furgonetka.pl: create and order shipments, download labels, book pickups, track parcels, find pickup points, send abroad and receive tracking webhooks. No framework and no HTTP library to install: plain cURL, PSR-3 for logging.
Installation
composer require very-code-com/furgonetka-api-php
Requires PHP 8.2+ with ext-curl, ext-json, ext-libxml, ext-mbstring and ext-simplexml, a Furgonetka.pl account
and an OAuth application. Getting started shows how to get the keys, for the sandbox and for
production.
Quick start
Keep the keys in the environment (FURGONETKA_CLIENT_ID, FURGONETKA_CLIENT_SECRET, FURGONETKA_ENV) and log in once
from a terminal (php examples/02_password_grant_and_2fa.php); the token is stored and refreshes itself after that.
use VeryCodeCom\FurgonetkaApi\Auth\Store\FileTokenStore; use VeryCodeCom\FurgonetkaApi\Dto\{Parcel, PriceScope, Pickup, Receiver, ShipmentRequest}; use VeryCodeCom\FurgonetkaApi\Enum\Carrier; use VeryCodeCom\FurgonetkaApi\{FurgonetkaApiClient, FurgonetkaApiConfig}; $client = FurgonetkaApiClient::create( FurgonetkaApiConfig::fromEnv(), new FileTokenStore('/var/lib/shop/furgonetka-token.json'), ); $service = $client->listServices()->first(Carrier::Dpd) // your contract with the carrier ?? throw new RuntimeException('The account has no DPD contract.'); $request = new ShipmentRequest( serviceId: $service->id ?? throw new RuntimeException('The service has no id.'), pickup: new Pickup('Marszalkowska 100', '00-026', 'Warszawa', name: 'Jan Kowalski', countryCode: 'PL', email: 'jan@example.com', phone: '500600700'), receiver: new Receiver(name: 'Anna Nowak', street: 'Florianska 15', postcode: '31-021', city: 'Krakow', countryCode: 'PL', email: 'anna@example.com', phone: '600700800'), parcels: [Parcel::package(30, 40, 20, 5.0, 100.0, 'Books')], // cm, kg, value in PLN ); // Prices of several carriers at once; a carrier that cannot take the parcel is `available: false`. $quotes = $client->calculatePrices($request, PriceScope::carriers(Carrier::Dpd, Carrier::InPost, Carrier::Gls)); // Create the shipment, then order it. A carrier's rejection is a result, not an exception. $package = $client->createPackage($request); $result = $client->orderPackages([$package]); if ($result->isSuccessful()) { file_put_contents('label.pdf', $client->fetchLabel($package)->bytes); echo implode(', ', $client->fetchPackage($package)->waybillNumbers()); } else { foreach ($result->errorsFor((string) $package->id) as $error) { echo $error->path, ': ', $error->message, PHP_EOL; } }
Ordering on production charges the account and books a carrier. Try everything on the sandbox first; the examples are dry unless you ask them to order.
Documentation
| Document | Contents |
|---|---|
| Getting started | Accounts and OAuth keys for the sandbox and production, configuration, debug mode, what to know before the first order |
| Authentication and tokens | The grants, token stores, several accounts, Laravel and Symfony |
| Sending abroad | Customs data, contracts, regulations, the customs signature outside the EU |
| API reference | Every client method, the objects they take and return, local validation, exceptions, the webhook parser |
| Furgonetka's quirks | What the API does that its documentation does not say, and what was not verified |
| Testing | Testing your code against a fake transport, running this library's tests, CI |
| Examples | Eighteen runnable scripts, three of them offline |
| Cookbook | About two hundred small recipes by carrier, service and country, each run against the sandbox |
| Changelog | Releases |
License
Apache License 2.0, see NOTICE for attribution requirements. You may use, distribute and modify
this library freely, and must retain the NOTICE file and copyright notices in any redistribution or derivative work.
Built by Very Code. Contributions welcome, open an issue or PR.