beziworld / laravel-apaczka
Apaczka.pl API v2 client for Laravel: HMAC-signed requests, price valuation, orders, waybills, pickups, parcel points, tracking and signed push-tracking webhooks.
Requires
- php: ^8.3
- ext-json: *
- guzzlehttp/guzzle: ^7.8
- illuminate/contracts: ^12.0|^13.0
- illuminate/http: ^12.0|^13.0
- illuminate/routing: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^3.7|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
- phpstan/phpstan-strict-rules: ^2.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-04 16:36:19 UTC
README
Apaczka.pl API v2 client for Laravel. One integration ships parcels with InPost, DPD, DHL, UPS, Poczta Polska (Pocztex), Orlen Paczka and more:
- HMAC-SHA256 signed requests, with the error envelope turned into exceptions
- price valuation, orders, cancellation, labels (waybills) and handover protocols
- courier pickups, parcel points (lockers, pickup points) and tracking
- signed push tracking webhooks dispatched as Laravel events
Installation
composer require beziworld/laravel-apaczka
php artisan vendor:publish --tag=apaczka-config # optional
APACZKA_APP_ID=your-app-id # panel: Settings > API (WebAPI application) APACZKA_APP_SECRET=your-app-secret APACZKA_SANDBOX=false # true = panel-sandbox.apaczka.pl
Price and send a parcel
use Beziworld\Apaczka\Data\Address; use Beziworld\Apaczka\Data\OrderRequest; use Beziworld\Apaczka\Data\Parcel; use Beziworld\Apaczka\Facades\Apaczka; $order = new OrderRequest( serviceId: 41, // InPost locker; ids come from serviceStructure() sender: new Address('ACME Shop', 'ul. Prosta 1', '00-001', 'Warszawa', email: 'shop@acme.pl', phone: '500600700'), receiver: new Address('Jan Kowalski', 'ul. Długa 5/3', '30-001', 'Kraków', email: 'jan@example.com', phone: '600700800', pointId: 'KRA01M'), // locker or pickup point parcels: [new Parcel(length: 38, width: 64, height: 8, weight: 2.5)], content: 'Books', codAmount: 149.99, // zloty; converted to grosze codBankAccount: '61109010140000071219812874', declaredValue: 200, pushTrackingUrl: route('apaczka.webhook'), ); $prices = Apaczka::valuation($order); // [41 => ['price' => 1200, 'price_gross' => 1476]] in grosze $created = Apaczka::sendOrder($order); $created->id; // Apaczka order id $created->waybillNumber; // carrier waybill number $pdf = Apaczka::waybill($created->id); // label, binary PDF
Without pickupDate the parcel is dropped off by the sender. Pass pickupDate: now()->addDay(), pickupFrom: '10:00', pickupTo: '15:00' to order a courier with the order, or use Apaczka::pickup() / Apaczka::batchPickup() later.
sendOrder() is not idempotent and is never retried automatically: on a timeout, check Apaczka::orders() before
sending again.
Other operations
Apaczka::serviceStructure(); // services, options, parcel types Apaczka::points('INPOST'); // list<Point>: id, address, coordinates, cod/send/deliver Apaczka::tracking('6800000000000'); // Tracking: service, events (newest first), isDelivered() Apaczka::pickupHours('00-001', serviceId: 21); // available courier windows Apaczka::turnIn([123, 124]); // handover protocol, binary PDF Apaczka::dispatchCode(123); // drop-off code Apaczka::cancelOrder(123); Apaczka::call('check_data/', ['vat_id' => 'PL5261040828']); // any other API v2 method
Push tracking webhook
The package registers POST /apaczka/webhook (route name apaczka.webhook). Set its URL as the tracking webhook
of the WebAPI application, or send it with each order as pushTrackingUrl. Every notification is verified with
HMAC-SHA256 and dispatched as an event:
use Beziworld\Apaczka\Events\TrackingStatusChanged; Event::listen(function (TrackingStatusChanged $event): void { $shipment = Shipment::where('apaczka_order_id', $event->notification->orderId)->first(); $status = $event->notification->latest()?->status; // e.g. ON_THE_WAY, DELIVERED, RETURNED // ... });
Apaczka redelivers a notification until it gets HTTP 200, so make listeners idempotent. Webhook statuses differ from
polling statuses (for example CANCELED versus CANCELLED; SENT means a COD payout). Webhook timestamps are
Europe/Warsaw time.
Configuration: APACZKA_WEBHOOK_ENABLED, APACZKA_WEBHOOK_PATH, and apaczka.webhook.middleware (default api).
Errors
Apaczka answers every call with HTTP 200 and reports the outcome in the body. The client throws ApiException for
every non-200 status, with apiStatus(), route() and isSignatureError(). Connection failures are thrown as
ApiException too. Missing credentials raise InvalidConfiguration.
Development
composer install
composer ci # pint --test, phpstan (level 8), pest
Author
Created and maintained by Kamil Ćwiertnia, beziworld.eu.
- E-mail: biuro@beziworld.eu
- Issues: GitHub issues
Need a shipping integration for your shop? Get in touch through beziworld.eu.
Other packages by the author
laravel-inpost · laravel-furgonetka · laravel-dpd · laravel-dhl-parcel · laravel-orlen-paczka
License
MIT. See LICENSE.md. This package is not affiliated with Apaczka.pl or Alsendo.