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

Gls Tracking Laravel Package

webit/gls-tracking

Laravel package that brings GLS parcel tracking into your PHP application. Look up shipments by tracking number and receive structured status and delivery updates, giving you a simple, consistent way to add GLS tracking to your app.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install with composer require webit/gls-tracking and immediately run composer show webit/gls-tracking to see the resolved version and its dependency constraints. This package's last tag is from 2017, so check whether Composer picked a PHP/Guzzle version that is compatible with your app; if it errors, you will likely need to fork the repo and relax the constraints before doing anything else.
  2. Check for Laravel wiring. Open the package's composer.json and look for an extra.laravel.providers block. Given the package age, assume there is no auto-discovery: register the service provider manually in config/app.php (or bootstrap/providers.php on Laravel 11) and add a facade alias if the README references one.
  3. Find the client first, config second. Read the README, then open src/ and identify the single class that talks to GLS (usually something like a GlsTracking/TrackingClient with methods such as getParcelStatus(...) / track(...)). That class is your entire integration surface. Check its constructor signature — it will tell you whether credentials, an endpoint URL, or a pre-built HTTP client are injected.
  4. Publish/define configuration. If the package ships a config file, run php artisan vendor:publish --provider="Webit\GlsTracking\..." (get the exact FQCN from the README). Otherwise create config/gls-tracking.php yourself with the keys the client expects: API endpoint, username/login, password, and any country/tenant identifier. Keep these in .env and never commit them.
  5. First use case: single-parcel lookup. Resolve the client from the container and call the status method with one parcel number. Log the raw response before doing anything else — the package returns the API's structures (arrays or XML objects), not clean DTOs, and you need to see the shape once to map it correctly.

Where to look first, in order: README → src/ client class → tests/ (if any) for real request/response fixtures → the GLS tracking API docs for the field meanings.

Implementation Patterns

Wrap the client in your own service. Never let controllers or Livewire components call the vendor class directly. Create App\Services\GlsTrackingService that takes the vendor client in its constructor and exposes intent-revealing methods (getStatus(string $parcelNumber): ParcelStatus). This isolates you from the package being abandoned, and it's the one place you'd edit to swap in a hand-rolled Guzzle call later.

Bind an interface for testability. Register TrackingProvider::class => GlsTrackingService::class in a service provider, and resolve that interface everywhere. Because this package predates Laravel's Http facade, you cannot use Http::fake(). Instead, either (a) inject a Guzzle Client with a MockHandler into the vendor client if its constructor allows it, or (b) bind a fake implementation of your own interface in tests and never touch the vendor class in feature tests.

Normalize before calling. Parcel numbers arrive from users with spaces, dashes, and case variation. Strip and validate in a FormRequest or in your service before handing the value to the client; the GLS API expects a specific format and will return an opaque error otherwise.

Cache aggressively. Tracking statuses change on the order of hours, not seconds. Cache each parcel result for 5–15 minutes keyed by normalized parcel number (Cache::remember("gls:parcel:{$number}", now()->addMinutes(10), ...)) with a refresh flag to bypass. This is the single biggest thing that keeps you under rate limits and off the API's critical path.

Queue bulk lookups. Any screen that lists more than a couple of parcels should dispatch a job per batch rather than loop in the request. Use a dedicated queue with a low concurrency (2–3 workers) to avoid hammering the endpoint, add retryUntil/backoff, and persist results into your own shipment_events table so the UI reads from the database, not the API.

Persist a normalized event timeline. Map the vendor's response into your own parcel_status / parcel_events tables (parcel number, status code, description, occurred_at, raw payload). Keep the raw payload in a json column for later debugging; you'll need it when a customer disputes a status.

Multi-account/multi-region. GLS credentials are per country subsidiary and the endpoints differ. Don't rely on a single global config if you ship to more than one country — construct a client per account (a small factory reading an array of configs) rather than reading config() inside the vendor class.

Scheduled refresh. A scheduled command every 15–30 minutes that selects open shipments (not yet delivered), dispatches refresh jobs, and marks terminal states once observed. Combine with your cache so manual page views don't re-fetch.

Gotchas and Tips

  • Age is the real risk. A 2017 release almost certainly pins PHP 7.0/7.1 and Guzzle 6. On Laravel 10/11 with Guzzle 7 you will hit conflicts; plan for a fork with "php": "^8.x" and "guzzlehttp/guzzle": "^7.0" in the fork's composer.json, consumed via a VCS repository entry or a private Packagist package.
  • No auto-discovery. Forgetting the manual provider registration produces a confusing "target class does not exist" rather than a clear error. Add it to a dedicated providers config block.
  • Unmocked HTTP in tests. Any test that resolves the real client will attempt a network call and be slow/flaky. Guard your service with a config('gls-tracking.enabled') short-circuit or bind the fake interface in TestCase::setUp().
  • Opaque errors. The package likely surfaces API failures as generic exceptions or returns an error node in the payload with no status code. Wrap every call in try/catch, convert to your own TrackingFailedException, and log the request payload (minus credentials) plus the full raw response at debug level.
  • Don't log credentials. If you enable Guzzle request logging, exclude the auth header/body. Credentials in this package are typically sent in the request body, so naive Log::info($request) leaks them.
  • Timeouts. Set an explicit Guzzle timeout (5–10s connect, 15s total) on the injected client. The default is infinite; a slow GLS endpoint will otherwise tie up your queue workers.
  • Response shape drift. Because there's no typed response object, treat the returned structure as untrusted: use data_get() with defaults and validate that the parcel number in the response matches the one you asked for before persisting.
  • Extension points are minimal. There's no event system or middleware. Extend by composition: decorate your own service, not the vendor class. If you need retries, add them at the job level ($tries, backoff()), not inside the package.
  • Version pinning. Since there will be no future releases, pin an exact version (or a commit hash of your fork) in composer.json so an unrelated composer update can't silently change behavior, and add a note in the repo that the dependency is frozen/abandoned.
  • Have an exit plan. Budget for replacing the vendor call with a ~100-line Guzzle client against the documented GLS tracking endpoint. Keeping your interface boundary clean from day one makes that a one-file change.
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