tibezh/ukrposhta-php-sdk

Contains integration with Ukrposhta service.

Installs: 26

Dependents: 0

Suggesters: 0

Security: 0

Stars: 3

Watchers: 2

Forks: 0

Open Issues: 0

pkg:composer/tibezh/ukrposhta-php-sdk

0.1.2 2025-12-22 15:15 UTC

This package is auto-updated.

Last update: 2025-12-22 15:18:57 UTC


README

Ukrposhta PHP SDK logo

An Ukrposhta PHP SDK based on the official Ukrposhta API.

Minimum PHP Version License CI codecov Latest Stable Version

Table of Contents

Requirements

This library uses PHP 8.3+.

To use the Ukrposhta API, you need to have Bearer and Token for each API sub-portal (eCom, StatusTracking and AddressClassifier). After signing the contract, the bearer and token are issued by your manager. You can find more information here.

Available Features

  • Status Tracking - available.
  • Address Classifier (counterparty) - available.
  • Shipments - planned.

Installation

To get started, simply require the project using Composer.

composer require tibezh/ukrposhta-php-sdk

Configuration

Retry Configuration

The SDK includes automatic retry logic for transient network errors (connection timeouts, DNS failures, etc.) with exponential backoff and jitter.

Default settings:

  • Max retries: 3 attempts
  • Base delay: 100ms (with exponential backoff: 100ms, 200ms, 400ms...)

You can customize retry behavior when creating a custom Request object:

use Ukrposhta\Request\Request;
use Ukrposhta\Tracking\Tracking;

// Create a custom request with retry settings.
$request = new Request(
    logger: null,       // Optional PSR-3 logger
    maxRetries: 5,      // Max retry attempts (default: 3)
    retryDelayMs: 200   // Base delay in milliseconds (default: 100)
);

// Use the custom request with Tracking.
$tracking = new Tracking(
    bearerStatusTracking: '[BEARER-TOKEN]',
    request: $request
);

To disable retries, set maxRetries to 0:

$request = new Request(logger: null, maxRetries: 0);

Logging

The SDK supports PSR-3 logging. Pass any PSR-3 compatible logger to track API requests and responses:

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Ukrposhta\Tracking\Tracking;

$logger = new Logger('ukrposhta');
$logger->pushHandler(new StreamHandler('path/to/ukrposhta.log', Logger::DEBUG));

$tracking = new Tracking(
    bearerStatusTracking: '[BEARER-TOKEN]',
    logger: $logger
);

Examples

Status Tracking

Request last status by barcode:

/** @var \Ukrposhta\Tracking\Entities\TrackingStatusInterface $barcodeLastStatus */
$barcodeLastStatus = (new \Ukrposhta\Tracking\Tracking())
  ->setAccessToken('[BEARER-STATUS-TRACKING-ACCESS-TOKEN]')
  // To get results in English:
  // ->setRequestLang('EN')
  ->requestBarcodeLastStatus('[BARCODE]');

// Prints event name value of the last status for the given barcode.
print $barcodeLastStatus->getEventName();

Request all statuses by barcode:

/** @var \Ukrposhta\Tracking\Entities\TrackingStatusCollectionInterface $barcodeStatuses */
$barcodeStatuses = (new \Ukrposhta\Tracking\Tracking())
  ->setAccessToken('[BEARER-STATUS-TRACKING-ACCESS-TOKEN]')
  // To get results in English:
  // ->setRequestLang('EN')
  ->requestBarcodeStatuses('[BARCODE]');

// Prints "[date]: [eventName]" of each status for the given barcode.
foreach ($barcodeStatuses as $status) {
  print $status->getDate()->format('c') . ': ' . $status->getEventName();
  print '<br>';
}

Request route by barcode:

/** @var \Ukrposhta\Tracking\Entities\TrackingRouteInterface $barcodeRoute */
$barcodeRoute = (new \Ukrposhta\Tracking\Tracking())
  ->setAccessToken('[BEARER-STATUS-TRACKING-ACCESS-TOKEN]')
  // To get results in English:
  // ->setRequestLang('EN')
  ->requestBarcodeRoute('[BARCODE]');

