PHP code example of vesselind / econt-integration

1. Go to this page and download the library: Download vesselind/econt-integration library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

vesselind / econt-integration example snippets



declare(strict_types=1);

use Econt\EcontApi\EcontClient;
use Econt\EcontApi\EcontConfiguration;
use Econt\EcontApi\Http\SymfonyHttpAdapter;
use Symfony\Component\HttpClient\HttpClient;

// 1. Configure — use the factory for the demo/test endpoint (credentials pre-filled)
$config = EcontConfiguration::forDemo();

// Or with explicit credentials for production
$config = new EcontConfiguration(
    username: 'your-username',
    password: 'your-password',
    baseUrl: EcontConfiguration::PRODUCTION_URL,
    timeout: 30,
    language: 'bg'  // 'bg' or 'en'
);

// 2. Create adapter + client
$adapter = new SymfonyHttpAdapter(HttpClient::create());
$client  = new EcontClient($config, $adapter);

// 3. Start querying
$countries = $client->address()->getCountries();
foreach ($countries as $country) {
    echo $country->nameEn . PHP_EOL;
}

use Econt\EcontApi\Http\Psr18HttpAdapter;
use Nyholm\Psr7\Factory\Psr17Factory;
use Symfony\Component\HttpClient\Psr18Client;

$psr17Factory = new Psr17Factory();
$adapter = new Psr18HttpAdapter(new Psr18Client(), $psr17Factory, $psr17Factory);
$client  = new EcontClient($config, $adapter);

$addressService = $client->address();

// Countries
$countries = $addressService->getCountries();  // CountryCollection

// Cities for a country
$cities = $addressService->getCities('BGR');   // CityCollection

// Streets for a city (cityID from City model)
$streets = $addressService->getStreets(41);    // StreetCollection

// Quarters for a city
$quarters = $addressService->getQuarters(41); // QuarterCollection

// Validate an address
use Econt\EcontApi\Model\Location\Address;
use Econt\EcontApi\Model\Location\City;
use Econt\EcontApi\Model\Location\Country;

$address = new Address(
    city: City::create(
        country:  Country::bulgaria(),
        postCode: '7000',
        name:     'Русе',
        nameEn:   'Ruse',
    ),
    street: 'Славянска',
    num:    '16',
);

$validated = $addressService->validateAddress($address);
echo $validated->validationStatus; // "normal" | "processed" | "invalid"

$officeService = $client->office();

// All offices / Econtomats in Bulgaria
$offices = $officeService->getOffices(countryCode: 'BGR');

// Offices in a specific city
$offices = $officeService->getOffices(countryCode: 'BGR', cityId: 41);

// Filter only physical offices (exclude Econtomat/APS machines)
$regularOffices = array_filter(
    iterator_to_array($offices),
    fn($o) => !$o->isAPS
);

use Econt\EcontApi\Enum\TariffSubCode;

$label = new ShippingLabel(
    senderClient:       new ClientProfile(name: 'Иван Иванов', phones: ['0888888888']),
    receiverClient:     new ClientProfile(name: 'Богдан Богданов', phones: ['0878787878']),
    packCount:          1,
    shipmentType:       ShipmentType::PACK,
    weight:             2.5,
    senderAddress:      $senderAddress,       // sender's door address
    receiverOfficeCode: '1127',               // Office::getCode() from getOffices()
    tariffSubCode:      TariffSubCode::DOOR_OFFICE,
    shipmentDescription: 'Книги',
);

$result = $client->shipment()->createLabel($label);

$label = new ShippingLabel(
    senderClient:       new ClientProfile(name: 'Иван Иванов', phones: ['0888888888']),
    receiverClient:     new ClientProfile(name: 'Богдан Богданов', phones: ['0878787878']),
    packCount:          1,
    shipmentType:       ShipmentType::PACK,
    weight:             2.5,
    senderOfficeCode:   '1034',               // sender drops off at this office
    receiverOfficeCode: '1127',               // receiver picks up at this office
    tariffSubCode:      TariffSubCode::OFFICE_OFFICE,
    shipmentDescription: 'Книги',
);

$offices = $client->office()->getOffices(countryCode: 'BGR', cityId: 41);
foreach ($offices as $office) {
    echo $office->getCode() . ' — ' . $office->getName() . PHP_EOL;
}

use Econt\EcontApi\Model\Shipment\ShippingLabel;
use Econt\EcontApi\Model\Shipment\ClientProfile;
use Econt\EcontApi\Enum\ShipmentType;

