laratables / laravel-shipping
A weight-based shipping cost calculator for Laravel with database-driven weight bands, free shipping thresholds, flat-rate fallback and a global on/off toggle.
Requires
- php: ^8.2
- illuminate/cache: ^10.0|^11.0|^12.0|^13.0
- illuminate/database: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0|^11.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
This package is auto-updated.
Last update: 2026-04-07 08:51:31 UTC
README
A weight-based shipping cost calculator for Laravel with database-driven weight bands, free shipping thresholds, flat-rate fallback, and a global on/off toggle.
Requirements
- PHP 8.2+
- Laravel 10, 11, 12 or 13
Note for Laravel 13 users: If you are developing on PHP 8.4 or 8.5 but deploying to a PHP 8.3 environment, add the following to your project's
composer.jsonto prevent Composer pulling Symfony 8 components that require PHP 8.4:"config": { "platform": { "php": "8.3.0" } }This pins dependency resolution to PHP 8.3 so Composer keeps pulling Symfony 7.4 components compatible with your server.
Installation
composer require laratables/laravel-shipping
Publish and run the migration:
php artisan vendor:publish --tag=shipping-migrations php artisan migrate
Publish the config file:
php artisan vendor:publish --tag=shipping-config
Seed the default weight bands:
php artisan vendor:publish --tag=shipping-seeders php artisan db:seed --class=ShippingWeightBandSeeder
Usage
Resolving shipping for a cart
use Laratables\Shipping\Services\ShippingResolver; $result = app(ShippingResolver::class)->resolve( cart: session('cart', []), orderSubtotal: 55.00, ); $result['total_shipping']; // float — final charge $result['is_free_shipping']; // bool $result['free_shipping_info']; // progress bar data $result['breakdown']; // itemised lines
Cart item shape
[
'product_id' => 1,
'name' => 'T-Shirt',
'weight_kg' => 0.5, // null to use flat rate
'shipping_cost' => null, // used when weight_kg is null
'quantity' => 2,
'price' => 19.99,
]
Per-product priority rule
| weight_kg | shipping_cost | Result |
|---|---|---|
| set | any | Algorithm used, shipping_cost ignored |
| null | set | Flat rate used directly |
| null | null | Not shippable, skipped |
Product estimate
$estimate = app(ShippingResolver::class)->estimateForProduct( productId: $product->id, name: $product->name, weightKg: $product->weight_kg, shippingCost: $product->shipping_cost, quantity: 1, );
Using the Facade
use Laratables\Shipping\Facades\Shipping; $result = Shipping::resolve(session('cart', []), $subtotal); $info = Shipping::freeShippingInfo($subtotal);
Configuration
All settings are in config/shipping.php and driven by environment variables:
| Key | .env | Default | Description |
|---|---|---|---|
enabled |
SHIPPING_ENABLED |
true |
Master on/off toggle |
disabled_fallback.mode |
SHIPPING_DISABLED_MODE |
free |
free, flat_rate, or unavailable |
disabled_fallback.flat_rate_amount |
SHIPPING_FLAT_RATE_AMOUNT |
5.99 |
Fixed charge when mode is flat_rate |
base_fee |
SHIPPING_BASE_FEE |
2.50 |
Handling fee on every order |
multi_product_surcharge |
SHIPPING_MULTI_PRODUCT_SURCHARGE |
1.50 |
Added when cart has >1 product line |
heavy_item_threshold_kg |
SHIPPING_HEAVY_ITEM_THRESHOLD_KG |
10.0 |
Line weight that triggers heavy surcharge |
heavy_item_surcharge |
SHIPPING_HEAVY_ITEM_SURCHARGE |
3.00 |
Charge per heavy product line |
max_weight_kg |
SHIPPING_MAX_WEIGHT_KG |
100.0 |
Maximum shippable order weight |
free_enabled |
SHIPPING_FREE_ENABLED |
true |
Enable free shipping threshold |
free_threshold |
SHIPPING_FREE_THRESHOLD |
75.00 |
Subtotal needed for free shipping |
free_weight_limit_kg |
SHIPPING_FREE_WEIGHT_LIMIT_KG |
null |
Max weight still eligible for free shipping |
Weight bands
Bands are stored in shipping_weight_bands and managed from your admin panel. After updating bands, clear the cache:
Cache::forget('shipping_weight_bands');
Disabled modes
SHIPPING_ENABLED=false SHIPPING_DISABLED_MODE=flat_rate SHIPPING_FLAT_RATE_AMOUNT=5.99 SHIPPING_DISABLED_MESSAGE="Flat rate shipping applied"
| Mode | Behaviour |
|---|---|
free |
All orders ship free |
flat_rate |
Fixed charge on every order |
unavailable |
Throws RuntimeException, block checkout |
Testing
composer test
License
MIT