Skip to main content
Carriers represent shipping providers and their delivery options. Shopper uses a two-level structure with carriers (the shipping company) and carrier options (specific delivery methods with prices per zone). Shopper provides a flexible shipping system that supports both manual rate configuration and real-time API integration with major carriers like UPS, FedEx, and USPS.

Models

Shopper uses two models to manage shipping: The Carrier model implements Shopper\Core\Models\Contracts\Carrier and uses the HasSlug and HasZones traits. It is not configurable via config/shopper/models.php.

Database Schema

Carrier Table

CarrierOption Table

Shipping Drivers

Shopper uses a driver-based architecture for shipping, similar to Laravel’s Mail or Queue systems. This allows you to connect carriers directly to shipping provider APIs for real-time rate calculation, or use manual rates stored in your database.

Available Drivers

Driver Configuration

All driver credentials are stored in your .env file. Publish the shipping configuration file to customize drivers:
This creates config/shopper/shipping.php:
Add the credentials to your .env file:

Using the Shipping Facade

The Shipping facade provides access to the shipping manager and all registered drivers:

Carrier Driver Integration

The Carrier model provides methods to work with shipping drivers:
When a carrier has a driver assigned, Shopper uses that driver to fetch real-time rates from the carrier’s API. When no driver is assigned (or set to manual), rates come from the CarrierOption records in your database.

Calculating Shipping Rates

The CarrierRateService provides a unified way to get shipping rates, regardless of whether the carrier uses an API driver or manual configuration.

Getting Rates for a Carrier

For carriers with an API driver, rates are fetched from the carrier’s API. For manual carriers, rates come from the CarrierOption records associated with the specified zone.

Getting Rates for a Zone

To get all available shipping rates for a zone across all enabled carriers:

ShippingRate DTO

Both methods return a collection of ShippingRate objects:

Custom Shipping Drivers

Shopper’s shipping system is designed for extensibility. You can create custom drivers for any shipping provider not included by default, such as DHL, Canada Post, Colissimo, or regional carriers.

Creating a Driver

A shipping driver must implement the ShippingDriver contract. The easiest approach is to extend the abstract Driver class, which provides sensible defaults for optional methods. Create your driver class:

The Driver Contract

The ShippingDriver contract defines the following methods: The abstract Driver class provides default implementations for supportsRealTimeRates(), supportsLabels(), and supportsTracking() (all return true), and throws ShippingException::notSupported() for createShipment() and track(). Override these methods as needed for your driver.

Registering the Driver

Register your custom driver in a service provider using the extend method on the Shipping facade:
The closure receives the driver name as a parameter and must return an instance of ShippingDriver. Drivers are resolved lazily, meaning the closure is only called when the driver is first accessed.

Adding Configuration

Add your driver configuration to config/shopper/shipping.php:
Once registered, your driver appears automatically in the carrier form dropdown and can be assigned to carriers like any built-in driver.

Driver Capabilities

The abstract Driver class provides a normalizePackages() helper method that converts between metric and imperial units. This is useful since different carriers expect different unit systems:
Pass 'metric' for carriers expecting centimeters and kilograms, or 'imperial' for those expecting inches and pounds.

Relationships

Carrier Options

Zone (CarrierOption)

Carrier (CarrierOption)

Query Scopes

Price Handling

CarrierOption prices are stored in cents:

Creating Carriers

Manual Carrier

For carriers where you define rates manually in the database:

API-Connected Carrier

For carriers using a shipping driver to fetch real-time rates:
With an API driver, you don’t need to create CarrierOption records. Rates are fetched directly from the carrier’s API when needed.

Free Shipping Option

Retrieving Carriers

Working with Orders

Storefront Example

Checkout Shipping Selection

The origin address for shipping calculations should come from your store’s inventory (warehouse). Shopper uses the Inventory model to represent physical locations where products are stored and shipped from.
If your store has multiple warehouses, you can pass the inventory ID to ship from a specific location. This is useful for selecting the nearest warehouse to the customer or the one with available stock:

Use Cases