// Prints "[from] -> [to]" information for the given barcode.
print $barcodeRoute->getFrom() . ' -> ' . $barcodeRoute->getTo();

Address Classifier

The Address Classifier API allows you to search regions, districts, cities, streets, post offices and more.

Request regions:

use Ukrposhta\AddressClassifier\AddressClassifier;
use Ukrposhta\Utilities\Languages\LanguagesEnum;

$classifier = new AddressClassifier(
    bearerCounterparty: '[BEARER-COUNTERPARTY-ACCESS-TOKEN]'
);

/** @var \Ukrposhta\AddressClassifier\Entities\Region\RegionCollectionInterface $regions */
$regions = $classifier->requestRegions('Київ');

foreach ($regions->all() as $region) {
    print $region->getId() . ': ' . $region->getName();
    print '<br>';
}

Request districts by region ID:

/** @var \Ukrposhta\AddressClassifier\Entities\District\DistrictCollectionInterface $districts */
$districts = $classifier->requestDistrictsByRegionId(regionId: 1);

foreach ($districts->all() as $district) {
    print $district->getId() . ': ' . $district->getName();
    print '<br>';
}

Request cities by region ID and district ID:

/** @var \Ukrposhta\AddressClassifier\Entities\City\CityCollectionInterface $cities */
$cities = $classifier->requestCityByRegionIdAndDistrictId(
    regionId: 1,
    districtId: 5,
    nameUa: 'Бориспіль'
);

foreach ($cities->all() as $city) {
    print $city->getId() . ': ' . $city->getName()->getByLanguage(LanguagesEnum::UA);
    print '<br>';
}

Request streets by city ID:

/** @var \Ukrposhta\AddressClassifier\Entities\Street\StreetCollectionInterface $streets */
$streets = $classifier->requestStreetByRegionIdAndDistrictIdAndCityId(
    regionId: 1,
    districtId: 5,
    cityId: 100,
    nameUa: 'Головна'
);

foreach ($streets->all() as $street) {
    print $street->getId() . ': ' . $street->getName()->getByLanguage(LanguagesEnum::UA);
    print '<br>';
}

Request post offices by city ID:

/** @var \Ukrposhta\AddressClassifier\Entities\PostOffice\PostOfficeCollectionInterface $postOffices */
$postOffices = $classifier->requestPostOfficeByCityId(cityId: 100);

foreach ($postOffices->all() as $postOffice) {
    print $postOffice->getPostIndex() . ': ' . $postOffice->getName()->getByLanguage(LanguagesEnum::UA);
    print '<br>';
}

Request nearest post offices by geolocation:

/** @var \Ukrposhta\AddressClassifier\Entities\NearestPostOffice\NearestPostOfficeCollectionInterface $nearestPostOffices */
$nearestPostOffices = $classifier->requestNearestPostOffices(
    latitude: 50.4501,
    longitude: 30.5234,
    maxDistance: 1000 // meters
);

foreach ($nearestPostOffices->all() as $postOffice) {
    print $postOffice->getFilialName() . ' - ' . $postOffice->getDistance() . ' m';
    print '<br>';
}

Fuzzy search for cities:

/** @var \Ukrposhta\AddressClassifier\Entities\CitySearchItem\CitySearchItemCollectionInterface $cities */
$cities = $classifier->requestSearchCity(
    regionId: 1,
    districtId: 5,
    cityName: 'Борис', // partial name
    language: LanguagesEnum::UA,
    fuzzy: true
);

foreach ($cities->all() as $city) {
    print $city->getName() . ' (' . $city->getTypeName() . ')';
    print '<br>';
}

Working with Collections

All collection classes implement Countable and IteratorAggregate/Iterator interfaces, allowing you to:

// Get count of items.
$count = count($regions);
// Or use the count() method.
$count = $regions->count();

// Check if collection is empty.
if ($regions->isEmpty()) {
    echo 'No regions found';
}

// Iterate directly with foreach.
foreach ($regions as $region) {
    echo $region->getName();
}

// Get all items as array.
$allRegions = $regions->all();