tudor / gls-api-php
MyGLS API PHP client for system integration
v1.0.1
2026-05-26 18:19 UTC
Requires
- php: >=8.4
Requires (Dev)
- phpunit/phpunit: ^11.0
README
PHP 8.4+ client for the MyGLS API (v25.12.11) — label printing, parcel tracking, master data.
Supports 7 countries, all GLS service codes (incl. MMP, SHD), and ships with a Laravel service provider.
Installation
composer require tudor/gls-api-php
Requires PHP >= 8.4.
Quick start
use Gls\Api\GLSClient; use Gls\Api\Enums\Country; use Gls\Api\Enums\TypeOfPrinter; use Gls\Api\Enums\ServiceCode; use Gls\Api\Models\Address; use Gls\Api\Models\Service; $gls = new GLSClient( username: 'you@example.com', password: 'secret', country: Country::HUNGARY, testMode: true, ); $pickup = new Address('My Company', 'Fő utca', '42', 'Budapest', '1132', 'HU'); $delivery = (new Address('Customer', 'Kossuth utca', '10', 'Debrecen', '4024', 'HU')) ->withContact('John', '+36209876543', 'john@email.com'); $parcel = $gls->parcel(123456, $pickup, $delivery) ->setClientReference('ORDER-001') ->setContent('Clothing') ->addService(Service::simple(ServiceCode::T12)); $response = $gls->printLabels([$parcel], typeOfPrinter: TypeOfPrinter::A4_2x2); if ($response->isSuccessful()) { file_put_contents('labels.pdf', $response->getLabelsBytes()); foreach ($response->getPrintLabelsInfoList() as $info) { echo "Parcel: {$info->getParcelNumber()}\n"; } }
Laravel
php artisan vendor:publish --tag=gls-config
.env:
GLS_USERNAME=you@example.com
GLS_PASSWORD=secret
GLS_COUNTRY_CODE=HU
GLS_TEST_MODE=true
$gls = app(\Gls\Api\GLSClient::class); // or app('gls')
Countries
| Country | Enum | Test | Production |
|---|---|---|---|
| Croatia | Country::CROATIA |
api.test.mygls.hr |
api.mygls.hr |
| Czechia | Country::CZECHIA |
api.test.mygls.cz |
api.mygls.cz |
| Hungary | Country::HUNGARY |
api.test.mygls.hu |
api.mygls.hu |
| Romania | Country::ROMANIA |
api.test.mygls.ro |
api.mygls.ro |
| Slovenia | Country::SLOVENIA |
api.test.mygls.si |
api.mygls.si |
| Slovakia | Country::SLOVAKIA |
api.test.mygls.sk |
api.mygls.sk |
| Serbia | Country::SERBIA |
api.test.mygls.rs |
api.mygls.rs |
Switch country (clones, does not mutate):
$glsCz = $gls->withCountry(Country::CZECHIA)->withTestMode(false);
API methods
Parcel service
| Method | Description |
|---|---|
prepareLabels($parcels) |
Validate + persist |
prepareLabelsV2($parcels) |
Same, improved internals |
getPrintedLabels($ids, $printer) |
PDF from existing IDs |
getPrintData($parcelIds, $parcels) |
Printed package info |
printLabels($parcels) |
Prepare + Print in one call |
printLabelsV2($parcels) |
Versioned PrintLabels_20251022 (PIN support) |
deleteLabels($parcelIds) |
Soft delete (capped at 50 IDs/request) |
modifyCOD($amount, $id, $number) |
Change COD amount |
getParcelList(...) |
Parcels by date range |
getParcelStatuses($number) |
Status history + optional POD |
getParcelListStatuses($numbers) |
Statuses for multiple parcels |
Master data
| Method | Description |
|---|---|
getDeliveryPoints($country, $lastUpdate) |
ParcelShops, Lockers, Depots (GZIP-compressed) |
getLocations($country, $lastUpdate) |
Depots, hubs, routing |
Services & parameters
Use Gls\Api\Enums\ServiceCode. GLS expects each parameter under the JSON key {Code}Parameter (e.g. ADRParameter, INSParameter) — the Service class produces this format automatically.
use Gls\Api\Models\ServiceParameters as P; $parcel ->addService(Service::simple(ServiceCode::T12)) ->addService(Service::withParameter(ServiceCode::INS, new P\ServiceParameterDecimal(50000))) ->addService(Service::withParameter(ServiceCode::PSD, new P\ServiceParameterStringInteger('2351-CSOMAGPONT'))) ->addService(Service::withParameter(ServiceCode::SDS, P\ServiceParameterTimeRange::fromDates( new DateTimeImmutable('2026-05-27 12:00:00'), new DateTimeImmutable('2026-05-27 16:00:00') )));
| Code | Name | Parameter |
|---|---|---|
H24 (24H) |
24 Hour delivery | — |
ADR |
Dangerous goods | ServiceParameterADR(...) |
AOS |
Addressee Only | ServiceParameterString(name) |
COD |
Cash on Delivery | use $parcel->setCod() |
CS1 |
Contact Service | ServiceParameterString(phone) |
DDS |
Day Definite | ServiceParameterDateTime(date) |
DPV |
Declared Parcel Value | ServiceParameterStringDecimal(str, dec) |
FDS |
Flexible Delivery | ServiceParameterString(email) |
FSS |
Flexible SMS | ServiceParameterString(phone) — requires FDS |
INS |
Insurance | ServiceParameterDecimal(value) |
LRS |
Locker Return | $parcel->setPickupType(2) — HU only |
MMP |
Multi-parcel | ServiceParameterDecimal(value) |
PRS |
Pick & Return | — requires DeliveryAddress.ContactPhone |
PSD |
Parcel Shop Delivery | ServiceParameterStringInteger(psdId) |
PSS |
Pick & Ship | — requires DeliveryAddress.ContactPhone |
SAT |
Saturday | Service::withValue(ServiceCode::SAT, phone) |
SDS |
Scheduled Delivery | ServiceParameterTimeRange(from, to) |
SHD |
Shop Home Delivery | enables Parcel::setFinalDeliveryAddress() |
SM1 |
SMS | ServiceParameterString("phone|text") |
SM2 |
SMS pre-advice | ServiceParameterString(phone) |
SRS |
Shop Return | — HU, SI only |
SZL |
Document Return | ServiceParameterString(docId) — max 15 chars |
T09 / T10 / T12 |
Express | — |
TGS |
Think Green | — |
XS |
Exchange | — |
Parcel::validate() (called automatically during JSON serialization) enforces:
- PRS/PSS require
DeliveryAddress.ContactPhone Countmust be 1–99deleteLabels()is capped at 50 IDs per request (enforced inDeleteLabelsRequest)
Printer types
TypeOfPrinter::A4_2x2 // 4 labels per A4 page TypeOfPrinter::A4_4x1 // 4 labels in a row TypeOfPrinter::CONNECT TypeOfPrinter::THERMO TypeOfPrinter::THERMO_ZPL // 203 DPI TypeOfPrinter::THERMO_ZPL_300DPI TypeOfPrinter::SHIP_IT_THERMO_PDF TypeOfPrinter::SHIP_IT_THERMO_ZPL
Parcel dimensions
use Gls\Api\Models\ParcelProperty; use Gls\Api\Enums\PackageType; $parcel->addParcelProperty(new ParcelProperty( content: 'Clothing items', packageType: PackageType::BOX, height: 20, length: 30, width: 40, weight: 2.5, ));
Tracking
$response = $gls->getParcelStatuses(12345678901, returnPOD: true); foreach ($response->getParcelStatusList() as $status) { echo $status->getStatusDate()->format('Y-m-d H:i') . ': ' . $status->getStatusDescription() . "\n"; } if ($podBytes = $response->getPodBytes()) { file_put_contents('pod.pdf', $podBytes); }
Master data (incremental updates)
$response = $gls->getDeliveryPoints(country: Country::HUNGARY); $lastUpdate = $response->getLastUpdateTime(); $response = $gls->getDeliveryPoints(country: Country::HUNGARY, lastUpdateTime: $lastUpdate); if ($response->getIsChanged()) { $deliveryPoints = $response->getData(); $lastUpdate = $response->getLastUpdateTime(); }
Error handling
All responses expose isSuccessful(). Per-call errors are typed; transport-level failures throw Gls\Api\Exceptions\GLSException.
if (!$response->isSuccessful()) { foreach ($response->getPrintLabelsErrorList() as $error) { echo "Error {$error->getErrorCode()}: {$error->getErrorDescription()}\n"; } }
Tests
composer install vendor/bin/phpunit
License
MIT