Weave Code
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 shipping package with UPS, FedEx, Canada Post, Purolator, and USPS v3 support. Get rates and create shipments via REST/OAuth APIs, with sandbox mode and flat-rate options (boxes/prices) via Eloquent models. Usable outside Laravel, too.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ivanmitrikeski/laravel-shipping
    php artisan migrate
    

    Run migrations to create shipments, shipment_providers, and related tables.

  2. Configure .env: Add credentials for your target providers (e.g., UPS_CLIENT_ID, CANADA_POST_CUSTOMER_NUMBER). Set SHIPPING_SANDBOX=true for testing.

  3. First Use Case: Fetch rates for a shipment via UPS:

    use IvanMitrikeski\Shipping\Facades\Shipping;
    
    $rates = Shipping::rates('ups')
        ->credentials()
        ->setShipper([
            'name' => 'Your Company',
            'address' => '123 Main St',
            // ... other required fields
        ])
        ->setRecipient([
            'name' => 'Recipient Name',
            'address' => '456 Oak Ave',
        ])
        ->setPackage([
            'weight' => 2.0, // in lbs
            'dimensions' => ['length' => 10, 'width' => 5, 'height' => 5],
        ])
        ->get();
    

Implementation Patterns

Core Workflows

  1. Rate Calculation: Chain methods to build a request, then call get():

    $rates = Shipping::rates('fedex')
        ->credentials()
        ->setShipper($shipperData)
        ->setRecipient($recipientData)
        ->setPackages([$package1, $package2]) // Array for multi-package shipments
        ->get();
    
    • Tip: Use ->sandbox() for testing without modifying .env.
  2. Shipment Creation: For providers supporting shipment APIs (UPS, FedEx, etc.):

    $shipment = Shipping::shipment('ups')
        ->credentials()
        ->setShipper($shipperData)
        ->setRecipient($recipientData)
        ->setPackages([$package])
        ->setService('01') // UPS Ground
        ->create();
    
  3. Provider-Specific Logic:

    • USPS: Only supports rate APIs (no shipment tracking). Use Shipping::rates('usps').
    • Canada Post/Purolator: Require billing/account numbers. Validate these in .env early.
  4. Reusable Credentials: Store provider credentials in a config file or database for dynamic switching:

    $credentials = config('shipping.providers.ups');
    $rates = Shipping::rates('ups')
        ->credentials($credentials)
        ->get();
    
  5. Handling Responses: Iterate over rate results:

    foreach ($rates as $rate) {
        echo $rate->service . ': ' . $rate->rate->amount . ' ' . $rate->rate->currency;
    }
    

Integration Tips

  1. Laravel Services: Bind the package to a service container for dependency injection:

    $this->app->singleton(Shipping::class, function ($app) {
        return new \IvanMitrikeski\Shipping\ShippingManager();
    });
    
  2. API Caching: Cache rate responses to reduce API calls (e.g., for cart pages):

    $rates = Cache::remember("shipping_rates_{$cacheKey}", now()->addHours(1), function () {
        return Shipping::rates('ups')->get();
    });
    
  3. Validation: Validate package dimensions/weights before API calls:

    $validator = Validator::make($request->all(), [
        'weight' => 'required|numeric|min:0.1',
        'dimensions.length' => 'required|numeric|min:1',
    ]);
    
  4. Logging: Log API responses for debugging:

    Shipping::rates('ups')
        ->setLogger(app(\Monolog\Logger::class))
        ->get();
    
  5. Queueable Jobs: Offload shipment creation to a queue for long-running processes:

    CreateShipmentJob::dispatch($shipmentData)->onQueue('shipping');
    

Gotchas and Tips

Pitfalls

  1. Sandbox vs. Production:

    • Issue: Forgetting to toggle SHIPPING_SANDBOX between environments.
    • Fix: Use environment-specific .env files or a config override:
      if (app()->environment('local')) {
          config(['shipping.sandbox' => true]);
      }
      
  2. Provider-Specific Quirks:

    • USPS: Requires a Commercial Plus account for accurate rates. Sandbox credentials may not reflect live pricing.
    • Canada Post/Purolator: Reject requests with missing billing_account or registered_account. Validate these early.
    • UPS/FedEx: OAuth tokens expire. Implement token refresh logic or use the package’s built-in retry mechanism.
  3. Rate Limiting:

    • Issue: API providers throttle requests (e.g., USPS blocks after 5 calls/minute).
    • Fix: Implement exponential backoff or use a queue:
      try {
          $rates = Shipping::rates('usps')->get();
      } catch (\IvanMitrikeski\Shipping\Exceptions\RateLimitException $e) {
          sleep(10);
          retry();
      }
      
  4. Currency/Unit Mismatches:

    • Issue: Providers expect weights in lbs (USPS) or kg (Canada Post). Convert units before sending:
      $weightKg = $weightLbs * 0.453592;
      
  5. Missing Required Fields:

    • Debugging: Check the provider’s API docs for hidden fields (e.g., UPS requires shipmentType).
    • Tip: Use dd($rate->toArray()) to inspect the full response structure.

Debugging Tips

  1. Enable Verbose Logging:

    Shipping::setLogLevel(\Monolog\Logger::DEBUG);
    

    Check logs at storage/logs/laravel.log.

  2. Inspect Raw API Responses: Override the provider’s HTTP client to log requests:

    Shipping::extend('ups', function ($app) {
        $client = new \GuzzleHttp\Client([
            'handler' => \GuzzleHttp\HandlerStack::create([
                'debug' => function ($handler) {
                    return function ($request, $options) use ($handler) {
                        \Log::debug('API Request:', [$request->getUri(), $request->getBody()]);
                        return $handler($request, $options);
                    };
                },
            ]),
        ]);
        return new \IvanMitrikeski\Shipping\Providers\Ups\UpsService($client);
    });
    
  3. Common Errors:

    • InvalidCredentialsException: Double-check .env values (e.g., UPS_ACCOUNT_NUMBER format).
    • ValidationException: Use ->validate() to check inputs before API calls.
    • ConnectionException: Ensure SHIPPING_SANDBOX matches your endpoint (e.g., sandbox.ups.com).

Extension Points

  1. Custom Providers: Extend the package by creating a new provider class:

    namespace App\Shipping\Providers;
    
    use IvanMitrikeski\Shipping\Contracts\Provider;
    
    class DHLService implements Provider {
        public function getRates(array $data) {
            // Custom logic
        }
    }
    

    Register it in config/shipping.php:

    'providers' => [
        'dhl' => \App\Shipping\Providers\DHLService::class,
    ],
    
  2. Modify Request/Response: Override the default HTTP client or response parser:

    Shipping::extend('ups', function ($app) {
        return new \IvanMitrikeski\Shipping\Providers\Ups\UpsService(
            $app->make(\GuzzleHttp\Client::class),
            new \App\Shipping\Parsers\CustomUpsParser()
        );
    });
    
  3. Add Custom Fields: Extend the Shipment model or use accessors:

    // app/Models/Shipment.php
    public function getTrackingUrlAttribute() {
        return $this->provider->getTrackingUrl($this->tracking_number);
    }
    
  4. Webhook Handling: For real-time updates (e.g., FedEx shipment status), create a controller:

    public function handleWebhook(Request $request) {
        $provider = $request->provider;
        $data = $request->json()->all();
        return Shipping::webhook($provider)->handle($data);
    }
    
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours