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

Geodis Bundle Laravel Package

zangra/geodis-bundle

A PHP/Laravel bundle for integrating Geodis shipping services into your application, providing structured configuration and service wiring to support Geodis-related transport and logistics workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and register the bundle

    composer require zangra/geodis-bundle
    

    Register it in config/bundles.php:

    Zangra\GeodisBundle\ZangraGeodisBundle::class => ['all' => true],
    

    If the bundle ships routes (e.g. webhook endpoint, admin UI), import them in config/routes.yaml:

    zangra_geodis:
        resource: "@ZangraGeodisBundle/Resources/config/routing.yaml"
    
  2. Look at these files first, in order

    • src/DependencyInjection/Configuration.php — the authoritative list of config keys (credentials, endpoints, sandbox flag, defaults). This is where you learn what is actually configurable.
    • src/DependencyInjection/ZangraGeodisExtension.php — which services get wired, aliases, and tagged services.
    • src/Api/ (or src/Client/) — the HTTP client wrapper around the Geodis REST/JSON endpoints. Confirm which calls are covered (rate, create shipment, label, tracking) versus missing.
    • src/Sylius/Shipping/Calculator/ — whether a CalculatorInterface implementation is provided for Sylius shipping method rate calculation.
    • README.md and any Tests/ fixtures — often the only working example of config shape.
  3. Configure credentials

    # config/packages/zangra_geodis.yaml
    zangra_geodis:
        environment: test        # or prod / sandbox — check config tree for the exact key
        credentials:
            customer_id: '%env(GEODIS_CUSTOMER_ID)%'
            api_key: '%env(GEODIS_API_KEY)%'
            # agency / contract numbers if required by your Geodis account
    
  4. First use case: rate calculation on a Sylius shipping method

    Create a shipping method in the Sylius admin, choose the Geodis calculator (if provided), and attach a matching shipping method rule (zone + weight/amount). Verify the calculator is tagged with sylius.shipping_calculator by dumping the container: bin/console debug:container --tag=sylius.shipping_calculator.

Implementation Patterns

  • Wrap the bundle's client behind your own interface. Because the package has single-digit contribution history, treat its API client as a vendor detail. Inject Zangra\GeodisBundle\...\Client into your own GeodisGateway interface and mock your interface in tests. This lets you swap to a raw HttpClient call if the bundle goes stale.

  • Label generation on shipment transitions. The idiomatic Sylius hook is the state machine, not a controller:

    // services.yaml
    App\EventListener\GeodisLabelListener:
        tags:
            - { name: kernel.event_listener, event: sylius.shipment.post_transition, method: onShipmentTransition }
    

    Trigger label creation when the shipment transitions ready → shipped. Store the returned label URL/tracking number on the shipment (via a custom field on Shipment or the shipment.metadata map) — do not block the transition on a Geodis HTTP failure; queue it instead.

  • Queue outbound calls with Symfony Messenger. Rate calls during checkout are latency-sensitive; label creation is not. Route CreateGeodisLabelMessage through your async transport so a Geodis 5xx doesn't fail checkout. Sylius already has Messenger wired in recent versions — reuse it rather than adding a separate queue.

  • Webhook / tracking sync pattern. Geodis typically pushes tracking updates via callback or you poll the tracking endpoint. If the bundle exposes a route, secure it (shared secret in header or IP allowlist — Geodis won't sign by default). Otherwise schedule app:geodis:sync-tracking as a messenger:consume job and update the shipment state machine from the result.

  • Rate caching by address signature. Geodis rate responses are stable for ~minutes. Cache on a hash of postcode|country|weight|service with a short TTL (5–15 min) using Symfony Cache. This is the single biggest win in checkout performance.

  • Test against recorded fixtures. Geodis REST responses have a fairly idiosyncratic envelope. Capture a handful of real sandbox responses (rate, label, tracking, error) into tests/fixtures/ and drive both your gateway and the bundle client with Symfony's MockHttpClient returning those bodies. This is the only way to get the error-shape handling right.

  • Multi-channel / multi-agency. If your Geodis contract has multiple agencies (per warehouse or per store), key the client config by channel. The bundle likely assumes one credential set; you'll instantiate multiple clients or decorate the factory.

Gotchas and Tips

  • The package is effectively pre-1.0. Zero stars, zero dependents, one release as of late 2025. Read composer.json for the exact Symfony/Sylius version constraints before adding it to an existing app — a bundle written against Sylius 1.x CalculatorInterface may not work on 2.x without a fork. Pin the version in composer.json and commit composer.lock.

  • Sandbox vs production is usually a host swap, not a flag. Check Configuration.php for how environment is consumed. A common failure mode is sandbox credentials hitting the production host (or vice versa) and getting a 401 that looks like a credential error. Log the resolved base URI on boot.

  • Error envelopes are inconsistent. Geodis typically returns JSON errors with a non-standard shape alongside a non-2xx status. Don't trust $response->getStatusCode() alone — inspect the body and log the raw payload on any non-success. Add a Retry-After-aware retry decorator on top of the client for 429/5xx.

  • Idempotency on label creation. Retrying a label request after a timeout can duplicate a parcel and a charge. Persist a client-generated reference (order number + shipment id) before the call, and on retry first query for an existing label by that reference before re-creating. If the bundle doesn't expose a "find by reference" call, you'll need to add it.

  • Address fields are stricter than Sylius. Geodis expects postcode/city/country with particular casing and country codes. French/EU addresses with missing state or street2 commonly fail validation. Add a small normalizer service translating Sylius\Component\Addressing\Model\Address → Geodis payload; do this in your own class rather than editing vendor code so upgrades are safe.

  • Extension points to prefer over editing the bundle:

    • Service decoration: App\Geodis\DecoratingClient implementing the same interface, decorates: zangra_geodis.client.
    • Compiler pass to add a channel-aware client factory.
    • Custom shipping calculator if the bundled one doesn't match your pricing model — Sylius calculators are cheap to write and easier to control than patching.
  • Debugging checklist when a rate returns 0 or 500:

    1. bin/console debug:config zangra_geodis — confirm credentials actually resolve from env (empty env vars are a classic).
    2. bin/console debug:container --tag=sylius.shipping_calculator — confirm the calculator is registered.
    3. Inspect the shipping method's zone rule — a mis-scoped zone silently yields no rate, unrelated to Geodis.
    4. Enable framework.http_client.default_options.trace or a profiler listener to see the actual outbound request body; Geodis errors frequently reference a field your normalizer dropped.
  • Vendor risk mitigation. Because the repository is unmaintained-by-popularity, plan for one of:

    • Fork into a private-vendor/ path repository (recommended) and apply patches directly,
    • Or wrap the bundle's client so a future replacement only touches one file.

    Either way, add a smoke test that hits the sandbox once in CI weekly — the API contract drift is the thing that will bite you, not the PHP code.

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.
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
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin