Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mygls Sdk Laravel Package

webapix/mygls-sdk

A PHP SDK for the MyGLS API that streamlines creating shipments, generating labels, printing parcels, and tracking deliveries. It offers a clean client for integrating GLS shipping workflows into Laravel or any PHP application.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a thin, framework-agnostic PHP wrapper around GLS's MyGLS REST API, so treat it as a domain client rather than a Laravel package. There is no service provider, no facade, and no config publish step — you wire it up yourself.

composer require webapix/mygls-sdk

Because it's unofficial and low-traffic (~29 stars), the source is the documentation. First thing: crack open src/ in vendor/webapix/mygls-sdk and read the main client/entry class, the request/response DTOs, and any *.php test fixtures. That 10-minute read will tell you more than a README typically will about MyGLS-specific quirks (credentials shape, endpoint grouping, response envelopes).

Credentials you'll need from GLS: client number, username, password, and (for most endpoints) a ClientNumber/ParcelNumber context — these come from your MyGLS contract, not the SDK. GLS typically issues separate test/sandbox credentials; ask your account manager for them before writing any integration code.

First use case — print a single label. The 90% path is: build a client → send a ParcelCreation request with recipient/sender/parcel data → receive parcel numbers → request the PDF printout. Get that working in a tinker session or an artisan command before wiring it into checkout or a fulfillment job. Everything else (tracking, cancellation, pickup booking) is a variation on the same request/response cycle.

A minimal Laravel bootstrap:

// config/services.php
'mygls' => [
    'client_number' => env('MYGLS_CLIENT_NUMBER'),
    'username'      => env('MYGLS_USERNAME'),
    'password'      => env('MYGLS_PASSWORD'),
    'sandbox'       => env('MYGLS_SANDBOX', true),
],

Then resolve the client in a small service class rather than sprinkling new Client(...) through controllers.

Implementation Patterns

Wrap the SDK in a single application service. Don't call SDK classes from controllers or jobs directly. Create App\Services\Shipping\GlsClient that constructs the underlying SDK client from config, exposes intent-revealing methods (createParcel(Order $order): ParcelResult, printLabels(array $parcelNumbers): string, track(string $parcelNumber): TrackingStatus), and translates SDK exceptions into your own domain exceptions. This is the difference between a package you can swap in a week and one that haunts you for a year.

Bind it as a singleton in a dedicated service provider:

$this->app->singleton(GlsClient::class, fn () => new GlsClient(config('services.mygls')));

The SDK client itself is usually stateless and HTTP-connection-pooled — safe to reuse per request lifecycle.

Map orders → parcel payloads with a dedicated data class. MyGLS parcel creation is fiddly (address format, parcel weight/dimensions, service codes, cash-on-delivery, insurance). Encapsulate the mapping in something like App\Shipping\MyGlsParcelData::fromOrder(Order $order). When GLS changes a required field, you edit one file, not twelve.

Always run label creation in a queued job. Label generation is a network round-trip to GLS; it doesn't belong in a checkout request. Pattern: order is paid → CreateMyGlsLabel job dispatched → job creates the parcel, stores the PDF in storage/app/labels/{order_number}.pdf (or S3), saves the returned parcel number back on the order → fires a MyGlsLabelCreated event. Retry with backoff; expose a manual "retry label" action in your admin for the inevitable failures.

Store the raw response, not just the parsed DTO. MyGLS responses contain the parcel number and status codes you'll need for support calls. Persist a JSON blob of the raw response alongside the order (orders.mygls_response json column, or a dedicated shipments table). Future-you debugging "why did this label fail" will thank present-you.

Tracking: poll or push. MyGLS does not reliably push webhooks for all account tiers — most integrations poll. Pattern: a scheduled SyncGlsTracking command loops active shipments, calls the tracking endpoint in batches, and appends status events to a shipment_events table. Throttle it (e.g. every 30–60 min) and stop polling once a shipment hits a terminal state (Delivered, Returned). If GLS does offer webhooks on your contract, handle them in a controller that verifies the payload and dispatches the same event-writing job — keep the writer identical for both paths.

Batch operations. For pickups and multi-parcel orders, one ParcelCreation call should carry all parcels. The SDK's request objects usually accept arrays; resist the temptation to loop and fire N HTTP calls — you'll hit rate limits and half-fail.

Idempotency. Keep a local parcels table keyed by (order_id, parcel_index) with a gls_parcel_number column. Before creating, check if a number already exists. GLS's API generally has no server-side idempotency key, so your database is the guard against duplicate labels on retry.

Gotchas and Tips

HTTP 200 doesn't mean success. MyGLS frequently returns 200 with an error code and message list in the body. Validate the response envelope explicitly (if (!empty($response->getErrors()))) — don't rely on exceptions or status codes alone. This is the single most common integration bug with MyGLS.

Sandbox ≠ production, and the SDK may not cleanly separate them. Check how the SDK selects base URLs — some versions hardcode endpoints, requiring you to subclass or configure it. If there's no supported way to point at the test environment, either fork the package (it's MIT, small, and low-velocity — a fork is cheap) or keep the SDK out of local dev entirely behind a fake.

Test with recorded fixtures, not live calls. Because round-trips are slow and credentials are precious, mock the SDK layer in tests. Since it's a thin client, this means mocking your GlsClient service, not the raw HTTP — assert on the parcel payload your service produces, not on HTTP verbs.

Country/address formatting is strict. GLS cares about ISO country codes, house number placement (especially for CZ/SK/PL/HU/RO — GLS's heartland), and phone format for notifications. Validate upstream and normalize before mapping. A HouseNumber missing from a Street line is a classic rejection reason.

Parcel number vs. client number vs. reference. Three different identifiers, easily confused. The parcel number is what the customer tracks with; your client number authenticates; your internal order reference is your field passed through. Store all of them but never substitute one for another in API calls.

PDF responses are binary — don't log them. If you dump a printout response into a log file, you get megabytes of raw PDF in your logs. Handle binary responses separately (->getBody() vs. parsed JSON) and store to disk immediately.

Date/timezones. GLS operates on Central European Time; send ISO-8601 with offset, not naive local strings from now(). Laravel's default UTC means now() will be an hour off for CET. Use ->setTimezone('Europe/Budapest') (or whichever GLS hub handles your account) when building pickup-date fields.

Rate limits and pickups. Booking pickups outside business hours, or booking too late in the day, can be rejected. Also be aware that repeated cancellation/creation cycles sometimes get flagged — keep your retry logic conservative (2–3 attempts with exponential backoff, not 10).

Extension points are minimal. Being a lightweight SDK, there's no middleware pipeline or event system to hook. If you need custom logging, retry, or telemetry, wrap the SDK client rather than trying to extend it. A small decorator class around your GlsClient (implementing the same interface) gives you retries and metrics without touching vendor code.

Pin the version and watch for changes. With a small maintainer footprint, treat upgrades as potentially breaking even on minor versions. Commit the lock file, and review the diff before bumping — there's no changelog you can rely on.

Have a fallback. If GLS integration is checkout-critical in your market, ensure label creation is async and order state doesn't depend on it. A GLS outage should block shipping, not selling. The SDK won't give you that property — your architecture has to.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings