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
Requires
- php: >=8.3.0
- guzzlehttp/guzzle: ^7.8 || ^7.7
- psr/log: ^3.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.40
- phpstan/phpstan: ^2.0 || ^1.10
- phpunit/phpunit: ^11.0 || ^10.5
This package is auto-updated.
Last update: 2025-12-22 15:18:57 UTC
README
An Ukrposhta PHP SDK based on the official Ukrposhta API.
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();