smart-dato/post-it-sdk

Poste Italiane (POST_IT) shipping API SDK for Laravel — Saloon-based client with typed DTOs.

Maintainers

Package info

github.com/smart-dato/post-it-sdk

pkg:composer/smart-dato/post-it-sdk

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.0.1 2026-05-08 09:17 UTC

This package is auto-updated.

Last update: 2026-05-08 10:01:33 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Saloon-based client for the Poste Italiane (POST_IT) shipping API.

  • OAuth-style session authentication (POST /user/sessions) with in-memory token caching
  • Waybill creation (POST /postalandlogistics/parcel/waybill) — returns label PDF URL
  • Shipment tracking (POST /postalandlogistics/parcel/tracking) — returns normalised events
  • Typed readonly DTOs for every request and response payload
  • Mockable end-to-end via Saloon's MockClient

Installation

composer require smart-dato/post-it-sdk

The service provider is auto-discovered. Optionally publish the config file:

php artisan vendor:publish --tag=post-it-sdk-config

Configuration

The SDK is credential-free by default — it does not read credentials from config or env. Pass them explicitly when constructing PostIt. The published config file (config/post-it-sdk.php) is provided as a convenience for single-account integrations that want to centralise defaults; multi-tenant applications typically store credentials per CarrierAccount row.

use SmartDato\PostIt\PostIt;

// Production (uses confirmed PRODUCTION_BASE_URL = https://apiw.gp.posteitaliane.it/gp/internet):
$client = PostIt::production(
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret',
    scope: 'shipping',
);

// Or, for a custom base URL (test environment, on-premise, alternate contract):
$client = new PostIt(
    baseUrl: 'https://your-tenant.posteitaliane.it/gp/internet',
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret',
    scope: 'shipping',
    grantType: 'client_credentials',
);

Creating a waybill

use SmartDato\PostIt\Constants\PrintFormat;
use SmartDato\PostIt\Data\AddressData;
use SmartDato\PostIt\Data\DeclarationData;
use SmartDato\PostIt\Data\ServicesData;
use SmartDato\PostIt\Data\WaybillData;
use SmartDato\PostIt\Data\WaybillRequestData;
use SmartDato\PostIt\Enums\PaymentModeEnum;

$response = $client->createWaybill(new WaybillRequestData(
    costCenterCode: 'CC100',
    shipmentDate: new DateTimeImmutable(),
    waybills: [
        new WaybillData(
            clientReferenceId: 'ORDER-123',
            printFormat: PrintFormat::DEFAULT,        // '1011' — 10×11 cm
            product: 'POSTACELERE',
            sender: new AddressData(
                nameSurname: 'Sender Co',
                contactName: 'Mario Rossi',
                address: 'Via Roma',
                streetNumber: '1',
                zipCode: '00100',
                city: 'Roma',
                cellphone: '393331111111',
                phone: '393331111111',
            ),
            receiver: new AddressData(
                nameSurname: 'Receiver Co',
                contactName: 'Luigi Bianchi',
                address: 'Via Milano',
                streetNumber: '2',
                zipCode: '20100',
                city: 'Milano',
                cellphone: '393332222222',
                phone: '393332222222',
            ),
            declared: [
                new DeclarationData(weightGrams: 1500, heightCm: 20, lengthCm: 30, widthCm: 40),
            ],
            services: new ServicesData(
                multicolloCode: 'APT000901',
                codAmount: 50.0,
                codPaymentMode: PaymentModeEnum::CashOnDelivery,
            ),
        ),
    ],
));

$waybillNumber = $response->waybills[0]['code'];
$labelPdfUrl = $response->waybills[0]['downloadURL'];

PostItApiException is thrown when the upstream returns result.errorCode !== 0 or when the response is missing required fields.

Tracking a shipment

$tracking = $client->trackShipment($waybillNumber);

foreach ($tracking->events as $event) {
    echo $event->statusCode.' '.$event->statusDescription.' @ '.$event->location.PHP_EOL;
}

Pass fullHistory: false to receive only the latest tracing state instead of the entire history.

Print formats

printFormat is a free-form string because Poste Italiane accepts contract-specific values:

use SmartDato\PostIt\Constants\PrintFormat;

PrintFormat::A4;          // 'A4'
PrintFormat::FORMAT_1011; // '1011'  (10×11 cm — default)
PrintFormat::ZPL;         // 'ZPL'
PrintFormat::DEFAULT;     // alias of FORMAT_1011

If your account uses a different value, pass it as a raw string.

Testing

The SDK tests itself with Saloon's MockClient. Consumer applications can do the same:

use Saloon\Http\Faking\MockClient;
use Saloon\Http\Faking\MockResponse;
use SmartDato\PostIt\Requests\AuthRequest;
use SmartDato\PostIt\Requests\CreateWaybillRequest;

MockClient::global([
    AuthRequest::class => MockResponse::make(['access_token' => 'fake'], 200),
    CreateWaybillRequest::class => MockResponse::make([
        'costCenterCode' => 'CC',
        'contractCode' => 'CT',
        'waybills' => [['code' => 'WB1', 'downloadURL' => 'https://...']],
    ], 200),
]);

// ... your code that calls $client->createWaybill(...) ...

MockClient::destroyGlobal();

Quality gate

composer test           # pint + phpstan + pest
composer test:lint      # pint --test
composer test:types     # phpstan analyse
composer test:unit      # pest
composer lint           # pint (fix)

License

MIT — see LICENSE.md.