PHPackages                             ages/shipping-gateway - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. ages/shipping-gateway

ActiveLibrary[API Development](/categories/api)

ages/shipping-gateway
=====================

Unified shipping carrier API for CzechPost, GLS, PPL

1.0.0(1mo ago)050↓100%PHPPHP &gt;=8.4

Since Apr 27Pushed 6d agoCompare

[ Source](https://github.com/A-g-e-s/shipping-gateway)[ Packagist](https://packagist.org/packages/ages/shipping-gateway)[ RSS](/packages/ages-shipping-gateway/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (4)Versions (2)Used By (0)

ages/shipping-gateway
=====================

[](#agesshipping-gateway)

Unified PHP library for shipping carrier integrations — **GLS**, **PPL**, **Czech Post**, **Gebrüder Weiss**.
Single entry point, config-driven credentials and pickup address, compatible with Nette + Nextras.

---

API Documentation
-----------------

[](#api-documentation)

DopravceOdkazGLS[https://api.mygls.hu/index\_cz.html](https://api.mygls.hu/index_cz.html)PPLČeská poštaGebrüder Weiss---

Requirements
------------

[](#requirements)

- PHP 8.4+
- Nette Utils `^4.0`
- Guzzle `^7.9`
- mPDF `^8.3`

---

Installation
------------

[](#installation)

```
composer require ages/shipping-gateway
```

Or add a path repository for local development:

```
{
    "repositories": [
        {
            "type": "path",
            "url": "../shipping-gateway"
        }
    ],
    "require": {
        "ages/shipping-gateway": "*"
    }
}
```

---

Configuration (Nette / neon)
----------------------------

[](#configuration-nette--neon)

All credentials and pickup address are configured in `config.neon` — nothing is hardcoded.

```
services:
    pickupAddress: Ages\ShippingGateway\Common\PickupAddress(
        name: 'MyShop s.r.o.'
        street: Ulice
        city: Město
        zip: '12345'
        country: CZ
        phone: '+420 123 456 789'
        email: 'info@myshop.cz'
        houseNumber: '10'
        # company: 'my-company-code'   # volitelne, pouziva se jen pro GW tracking URL
    )

    glsConfig: Ages\ShippingGateway\Gls\Config\GlsConfig(
        username: 'user@example.com'
        password: secret
        clientNumber: 12345678
        pickupAddress: @pickupAddress
        # url: https://api.test.mygls.cz/ParcelService.svc/json/   # test endpoint
    )

    pplConfig: Ages\ShippingGateway\Ppl\Config\PplConfig(
        clientId: CLIENT_ID
        clientSecret: CLIENT_SECRET
        pickupAddress: @pickupAddress
        # url: https://api-dev.dhl.com/ecs/ppl/myapi2/             # test endpoint
    )

    czechPostConfig: Ages\ShippingGateway\CzechPost\Config\CzechPostConfig(
        apiToken: api-token-here
        secretKey: secret-key-here
        idContract: 123456789
        customerId: L12345
        postCode: '53307'
        locationNumber: 1
        certificatePath: %wwwDir%/cert/postsignum-bundle.pem
        # packageLimit: 5
    )

    gwConfig: Ages\ShippingGateway\GebruderWeiss\Config\GebruderWeissConfig(
        clientId: CLIENT_ID
        clientSecret: CLIENT_SECRET
        customerId: 12345
        branchCode: PRG
        pickupAddress: @pickupAddress
        ssccPrefix: '22260000'          # číselný prefix pro generování SSCC kódů
        # product: GW_PRO_LINE
        # incoterm: DAP
        # goodsDescription: Goods
        # logoPath: %wwwDir%/img/logo-gw.png   # čtvercové logo na etiketu (volitelné)
    )

    - Ages\ShippingGateway\ShippingGateway
```

> **Certifikát České pošty** (`postsignum-bundle.pem`) je třeba umístit ručně do projektu.
> Cesta se nastavuje přes `certificatePath` — nikdy se nekopíruje do balíčku.

> **Gebrüder Weiss — `clientId` / `clientSecret`** odpovídají hodnotám **Consumer Key** a **Consumer Secret** z portálu `developer.my.gw-world.com` (záložka vaší aplikace po subscribe na API).
> Je třeba mít subscribe na obě API: `TRANSPORT_ORDER_CREATE` i `TRACKNTRACE`.

> **Gebrüder Weiss — `ssccPrefix`** je povinný číselný řetězec (doporučeno 6–10 číslic) sloužící jako základ pro automatické generování SSCC kódů (18 číslic dle GS1).
> Podpora jej sdělí nebo si zvolte vlastní firemní prefix, např. `22260000`.
> Volitelný `logoPath` přijímá absolutní cestu k obrázku — ten se zobrazí v levém horním rohu štítku ve čtvercové oblasti cca 24 × 24 mm.

---

Usage
-----

[](#usage)

### Unified shipment creation

[](#unified-shipment-creation)

Předáš `ShipmentRequest`, označíš dopravce a dostaneš `ShipmentLabel[]` — jeden štítek per balík.

```
use Ages\ShippingGateway\Common\Carrier;
use Ages\ShippingGateway\Common\Shipment\CashOnDelivery;
use Ages\ShippingGateway\Common\Shipment\Parcel;
use Ages\ShippingGateway\Common\Shipment\RecipientAddress;
use Ages\ShippingGateway\Common\Shipment\ShipmentRequest;
use Ages\ShippingGateway\Common\Shipment\ShipmentValue;

$request = new ShipmentRequest(
    reference: '2025-00123',
    recipient: RecipientAddress::fromFullName(
        name: 'Jan Novák',
        street: 'Hlavní',
        houseNumber: '42',
        city: 'Praha',
        zip: '10000',
        country: 'CZ',
        phone: '+420600123456',
        email: 'jan@example.com',
    ),
    parcels: [
        new Parcel(weight: 2.5),
        new Parcel(weight: 1.8),
    ],
    value: new ShipmentValue(amount: 1490.0),
    cod: new CashOnDelivery(amount: 1490.0, variableSymbol: '2025001'),
    note: 'Poznámka pro přepravu',
    // Pro výdejní místa:
    // parcelShopCode: 'B69623',
    // parcelShopZip: '69623', // u České pošty explicitně PSČ provozovny
);

/** @var \Ages\ShippingGateway\ShippingGateway $gateway */
$labels = $gateway->createShipment(Carrier::Gls, $request);

foreach ($labels as $label) {
    echo $label->trackingNumber;             // číslo zásilky
    file_put_contents('label.pdf', $label->labelPdf); // raw PDF bytes
}
```

Dostupné hodnoty `Carrier`: `Carrier::Gls`, `Carrier::Ppl`, `Carrier::CzechPost`, `Carrier::GebruderWeiss`.

---

#### RecipientAddress

[](#recipientaddress)

```
// Ze jména — rozdělí podle první mezery (Jan / Novák)
RecipientAddress::fromFullName('Jan Novák', $street, $city, $zip, $country, $phone, $email);

// Nebo přímo s firstName / lastName
new RecipientAddress(
    firstName: 'Jan',
    lastName: 'Novák',
    street: 'Hlavní',
    city: 'Praha',
    zip: '10000',
    country: 'CZ',
    phone: '+420600123456',
    email: 'jan@example.com',
    company: 'Firma s.r.o.',      // volitelné
    houseNumber: '42',            // volitelné
    type: RecipientType::Company, // Person (výchozí) nebo Company
);
```

---

#### Parcel — typy zásilek

[](#parcel--typy-zásilek)

```
use Ages\ShippingGateway\Common\Shipment\Dimensions;
use Ages\ShippingGateway\Common\Shipment\ParcelType;

new Parcel(weight: 2.5);                                         // standardní balík
new Parcel(weight: 15.0, type: ParcelType::PackageOversize);     // neskladný / atypický
new Parcel(weight: 80.0, type: ParcelType::PalletEur);           // EUR paleta (GebrüderWeiss)
new Parcel(weight: 60.0, type: ParcelType::PalletOneWay);        // jednorázová paleta
new Parcel(weight: 50.0, type: ParcelType::PalletHalf);          // půl paleta
new Parcel(weight: 40.0, type: ParcelType::PalletCustom);        // vlastní paleta

// S rozměry — hodnoty v cm; u Gebrüder Weiss se odesílají jako metry (automatická konverze ÷ 100)
new Parcel(weight: 5.0, dimensions: new Dimensions(60, 40, 30));
```

> Palety jsou podporovány **pouze přes Gebrüder Weiss**.
> GLS a PPL paletové typy nepodporují — handler vyhodí `InvalidArgumentException`.
> Česká pošta podporuje `Package` a `PackageOversize` (neskladná zásilka, služba 10), palety nepodporuje.

---

#### ShipmentLabel — výstup

[](#shipmentlabel--výstup)

```
$label->carrier;        // Carrier::Gls | Carrier::Ppl | Carrier::CzechPost
$label->trackingNumber; // číslo zásilky pro sledování
$label->labelPdf;       // raw PDF bytes — ulož nebo pošli do prohlížeče

// Uložení štítku
file_put_contents('/path/to/' . $label->trackingNumber . '.pdf', $label->labelPdf);

// Sledování zásilky (po doručení)
$tracking = $gateway->tracking($label->carrier, $label->trackingNumber);
```

> **Více balíků — GLS / PPL / Czech Post:** API vrátí jeden kombinovaný PDF soubor pro všechny balíky.
> Každý `ShipmentLabel` má svůj `trackingNumber`, `labelPdf` je u všech shodné (kombinovaný tisk).
>
> **Více balíků — Gebrüder Weiss:** každý balík dostane vlastní SSCC kód v etiketě a samostatné PDF etiket.
> `ShipmentLabel[]` má tolik prvků, kolik je zásilek — pro tracking mají všechny stejný `trackingNumber` (`reference` / `orderId`), `labelPdf` je u prvního prvku a SSCC zůstává součástí etikety.

---

### Unified tracking

[](#unified-tracking)

```
$tracking = $gateway->tracking(Carrier::Gls, '1234567890');
$tracking = $gateway->tracking(Carrier::Ppl, 'KEA12345678');
$tracking = $gateway->tracking(Carrier::CzechPost, 'DR123456789CZ');
$tracking = $gateway->tracking(Carrier::GebruderWeiss, 'ORDER-2026-001'); // reference zásilky / orderId

$trackingUrl = $gateway->trackingUrl(Carrier::Gls, '1234567890');
$trackingUrl = $gateway->trackingUrl(Carrier::Ppl, 'KEA12345678');
$trackingUrl = $gateway->trackingUrl(Carrier::CzechPost, 'DR123456789CZ');
$trackingUrl = $gateway->trackingUrl(Carrier::GebruderWeiss, 'ORDER-2026-001');

// GW public tracking deep-link needs pickupAddress.company in config.
// PPL public tracking URL uses ?shipmentId={trackingNumber}.

if ($tracking !== null) {
    $tracking->getDelivered();           // bool
    $tracking->getDeliveredDate();       // ?DateTimeImmutable
    $tracking->getWeight();              // float (kg)
    $tracking->getParcelNumber();        // string
    $tracking->getDeliveryCountryCode(); // string (ISO)

    foreach ($tracking->getParcelStatuses() as $status) {
        $status->getStatusDate();        // ?DateTimeImmutable
        $status->getStatusDescription(); // string
        $status->getCustomInfo();        // ?string
        $status->getDelivered();         // bool
        $status->getDamaged();           // bool
    }
}
```

> `trackingUrl()` vrací veřejnou stránku sledování dopravce.
> U GLS a České pošty je URL předvyplněná číslem zásilky, u PPL a Gebrüder Weiss vede na jejich oficiální tracking stránku.

> **Gebrüder Weiss:** tracking probíhá přes reference/orderId vrácené v `$label->trackingNumber`.
> API vrací aktuální stav zásilky; `null` znamená, že zásilka ještě není v systému GBW (zpoždění po odeslání objednávky).

---

---

Extending in your project
-------------------------

[](#extending-in-your-project)

Balíček obsahuje API vrstvu (HTTP komunikace, entity, config) a unified shipment handlery.
Aplikační logika — mapování objednávky/faktury na zásilku, ukládání do DB — patří do projektu.

### GLS — příklad rozšíření

[](#gls--příklad-rozšíření)

```
namespace App\Api\Gls;

use Ages\ShippingGateway\Gls\GlsApi;
use Ages\ShippingGateway\Gls\Entity\ParcelEntity;
use Ages\ShippingGateway\Gls\Entity\ServiceEntity;

class Gls extends GlsApi
{
    const string Carrier = 'GLS';
    const string TrackUrl = 'https://gls-group.eu/CZ/cs/sledovani-zasilek/?match=';

    public function createConsignmentFromInvoice(Invoice $invoice): ?Consignment
    {
        $services = ServiceEntity::of();
        if ($invoice->cashOnDelivery) {
            $services->addServiceCOD($invoice->priceTax, $invoice->variableSymbol, $invoice->currencyIso);
        }

        $parcel = ParcelEntity::of(
            strval($this->config->clientNumber),
            $invoice->code,
            $invoice->packageQty,
            $this->getPickupAddress(),  // z configu
            $deliveryAddress,
            $services,
        );

        $data = $this->printLabels($parcel);
        // $data->PrintLabelsInfoList[0]->ParcelNumber  ← tracking number
        // implode(array_map('chr', $data->Labels))     ← PDF bytes
    }
}
```

### PPL — příklad rozšíření

[](#ppl--příklad-rozšíření)

```
namespace App\Api\Ppl;

use Ages\ShippingGateway\Ppl\PplApi;

class Ppl extends PplApi
{
    public function createConsignmentFromInvoice(Invoice $invoice): ?Consignment
    {
        $parcel = ParcelEntity::of(
            $invoice->code,
            $invoice->packageQty,
            $this->getPickupAddress(),
            $deliveryAddress,
            SpecificDeliveryEntity::of($psdCode),
            $cod,
        );

        $batchId = $this->createBatch($parcel);
        $status  = $this->getStatus($batchId);   // poll dokud není Complete
        // $status->items[0]->shipmentNumber      ← tracking number
        // $status->completeLabel->labelUrls[0]   ← URL štítku → getLabel($url)
    }
}
```

### Czech Post — příklad rozšíření

[](#czech-post--příklad-rozšíření)

```
namespace App\Api\CzechPost;

use Ages\ShippingGateway\CzechPost\CzechPostApi;

class CzechPost extends CzechPostApi
{
    public function createConsignmentFromInvoice(Invoice $invoice): ?Consignment
    {
        $header = $this->prepareParcelServiceHeader(); // z configu

        $res = $this->parcelService($header, $consignmentEntity->toArray(), $multipart);

        // $res['responseHeader']['resultHeader']['responseCode'] === 1  ← úspěch
        // $res['responseHeader']['resultParcelData'][n]['parcelCode']   ← tracking number
        // $res['responseHeader']['responsePrintParams']['file']         ← base64 PDF
    }
}
```

---

Architecture overview
---------------------

[](#architecture-overview)

```
src/
├── ShippingGateway.php               ← facade: tracking() + createShipment()
├── Common/
│   ├── Carrier.php                   ← enum: Gls | Ppl | CzechPost | GebruderWeiss
│   ├── CarrierInterface.php
│   ├── ShipmentHandlerInterface.php  ← createShipment(ShipmentRequest): ShipmentLabel[]
│   ├── ParcelTrackingInterface.php
│   ├── ParcelStatusInterface.php
│   ├── PickupAddress.php
│   ├── ShippingException.php
│   └── Shipment/
│       ├── ShipmentRequest.php       ← vstupní DTO
│       ├── ShipmentLabel.php         ← výstupní DTO (carrier, trackingNumber, labelPdf)
│       ├── RecipientAddress.php      ← fromFullName() factory
│       ├── Parcel.php                ← weight, type, dimensions
│       ├── Dimensions.php
│       ├── ShipmentValue.php
│       ├── CashOnDelivery.php
│       ├── ParcelType.php            ← Package | PackageOversize | PalletEur | ...
│       └── RecipientType.php         ← Person | Company
├── Gls/
│   ├── Config/GlsConfig.php
│   ├── GlsApi.php
│   ├── Handler/GlsShipmentHandler.php
│   └── Entity/ Values/
├── Ppl/
│   ├── Config/PplConfig.php
│   ├── PplApi.php
│   ├── Handler/PplShipmentHandler.php
│   └── Entity/ Values/
├── CzechPost/
│   ├── Config/CzechPostConfig.php
│   ├── CzechPostApi.php
│   ├── CzechPostException.php
│   ├── Handler/CzechPostShipmentHandler.php
│   └── Entity/ Values/
└── GebruderWeiss/
    ├── Config/GebruderWeissConfig.php
    ├── GebruderWeissApi.php
    ├── Handler/GebruderWeissShipmentHandler.php
    ├── Label/GebruderWeissLabelGenerator.php  ← mPDF etiketa 100×150 mm
    └── Tracking/
        ├── GbwParcelTracking.php
        └── GbwParcelStatus.php

```

**Co je v balíčku:** HTTP komunikace, entity, config, unified tracking, unified shipment creation.
**Co patří do projektu:** mapování Invoice → ShipmentRequest, ukládání zásilek do DB, Storage.

---

License
-------

[](#license)

Private package — Ages s.r.o.

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance95

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

43d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/20422823?v=4)[Jiří Hovad](/maintainers/A-g-e-s)[@A-g-e-s](https://github.com/A-g-e-s)

---

Top Contributors

[![A-g-e-s](https://avatars.githubusercontent.com/u/20422823?v=4)](https://github.com/A-g-e-s "A-g-e-s (48 commits)")

### Embed Badge

![Health badge](/badges/ages-shipping-gateway/health.svg)

```
[![Health](https://phpackages.com/badges/ages-shipping-gateway/health.svg)](https://phpackages.com/packages/ages-shipping-gateway)
```

###  Alternatives

[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3751.2M45](/packages/tencentcloud-tencentcloud-sdk-php)[neuron-core/neuron-ai

The PHP Agentic Framework.

1.9k496.1k32](/packages/neuron-core-neuron-ai)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

232.5k](/packages/eslazarev-wildberries-sdk)[files.com/files-php-sdk

Files.com PHP SDK

2478.1k](/packages/filescom-files-php-sdk)[aimeos/prisma

A powerful PHP package for integrating media related Large Language Models (LLMs) into your applications

1772.4k4](/packages/aimeos-prisma)[volcengine/volcengine-php-sdk

117.6k](/packages/volcengine-volcengine-php-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