$label = new ShippingLabel(
    senderClient:        new ClientProfile(name: 'Иван Иванов', phones: ['0888888888']),
    senderAddress:       $senderAddress,
    receiverClient:      new ClientProfile(name: 'Богдан Богданов', phones: ['0878787878']),
    receiverAddress:     $receiverAddress,
    packCount:           1,
    shipmentType:        ShipmentType::PACK,
    weight:              2.5,
    shipmentDescription: 'Книги',
    mode:                'calculate',
);

$price = $client->shipment()->calculatePrice($label);
echo $price->totalPrice . ' ' . $price->currency; // e.g. "7.32 BGN"

// Create
$label->mode = 'create';
$created = $client->shipment()->createLabel($label);
echo $created->waybillNumber;  // e.g. "1234567890"

// Cancel
$client->shipment()->cancelLabel($created->waybillNumber);

// Confirm a label (after creation)
$client->shipment()->confirmLabel($waybillNumber);

// Update a label
$label->weight = 3.0;
$client->shipment()->updateLabel($label);

// Request courier pickup
use Econt\EcontApi\Model\Shipment\CourierRequest;

$request = new CourierRequest(
    shipmentWaybillNumber:  $waybillNumber,
    requestCourierTimeFrom: '09:00',
    requestCourierTimeTo:   '12:00',
);
$client->shipment()->requestCourier($request);

$bg = Country::bulgaria();  // BG / BGR
$ro = Country::romania();   // RO / ROU
$gr = Country::greece();    // GR / GRC

// Generic factory for any other country (id defaults to null)
$de = Country::create(code2: 'DE', code3: 'DEU', nameEn: 'Germany');

$city = City::create(country: Country::bulgaria(), postCode: '1000', name: 'София', nameEn: 'Sofia');

use Econt\EcontApi\Enum\ShipmentType;
// PACK, DOCUMENT, PALLET, CARGO, FURNITURE, ...

use Econt\EcontApi\Enum\TariffSubCode;
// OFFICE_TO_OFFICE, OFFICE_TO_DOOR, DOOR_TO_OFFICE, DOOR_TO_DOOR

$country = Country::fromArray([
    'code2'  => 'BG',
    'code3'  => 'BGR',
    'name'   => 'България',
    'nameEn' => 'Bulgaria',
]);

$array = $country->toArray();
// ['code2' => 'BG', 'code3' => 'BGR', 'name' => 'България', 'nameEn' => 'Bulgaria']

use Econt\EcontApi\Exception\EcontException;
use Econt\EcontApi\Exception\EcontApiException;
use Econt\EcontApi\Exception\EcontNetworkException;
use Econt\EcontApi\Exception\EcontValidationException;

try {
    $offices = $client->office()->getOffices('BGR', 41);
} catch (EcontValidationException $e) {
    // Invalid input before any HTTP call is made
    echo implode(', ', $e->getViolations());
} catch (EcontApiException $e) {
    // API returned an error response
    echo $e->getApiErrorCode() . ': ' . $e->getApiErrorMessage();
} catch (EcontNetworkException $e) {
    // HTTP transport failure
    echo 'Network error: ' . $e->getMessage();
} catch (EcontException $e) {
    // Base catch-all for all library exceptions
}

// Factory method for the demo/test endpoint (official demo credentials pre-filled)
$config = EcontConfiguration::forDemo();

// Override language or timeout while still targeting demo
$config = EcontConfiguration::forDemo(language: 'bg', timeout: 10);

// Full constructor for production
$config = new EcontConfiguration(
    username: 'your-username',
    password: 'your-password',
    baseUrl:  EcontConfiguration::PRODUCTION_URL,
    timeout:  30,
    language: 'bg'  // 'bg' (Bulgarian) or 'en' (English)
);

src/
├── EcontClient.php             # Main entry point
├── EcontConfiguration.php      # Configuration (URL, credentials, language)
├── Collection/                 # Typed iterable collections (CountryCollection, etc.)
├── Enum/
│   ├── ShipmentType.php
│   └── TariffSubCode.php
├── Exception/
│   ├── EcontException.php      # Base exception
│   ├── EcontApiException.php
│   ├── EcontNetworkException.php
│   └── EcontValidationException.php
├── Http/
│   ├── HttpAdapterInterface.php
│   ├── SymfonyHttpAdapter.php  # Default adapter
│   └── Psr18HttpAdapter.php    # PSR-18 adapter
├── Model/
│   ├── Location/               # Country, City, Street, Quarter, Address, ValidatedAddress
│   ├── Office/                 # Office
│   ├── Result/                 # PriceResult
│   └── Shipment/               # ShippingLabel, ClientProfile, CourierRequest, etc.
└── Service/
    ├── AddressService.php
    ├── OfficeService.php
    └── ShipmentService.php

tests/
├── Unit/                       # Mocked unit tests (64 tests)
└── Integration/                # Live API tests (