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

Laravel Shipping Laravel Package

ivanmitrikeski/laravel-shipping

Laravel package for multi-carrier shipping quotes and shipments, supporting UPS, FedEx, Canada Post, USPS and Purolator rate and shipment APIs, with flat-rate models and standalone use outside Laravel.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Modularity: The package aligns well with Laravel’s Eloquent ORM and service container, enabling clean separation of shipping logic from business logic. The provider-agnostic design (via abstract ShippingProvider class) allows for easy extension or swapping of carriers.
  • Domain-Specific Models: Eloquent models (Shipment, Rate, Address, etc.) fit naturally into Laravel’s MVC structure, reducing boilerplate for shipping-related CRUD operations.
  • API Abstraction: The package abstracts OAuth/REST complexity for UPS, FedEx, etc., which is critical for e-commerce platforms with multi-carrier needs.
  • Transport Layer Change (v1.0.10): The HTTP transport is now Guzzle 8.x. Provider classes, models, and the public API surface are unchanged, but the underlying request/response/exception semantics are those of Guzzle 8 + PSR-7 v2. Any application code that reaches into the transport (custom HandlerStack middleware, Guzzle event subscribers, direct RequestException handling) is now coupled to a different major version.

Integration Feasibility

  • Laravel-Centric: Designed for Laravel (e.g., service providers, Facades, migrations), minimizing friction for adoption. Non-Laravel usage is possible but secondary.
  • Dependency Clarity: Explicit .env requirements for credentials and sandbox mode simplify configuration. However, sensitive data management (e.g., rotation, encryption) must be handled externally.
  • API Coverage: Supports core shipping workflows (rate calculation, shipment creation), but lacks advanced features like tracking updates or labels (beyond USPS).
  • Guzzle 8 Dependency Conflict Risk (new): This is the primary integration concern for v1.0.10. Laravel’s framework (and therefore the Http facade used by most host apps) constrains guzzlehttp/guzzle to ^7.x. If that remains true for your Laravel version, Composer cannot resolve the package at v1.0.10 alongside the framework. Confirm resolution before planning any upgrade; a failed composer update is the expected first symptom.
  • Semver Signal: A major HTTP-client bump shipped as a patch (v1.0.9 → v1.0.10) understates the blast radius. Treat v1.0.10 as a breaking upgrade for planning purposes regardless of the tag.

Technical Risk

  • Provider-Specific Quirks: Each carrier’s API has edge cases (e.g., UPS’s Shipment API vs. FedEx’s CreateShipment). The package mitigates this via provider-specific classes, but custom logic may still be needed.
  • Rate Limiting/Throttling: No built-in retry logic for API rate limits. Requires middleware or application-level handling (e.g., Laravel’s retry helper).
  • Data Validation: Relies on Laravel’s validation, but complex carrier-specific rules (e.g., Purolator’s billing account formats) may need manual validation layers.
  • Testing: Limited test coverage in the package (per repository maturity). Integration tests for all providers should be prioritized. For v1.0.10 specifically, verify the package publishes a CI matrix covering Guzzle 8, and confirm your own contract tests against each carrier sandbox pass on the new transport.
  • Custom Guzzle Middleware (new): If you added logging, backoff, or header-injection middleware around the package’s client, the Guzzle 8 middleware/handler API changes put that code at risk. Inventory any HandlerStack::push, Middleware::retry, or event-subscriber usage before upgrading.
  • Exception Hierarchy (new): GuzzleHttp\Exception\* and PSR-18 ClientExceptionInterface behaviour differs enough that catch blocks written against Guzzle 7 may silently stop matching. Audit catch statements around shipping calls.

Key Questions

  1. Carrier Prioritization: Which providers are critical for MVP vs. future phases? (e.g., USPS-only may simplify initial integration.)
  2. Authentication Flow: How will credentials be managed (e.g., Vault, encrypted .env, or a secrets manager)?
  3. Error Handling: What’s the acceptable UX for API failures (e.g., retries, fallback carriers, or user notifications)?
  4. Extensibility: Are there plans to support additional providers (e.g., DHL, Amazon Shipping) or features (e.g., tracking, labels)?
  5. Performance: Will rate calculations be cached (e.g., Redis), and how will stale data be handled?
  6. Compliance: Are there regional restrictions (e.g., Canada Post for Canadian orders only) that require logic branching?
  7. Guzzle 8 Compatibility (new): Does v1.0.10 allow a dual constraint (^7.0|^8.0), or is Guzzle 8 now a hard requirement? Does the maintainer intend to keep a v1.0.9-compatible line for apps pinned to Laravel’s Guzzle 7?
  8. Laravel Version Gate (new): Which Laravel release line (if any) permits Guzzle 8? If none today, v1.0.10 is not installable in a standard Laravel app and should be deferred.

Integration Approach

Stack Fit

  • Laravel Ecosystem: Ideal for Laravel apps using Eloquent, Queues, and API clients (e.g., Guzzle). Compatible with:
    • Frontend: Livewire/Inertia for real-time rate updates.
    • Backend: Queues for async shipment creation (e.g., dispatch(new CreateShipmentJob($data))).
    • Testing: Pest/Laravel’s HTTP tests for API provider mocking.
  • HTTP Client Coexistence (new): Composer installs one major version of guzzlehttp/guzzle per project. If your app or framework requires Guzzle 7, you cannot adopt v1.0.10 without a resolution strategy. Options, in order of preference:
    1. Stay on v1.0.9 until the framework allows Guzzle 8 (lowest risk, zero code change).
    2. Isolate shipping into a separate service/worker that can run Guzzle 8 independently of the main Laravel app.
    3. Force resolution (composer update --with-all-dependencies) only after confirming the framework tolerates Guzzle 8 — not recommended without maintainer guidance.
  • Non-Laravel: Possible but requires manual setup (e.g., instantiating ShippingProvider directly). Not recommended for greenfield projects. Note that non-Laravel consumers face the same Guzzle 8 major-version decision.

Migration Path

  1. Phase 0: Dependency Audit (new, mandatory)
    • Run composer why guzzlehttp/guzzle and composer why-not guzzlehttp/guzzle ^8.0 to see who pins what.
    • Inventory custom Guzzle middleware, handler stacks, event subscribers, and catch blocks touching shipping calls.
    • Decide: defer, isolate, or upgrade. Record the decision and the pin.
  2. Phase 1: Sandbox Setup
    • Configure .env with sandbox credentials for all target providers.
    • Test rate calculations and shipment creation in a staging environment.
  3. Phase 2: Production Rollout
    • Replace sandbox credentials with live ones in a feature flagged branch.
    • Implement monitoring for API failures (e.g., Sentry, Laravel Horizon).
  4. Phase 3: Feature Expansion
    • Add carrier-specific logic (e.g., Purolator’s registered account validation).
    • Integrate with order workflows (e.g., trigger shipment creation post-payment).
  5. Phase 4: Guzzle 8 Upgrade (new, conditional)
    • Only if Phase 0 concludes the stack can move. Pin ivanmitrikeski/laravel-shipping:v1.0.10 and run the full provider contract suite in sandbox before touching production.
    • Keep v1.0.9 documented as the rollback target in the runbook.

Compatibility

  • Laravel Version: Tested with Laravel 10+ (per last release date). Verify compatibility with your version.
  • PHP Version: Requires PHP 8.1+. Guzzle 8 raises the effective floor to PHP 8.1 and requires PSR-7 / psr/http-message v2 — confirm no transitive package pins PSR-7 v1. Deprecated-function checks are less relevant than PSR interface version checks now.
  • Guzzle Version (new): v1.0.10 requires Guzzle 8. Determine explicitly whether the package’s constraint is ^8.0 only or ^7.0|^8.0. This single fact determines whether the upgrade is a drop-in or a project-wide dependency event.
  • Database: Uses Eloquent, so any Laravel-supported DB (MySQL, PostgreSQL, etc.) works. Migrations are provider-agnostic. No schema changes in v1.0.10.
  • Third-Party Conflicts: Potential naming collisions with existing Shipping classes or Facades. Use aliases if needed. Add Guzzle-8-vs-Laravel-HTTP-client conflict to the known-issues list.

Sequencing

  1. Prerequisites:
    • Laravel app with Eloquent and API client (Guzzle) configured.
    • Database migrations run (php artisan migrate).
    • Dependency decision recorded (v1.0.9 pin vs. v1.0.10 upgrade) with named owner.
  2. Core Integration:
    • Publish package config (php artisan vendor:publish --provider="IvanMitrikeski\Shipping\ShippingServiceProvider").
    • Bind providers to the container (e.g., config(['shipping.providers.ups' => UpsProvider::class])).
  3. Workflow Integration:
    • Hook into order creation (e.g., OrderCreated event → calculate rates).
    • Add shipping rate selection to checkout (e.g., Livewire component).
  4. Post-Launch:
    • Implement webhooks for shipment updates (if providers support it).
    • Add analytics for carrier performance (e.g., cost, success rates).
  5. Upgrade Window (new):
    • Schedule the Guzzle 8 move outside peak shipping periods (avoid Q4/holiday freezes), and treat it like a framework upgrade: sandbox → staging soak → canary → full rollout.

Operational Impact

