Search by

beziworld / laravel-geis

kamcw

Laravel client for the Geis GService REST API (Geis Polska, CZ, SK): parcel and cargo shipments, orders, labels, pickup lists, pickups, tracking and routing.

Package info

github.com/Beziworld/laravel-geis

Homepage

Issues

pkg:composer/beziworld/laravel-geis

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.0 2026-11-04 19:56 UTC

This package is auto-updated.

Last update: 2026-11-04 19:57:45 UTC


README

tests Latest Version License

Laravel client for the Geis GService REST API, the integration interface of Geis Polska (also Geis CZ and Geis SK):

  • expeditions (shipments from your warehouse) and orders (collection from a third party) through a typed, validating builder
  • pallets and other packing types, sub-items, COD, insurance, SMS and phone notifications, B2B / HDS / HDP categories
  • labels (PDF, PDFO, ZPL, EPL, BMP) and the pickup list (handover protocol)
  • pickups: creation and the list of pickups planned for a day
  • tracking: latest status of up to 200 shipments per call and the full Track and Trace record per shipment
  • deleting shipments, own number ranges, routing table and delivery routing for self-printed labels
  • dictionaries: additional services, packing types, statuses, currencies
  • multiple accounts and instances (pl, cz, sk), runtime credentials, php artisan geis:check

Polska wersja dokumentacji

Why this package

Packagist has no client for the Geis REST API and nothing for Geis Polska: the only Geis packages are a generated SOAP client for the Czech service (goetas-webservices/geis-group-cz-client) and a GeisPoint pickup point client (ondrejd/geis-point-service). The GService manual (v6.2) recommends REST for new integrations; this package follows the public OpenAPI document of the Polish test instance, validates the schema rules before sending and handles the documented limits (200 shipments per call, call limits per method, HTTP 429).

Installation

composer require beziworld/laravel-geis
php artisan vendor:publish --tag=geis-config   # optional
GEIS_CUSTOMER_CODE=...          # customer code and password from your Geis business manager
GEIS_PASSWORD=...
GEIS_COUNTRY=pl                 # pl, cz or sk
GEIS_SANDBOX=false              # true = gservicetest.geis.pl (separate credentials)
GEIS_LABEL_FORMAT=PDF           # PDF, PDFO, ZPL, EPL, BMP

GEIS_SENDER_NAME="ACME Sp. z o.o."      # default collection address of orders
GEIS_SENDER_STREET="ul. Prosta 1"
GEIS_SENDER_CITY=Warszawa
GEIS_SENDER_ZIP_CODE=00-001
GEIS_SENDER_CONTACT_NAME="Jan Nowak"
GEIS_SENDER_CONTACT_PHONE="+48 500 600 700"
GEIS_SENDER_CONTACT_EMAIL=magazyn@example.com

Check the credentials and see your packing types and services:

php artisan geis:check --country=PL

Expeditions

An expedition leaves from the address of your customer account. A pickup must exist for the pickup date (Geis may create it automatically; otherwise use createPickup()).

use Beziworld\Geis\Data\Address;
use Beziworld\Geis\Data\Contact;
use Beziworld\Geis\Facades\Geis;

$created = Geis::expedition()
    ->to(
        new Address('Hurtownia Kowalski', 'ul. Długa 5', 'Kraków', '30-001'),
        new Contact('Anna Kowalska', '+48 600 700 800', 'anna@example.com'),
    )
    ->pickupDate(now())
    ->units('FP', weight: 150, count: 1, description: 'Books', length: 1.2, width: 0.8, height: 1.5)  // metres
    ->units('HP', weight: 80)
    ->cashOnDelivery('1499.90', 'PLN', variableSymbol: '20261105', iban: 'PL61 1090 1014 0000 0712 1981 2874')
    ->insurance(2000, 'PLN')
    ->sms('+48 600 700 800')
    ->reference('ORDER-1')
    ->send();

$created->packNumber;   // 13-digit shipment number

homeDelivery() sets the HDS category, personalPickup() and exWorks() set the matching flags and shipmentNumber() uses a number from your own range (assignRange()). Packing type codes (FP, HP, ...) come from Geis::packingTypes(); services enabled for a destination from Geis::services('DE').

Orders

An order is collected from another address, at the earliest on the next business day. The configured sender is the default collection address.

Geis::order()
    ->from(new Address('Supplier', 'ul. Fabryczna 2', 'Łódź', '90-001'), new Contact('Piotr', '+48 601 000 000'))
    ->to(new Address('ACME Sp. z o.o.', 'ul. Prosta 1', 'Warszawa', '00-001'))
    ->pickupDate(now()->addWeekday())
    ->units('FP', weight: 300, count: 2)
    ->totals(weight: 300, volume: 1.5)
    ->send();

build() returns the validated Shipment without sending it; pass it to Geis::create() later.

Labels and pickup list

use Beziworld\Geis\Enums\LabelFormat;

$labels = Geis::labels(['1234567890123', '9876543210987']);          // configured format, PDF position 1
$labels = Geis::labels('1234567890123', LabelFormat::Zpl, resolution: 300);

Storage::put($labels[0]->filename(), $labels[0]->content);            // label-1234567890123.pdf

$list = Geis::pickupList(now());     // handover protocol (PDF) for all expeditions of the day

Labels are available for expeditions created through the API.

Pickups

use Beziworld\Geis\Data\PickupItem;
use Beziworld\Geis\Data\PickupRequest;

Geis::createPickup(new PickupRequest(
    date: now(),                                      // same day only until 10:00
    contact: new Contact('Jan Nowak', '+48 500 600 700', 'magazyn@example.com'),
    count: 3,
    totalWeight: 420,
    items: [new PickupItem('FP', 3, 420)],
));

Geis::pickups(now(), isOrder: false);                  // pickups planned for the day

Tracking

$status = Geis::status('1234567890123');               // latest status: code and name
$statuses = Geis::statuses($numbers);                  // any number of shipments, 200 per request

$detail = Geis::track('1234567890123');
$detail->latest()?->name;
foreach ($detail->history as $event) {
    $event->occurredAt; $event->code; $event->name; $event->depot;
}
$detail->colli('123456789012301');                    // events of one handling unit
$detail->services;                                     // charged services with decimal string prices

Geis::trackBy(reference: 'ORDER-1');
Geis::shipments(pickupDate: now());                    // what was created for a day

Deleting shipments

foreach (Geis::delete(['1234567890123']) as $result) {
    $result->deleted;        // false when the shipment already has an operational status
    $result->errorMessage;
}

Multiple accounts

// config/geis.php
'connections' => [
    'default' => [],
    'cz' => ['customer_code' => env('GEIS_CZ_CUSTOMER_CODE'), 'password' => env('GEIS_CZ_PASSWORD'), 'country' => 'cz'],
],
Geis::connection('cz')->statuses($numbers);
Geis::using(['customer_code' => $tenant->geis_code, 'password' => $tenant->geis_password])->packingTypes();

Errors

Exception When
InvalidShipment A schema rule is broken; nothing is sent.
ApiException HTTP 400, 404, 409, 415 or 5xx: errorCode() (for example 2000, 2003, 2015, 2096), apiMessage(), httpStatus().
AuthenticationFailed HTTP 401.
RateLimited HTTP 429 (error 2064); retryAfter() when the service sends Retry-After.
ConnectionFailed The service cannot be reached. Reads are retried first (GEIS_READ_RETRIES, default 2).
InvalidConfiguration Missing credentials, unsupported country or label settings, unknown connection.

All exceptions extend GeisException. Creating shipments, pickups, number ranges and deletions is never retried; after a timeout check Geis::shipments() before sending again. Any endpoint can be called with Geis::request('GET', '/api/Status', read: true).

Notes

  • Before going live Geis requires integration testing on the test instance and approval of sample labels and pickup lists by the business manager.
  • The REST API has no price calculation; ShipmentDetail::$services shows charged services after the fact.

Development

composer install
composer ci   # pint --test, phpstan (level 8), pest

Author

Created and maintained by Kamil Ćwiertnia, beziworld.eu.

Need an integration? Get in touch through beziworld.eu.

Other packages by the author

laravel-ambro · laravel-dpd · laravel-poczta-polska · laravel-inpost · laravel-gls

License

MIT. See LICENSE.md. This package is not affiliated with Geis Group or Geis PL.