ernadoo/mondial-relay
Framework-agnostic PHP client for Mondial Relay: create shipment labels via the V2 REST API and search relay points via the V1 SOAP API. Supports sandbox testing, tracking URLs, and label PDFs.
SoapParcelShopClient) and shipment/label creation (RestShipmentClient via MondialRelayClient) — the two capabilities needed to offer “deliver to a pickup point” to French, Belgian, and broader EU customers.ParcelShopSearchRequest::around($countryCode, $latitude, $longitude), or latitude/longitude arguments with an optional post code). This unlocks map pin-drops, geolocation-based store locators, and mobile checkout flows that previously required a post code — a meaningful UX and conversion lever, not just a backend detail.ParcelShop::schedule() exposes day-by-day opening hours (on($isoDay), isOpenOn(), isAlwaysOpen(), isEmpty()) instead of raw "0930-1300 1400-1900" strings, plus new $locker and $directions fields. That supports “open now” badges, locker filtering, and usable wayfinding copy in the picker — reduces drop-off at the selection step and “where exactly is it / is it open?” support contacts.Level-based severity parsing, credential leakage in HTTP error bodies, and now opening-hours/business-hours modelling and geospatial query validation. This release absorbs that carrier-specific complexity, so the PM decision shifts further toward buying/integrating rather than owning a bespoke connector.ConfigurationException / TransportException / ApiException let the team distinguish misconfiguration from carrier outages from Mondial Relay business rejections — useful for translated customer-facing errors and for support triage. v4.2.0 adds an earlier, cheaper failure mode: bad search input (no post code and no coordinates, a single coordinate, out-of-range coordinates) now raises \InvalidArgumentException client-side instead of a carrier round-trip, so bad requests surface in your own logs with your own stack traces rather than as ambiguous carrier rejections.login → apiLogin, password → apiPassword, customerId → brandCode, secretKey → privateKey rename from v4.1.0 is only breaking for named arguments; positional calls are unaffected. One behavioural nuance worth flagging: callers that currently catch ApiException for malformed search parameters must also handle \InvalidArgumentException, since that validation moved in front of the API call.Level parsing, credential redaction in exceptions, and now opening-hours parsing and coordinate validation.ApiException to \InvalidArgumentException.To executives: Mondial Relay is a major lever for French and EU e-commerce conversion, especially pickup-point delivery. Earlier versions of this integration were not production-viable — label creation and relay-point search both failed outright. v4.1.0 was the reliability release; v4.2.0 builds on it with customer-visible capability: pickup points can now be found by map location or device position rather than requiring a post code, and the picker can show real opening hours, locker availability, and directions. That translates into a better selection experience and fewer “is it open / where is it” support contacts. The commercial ask is modest: adopt v4.2.0+, pin the version, and budget a short engineering pass for the named-argument rename carried over from v4.1.0.
To engineering: This is a low-level, carrier-specific client — useful, but not a multi-carrier abstraction. PSR-3 logging never records credentials, request bodies, or response bodies. Failures are typed (ConfigurationException, TransportException, ApiException) so callers can branch without parsing message strings; v4.2.0 adds pre-flight \InvalidArgumentException for invalid search parameters, so search call sites should catch it alongside ApiException and treat it as a caller bug, not a carrier incident. ApiException::getErrors() returns array<int|string, string> because PHP coerces numeric Mondial Relay codes to integer keys — account for that in consumers. ParcelShop::schedule() is the structured path; openingHours still holds raw strings for anyone who needs them, so migrate incrementally. $locker and $directions are additive optional properties — handle nulls. Positional constructor/create() calls remain source-compatible; named arguments are not (v4.1.0 change). Any existing wrapper or test using named arguments should be updated and covered by an integration test against the sandbox before release.
To product/support: Customer-facing errors can be translated by exception type rather than Mondial Relay’s raw message, and invalid search inputs are now rejected before they reach the carrier, giving cleaner telemetry on where the funnel breaks. Relay-point names and addresses are cleaned of the apostrophe-to-space artefact and padding, and pickup details now include structured opening hours, locker flags, and directions. That reduces support tickets for “missing street name”, “wrong distance”, “is this shop open?”, and “where do I collect?” complaints, and makes an “open now” filter feasible without bespoke parsing.
How can I help you explore Laravel packages today?