Maintenance

  • Updates: MIT license allows forks. Monitor for provider API changes (e.g., UPS deprecating endpoints). Plan for:
    • Dependency updates (composer update ivanmitrikeski/laravel-shipping).
    • Backward-compatibility breaks (e.g., renamed provider methods).
    • Version pinning discipline (new): Pin v1.0.9 or v1.0.10 explicitly rather than using a floating constraint; a patch tag now carries breaking dependency weight.
  • Credential Rotation: Automate .env updates for provider credentials (e.g., using Laravel Forge or a secrets manager).
  • Deprecation: USPS API v3 is stable, but other providers may sunset endpoints. Subscribe to carrier changelogs. Add Guzzle 7 → 8 security-support timelines to the same watch list.
  • Maintenance Burden Shift (new): Post-upgrade, you own a Guzzle 8 code path the maintainer has only just adopted. Budget a small ongoing allowance to track Guzzle 8 patch releases and any follow-up fixes in v1.0.11+.

Support

  • Debugging: Use SHIPPING_SANDBOX=true for local testing. Log provider responses for troubleshooting:
    $provider->setDebug(true);
    
    On Guzzle 8, confirm setDebug still routes through the new middleware stack; if not, attach your own logging middleware.
  • Provider-Specific Issues:
    • UPS/FedEx: OAuth token expiration handling (e.g., refresh tokens).
    • Canada Post: Customer number validation errors.
    • USPS: Address validation failures (may require external tools like SmartyStreets).
  • Transport-Level Issues (new): Expect a new class of tickets immediately after upgrade — connection/timeout exceptions surfacing under different class names, PSR-7 stream behaviour differences, and header normalization changes. Update the on-call runbook with Guzzle 8 equivalents for the top five error signatures.
  • Community: Limited stars/support. Plan for internal documentation or extended SLAs for critical providers. The maintainer’s response time on Guzzle 8 regressions is an unknown and should be treated as a risk until v1.0.11 ships clean.

Scaling

  • Rate Limiting: Implement exponential backoff for API calls (e.g., using spatie/fork).
  • Concurrency: Use Laravel Queues for async shipment creation to avoid timeouts:
    CreateShipment::dispatch($shipmentData)->onQueue('shipping');
    
  • Caching: Cache rate responses (e.g., 5-minute TTL) for frequent queries:
    $rates = Cache::remember("rates_{$origin}_{$destination}", now()->addMinutes(5), fn() =>
        $provider->getRates($origin, $destination)
    );
    
  • Database: Optimize shipments table for read-heavy workloads (e.g., add indexes for status, carrier).
  • Scaling Notes for v1.0.10 (new): Throughput characteristics are unchanged — Guzzle 8 is not a performance feature, it is a compatibility event. No capacity replanning is required, but do re-baseline p95 latency on rate calls after upgrade, since connection pooling and default timeout behaviour can shift subtly.

Failure Modes

Failure Scenario Impact Mitigation
Provider API downtime Orders stuck in checkout Fallback to a secondary carrier or manual override.
Invalid credentials All requests fail Automated alerting (e.g., Laravel Healthcheck).
Rate calculation timeouts Poor UX during checkout Queue requests and notify user via email.
Carrier-specific validation errors Failed shipments Pre-validate addresses/carrier rules.
Database connection issues Lost shipment records Use transactions and retry logic.
Composer conflict on Guzzle 8 (new) Update blocked or app-wide dependency churn Pin v1.0.9; resolve via Phase 0 audit before attempting upgrade.
Custom middleware incompatible (new) Silent loss of logging/retry/header injection; shipping calls fail or misbehave post-upgrade Inventory middleware in Phase 0; port and test in sandbox first.
Changed exception classes (new) Catch blocks stop matching; unhandled exceptions surface as 500s at checkout Re-audit catch statements; add a fallback Throwable handler around shipping calls.

Ramp-Up

  • Onboarding Time: 2–4 weeks for a Laravel dev to integrate core providers (excluding custom logic). Add 1–2 days for the Guzzle 8 dependency audit and decision, plus 3–5 days if the upgrade is approved (middleware porting, exception audit, sandbox soak).
  • Training Needs:
    • Developers: Focus on provider-specific quirks (e.g., FedEx’s Shipment API vs. UPS). Add: Guzzle 8 migration differences and PSR-7 v2 semantics for anyone touching the transport.
    • QA: Test edge cases (e.g., international addresses, weight limits). Add: re-run the full carrier sandbox regression suite against v1.0.10, including timeout and error-path scenarios.
    • Ops: Understand credential rotation and monitoring setup. Add: how to detect and roll back a failed dependency upgrade.
  • Documentation Gaps: Supplement the README with:
    • Example workflows (e.g., "How to add a new carrier").
    • Troubleshooting guides for common errors (e.g., Purolator’s 403 Forbidden).
    • Guzzle version support matrix stating which package versions require which Guzzle major, and the recommended pin per Laravel version.
  • Tooling: Recommend:
    • Postman collections for provider API testing.
    • Laravel Telescope for debugging requests.
    • Composer dependency guard in CI (e.g., composer why-not check) so a routine composer update cannot silently pull v1.0.10 into a Guzzle 7 project.
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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel