ATU Shipping - A package for Laravel that provides shipping support for your e-commerce website.
vormia-folks/atu-shipping is a Laravel package for atu shipping - a package for laravel that provides shipping support for your e-commerce website..
It currently has 0 GitHub stars and 103 downloads on Packagist (latest version v1.3.2).
Install it with composer require vormia-folks/atu-shipping.
Discover more Laravel packages by vormia-folks
or browse all Laravel packages to compare alternatives.
Last updated
A Laravel package for rule-based shipping fee and shipping tax calculation engine. Designed to work independently or with optional integration to ATU Multi-Currency.
Admin Livewire UI: This package does not declare livewire/livewire in Composer. The copied admin views are Livewire 4 single-file components. Install Livewire 4 in your app—typically it is already required by A2Commerce, or you can add livewire/livewire yourself. See the Livewire 4 documentation.
Optional: For currency conversion helpers, install vormia-folks/atu-multi-currency (^2.0); see Composer suggest.
Before installing ATU Shipping, ensure you have Laravel, Vormia, and A2Commerce installed. See the A2Commerce installation guide for detailed instructions on installing A2Commerce and its dependencies.
composer require vormia-folks/atu-shipping
php artisan atushipping:install
This will automatically install ATU Shipping with all files and configurations:
Automatically Installed:
database/migrations directory (via loadMigrationsFrom() — nothing copied into your app’s database/migrations)database/seeders/ATUShippingSeeder.phpconfig/atu-shipping.phpShippingController copied to app/Http/Controllers/Atu/ShippingController.phpresources/views/livewire/admin/atu/shipping/**.env and .env.exampleroutes/api.php (between START/END markers)auth middleware group of routes/web.phpsidebar.blade.php (if found)Installation Options:
--no-overwrite: Keep existing files instead of replacing them--skip-env: Leave .env files untouchedExample:
# Install without overwriting existing files
php artisan atushipping:install --no-overwrite
# Install without modifying .env files
php artisan atushipping:install --skip-env
Migrations are loaded automatically from inside the package (no copies in
database/migrations), so a plain php artisan migrate is all you need. The
installer prompts to run both for you:
# Run migrations (package-shipped, auto-loaded)
php artisan migrate
# Run seeders to create default couriers
php artisan db:seed --class=ATUShippingSeeder
Upgrading from older releases: If an earlier version of this package copied migration files into your app’s database/migrations/ directory, remove those duplicate *atu_shipping* PHP files after you upgrade. Laravel registers migrations by basename; keeping both the app copies and the package’s loadMigrationsFrom path can cause duplicate-name conflicts.
A later migration, 2026_02_17_100000_alter_atu_shipping_tables_for_4char_currency_codes.php, widens the currency column on atu_shipping_rules and atu_shipping_logs from 3 to 4 characters so you can store ISO 4217 codes and extended 4-character codes (for example with ATU Multi-Currency). It ships inside the package and runs automatically on php artisan migrate.
If production was already altered manually (columns are already CHAR(4) but this migration never ran), add a row to the migrations table so Laravel skips it: set migration to 2026_02_17_100000_alter_atu_shipping_tables_for_4char_currency_codes and use a batch value consistent with your app.
After installation, you can configure the package in config/atu-shipping.php:
return [
'default_origin_country' => env('ATU_SHIPPING_DEFAULT_ORIGIN_COUNTRY', 'ZA'),
'base_currency' => env('ATU_SHIPPING_BASE_CURRENCY', config('a2_commerce.currency', 'USD')),
'enable_logging' => env('ATU_SHIPPING_ENABLE_LOGGING', true),
];
The configuration file includes settings for:
suggest)The following environment variables are added to your .env file during installation:
# ATU Shipping Configuration
ATU_SHIPPING_DEFAULT_ORIGIN_COUNTRY=ZA
ATU_SHIPPING_BASE_CURRENCY=USD
ATU_SHIPPING_ENABLE_LOGGING=true
ATU_SHIPPING_DEFAULT_ORIGIN_COUNTRY: Default origin country code (ISO 3166-1 alpha-2) if not specified when calculating shippingATU_SHIPPING_BASE_CURRENCY: Base currency code for shipping calculations. Falls back to A2 Commerce currency if not setATU_SHIPPING_ENABLE_LOGGING: Reserved for future use (default: true). Selection rows are written when select() runs; the flag does not disable logging in the current releaseGet shipping options for a cart:
use Vormia\ATUShipping\Facades\ATU;
$options = ATU::shipping()
->forCart($cart)
->from('ZA') // Origin country (ISO 3166-1 alpha-2)
->to('KE') // Destination country
->options();
// Returns array of shipping options:
// [
// [
// 'courier' => 'DHL',
// 'fee' => 755.0,
// 'tax' => 120.8,
// 'total' => 875.8,
// 'currency' => 'ZAR',
// 'rule_id' => 12,
// 'tax_rate' => 0.16
// ]
// ]
$shipping = ATU::shipping()
->forOrder($order)
->from('ZA')
->to('KE');
// Get options
$options = $shipping->options();
// Select a courier (logs the selection)
$selected = $shipping->select('DHL');
The package uses a rule-based system where:
Evaluated at runtime (see RuleEvaluator):
applies_per_item on the rule)Stored on the rule but not used by the current evaluator (reserved for future logic or custom extensions):
Details: docs/atu-shipping.md.
The package creates the following tables:
atu_shipping_couriers - Courier informationatu_shipping_rules - Shipping rulesatu_shipping_fees - Fee structuresatu_shipping_logs - Shipping selection logsInstall the package with all necessary files and configurations:
php artisan atushipping:install
Options:
--skip-env: Do not modify .env files--no-overwrite: Skip existing files instead of replacingAutomatically Installed:
database/migrations (nothing copied into your app’s database/migrations)database/seeders/ATUShippingSeeder.phpconfig/atu-shipping.phpShippingController copied to app/Http/Controllers/Atu/ShippingController.phpresources/views/livewire/admin/atu/shipping/**.env and .env.exampleroutes/api.phproutes/web.php (inside the auth middleware group)Example:
# Install without overwriting existing files
php artisan atushipping:install --no-overwrite
# Install without modifying .env files
php artisan atushipping:install --skip-env
Update package files and configurations, refresh migrations and seeders, clear caches:
php artisan atushipping:update
Options:
--skip-env: Do not modify .env files--force: Skip confirmation promptsThis command will:
routes/api.phpExample:
# Update without confirmation
php artisan atushipping:update --force
# Update without modifying .env files
php artisan atushipping:update --skip-env
Remove all package files and configurations:
php artisan atushipping:uninstall
Options:
--keep-env: Preserve environment variables--force: Skip confirmation prompts⚠️ Warning: This will remove all ATU Shipping files and optionally drop database tables. A backup will be created in storage/app/atushipping-final-backup-{timestamp}/.
Example:
# Uninstall without confirmation
php artisan atushipping:uninstall --force
# Uninstall but keep environment variables
php artisan atushipping:uninstall --keep-env
Note: The uninstall command will:
routes/api.php, routes/web.php, and the Flux sidebar (when present)atu_shipping_* tables and prune this package’s rows from the migrations table (migration PHP stays in vendor/ until you run composer remove)After uninstalling, you'll need to manually remove the package from composer:
composer remove vormia-folks/atu-shipping
Display help information and usage examples:
php artisan atushipping:help
After installing the base package, you can set up the admin UI components for managing shipping couriers, rules, and logs. The package includes reference files and view stubs that show you exactly what routes, menu items, and views to add.
The package includes Livewire view files in vendor/vormia-folks/atu-shipping/src/stubs/resources/views/livewire/admin/atu/shipping/:
couriers/index.blade.php, couriers/create.blade.php, couriers/edit.blade.phprules/index.blade.php, rules/create.blade.php, rules/edit.blade.phplogs/index.blade.phpCopy these files to your resources/views/livewire/admin/atu/shipping/ directory to use the admin UI.
The package provides reference files in vendor/vormia-folks/atu-shipping/src/stubs/reference/:
admin-routes-to-add.php - Admin routes for managing couriers, rules, and logsroutes-to-add.php - API routes for calculating shipping options (optional)sidebar-menu-to-add.blade.php - Sidebar menu items for the admin panelAdd the following routes to your admin routes file (e.g., routes/admin.php or routes/web.php with admin middleware):
Route::prefix('admin/atu/shipping')->name('admin.atu.shipping.')->group(function () {
// Couriers — second argument is the Livewire view name (see resources/views/livewire/...)
Route::livewire('couriers', 'admin.atu.shipping.couriers.index')->name('couriers.index');
Route::livewire('couriers/create', 'admin.atu.shipping.couriers.create')->name('couriers.create');
Route::livewire('couriers/{id}/edit', 'admin.atu.shipping.couriers.edit')->name('couriers.edit');
// Rules
Route::livewire('rules', 'admin.atu.shipping.rules.index')->name('rules.index');
Route::livewire('rules/create', 'admin.atu.shipping.rules.create')->name('rules.create');
Route::livewire('rules/{id}/edit', 'admin.atu.shipping.rules.edit')->name('rules.edit');
// Logs
Route::livewire('logs', 'admin.atu.shipping.logs.index')->name('logs.index');
});
Note: Route::livewire() is provided by Livewire 4. See Livewire routing and components.
If you need API endpoints for calculating shipping options, add these routes to routes/api.php:
Route::prefix('atu/shipping')->group(function () {
// Calculate shipping options for a cart
Route::post('/calculate', [
\App\Http\Controllers\Atu\ShippingController::class,
'calculate'
])->name('api.shipping.calculate');
// Get shipping options for a cart
Route::get('/options', [
\App\Http\Controllers\Atu\ShippingController::class,
'options'
])->name('api.shipping.options');
// Select shipping courier for an order
Route::post('/select', [
\App\Http\Controllers\Atu\ShippingController::class,
'select'
])->name('api.shipping.select');
});
Note: The ShippingController class is automatically copied to app/Http/Controllers/Atu/ShippingController.php during installation. You'll need to implement the resolveCart() and resolveOrder() methods based on your application's Cart and Order models.
/atu/shipping/calculateCalculate shipping options for a cart.
Request Body:
{
"cart_id": 123,
"from": "ZA",
"to": "KE"
}
Response (200 OK):
{
"success": true,
"data": [
{
"courier": "DHL",
"fee": 755.0,
"tax": 120.8,
"total": 875.8,
"currency": "ZAR",
"rule_id": 12,
"tax_rate": 0.16
}
]
}
Error Response (422 Validation Error):
{
"success": false,
"message": "Validation failed",
"errors": {
"cart_id": ["The cart id field is required."],
"from": ["The from field is required."]
}
}
/atu/shipping/optionsGet shipping options for a cart (same as calculate but via GET request).
Query Parameters:
cart_id (required): Cart IDfrom (required): Origin country code (ISO 3166-1 alpha-2)to (required): Destination country code (ISO 3166-1 alpha-2)Example Request:
GET /atu/shipping/options?cart_id=123&from=ZA&to=KE
Response: Same format as POST /calculate
/atu/shipping/selectSelect a shipping courier for an order and log the selection.
Request Body:
{
"order_id": 456,
"courier": "DHL",
"from": "ZA",
"to": "KE"
}
Note: from and to are optional. If not provided, the order's default origin and destination countries will be used (if available via OrderInterface methods).
Response (200 OK):
{
"success": true,
"data": {
"fee": 755.0,
"tax": 120.8,
"total": 875.8,
"currency": "ZAR"
}
}
Error Response (400 Bad Request):
{
"success": false,
"message": "Failed to select courier. No matching rule found or courier is not available."
}
The installer automatically injects the menu below into your Flux sidebar blade
(at resources/views/layouts/app/sidebar.blade.php or
resources/views/components/layouts/app/sidebar.blade.php). The injected block is
fenced by markers so atushipping:uninstall can remove it cleanly.
If your sidebar lives elsewhere, copy this manually from
vendor/vormia-folks/atu-shipping/src/stubs/reference/sidebar-menu-to-add.blade.php:
{{-- >>> ATU Shipping Sidebar START --}}
<flux:sidebar.item icon="truck" :href="route('admin.atu.shipping.couriers.index')" wire:navigate>
{{ __('Shipping couriers') }}
</flux:sidebar.item>
<flux:sidebar.item icon="rectangle-stack" :href="route('admin.atu.shipping.rules.index')" wire:navigate>
{{ __('Shipping rules') }}
</flux:sidebar.item>
<flux:sidebar.item icon="clipboard-document-list" :href="route('admin.atu.shipping.logs.index')" wire:navigate>
{{ __('Shipping logs') }}
</flux:sidebar.item>
{{-- >>> ATU Shipping Sidebar END --}}
The package uses flux:sidebar.item (not flux:navlist.item) to match the
default Flux admin sidebar from vormiaphp/ui-livewireflux-admin.
Reference Files:
vendor/vormia-folks/atu-shipping/src/stubs/reference/admin-routes-to-add.phpvendor/vormia-folks/atu-shipping/src/stubs/reference/routes-to-add.phpvendor/vormia-folks/atu-shipping/src/stubs/reference/shipping-controller.phpvendor/vormia-folks/atu-shipping/src/stubs/reference/sidebar-menu-to-add.blade.phpThe package uses interfaces for cart and order contexts:
Vormia\ATUShipping\Contracts\CartInterfaceVormia\ATUShipping\Contracts\OrderInterfaceYour cart and order models should implement these interfaces to work with ATU Shipping.
When you call select() on the shipping service, a row is written to atu_shipping_logs on success (failures are caught and reported to Laravel’s log). Typical call sites:
select()The enable_logging entry in config/atu-shipping.php is kept for forward compatibility; today’s package does not skip logging based on that flag. If you need toggled logging, wrap select() in your application or extend ShippingService.
Logs are stored in the atu_shipping_logs table and include:
Optional package vormia-folks/atu-multi-currency is listed under Composer suggest. The shipping fee calculator includes a conversion hook (FeeCalculator::convertCurrency()) that detects Multi-Currency classes but does not yet apply live conversion in core flows—amounts stay in the rule’s currency (or A2 Commerce default). Implement conversion in your app or extend the calculator if you need cross-currency totals. See docs/atu-shipping.md.
ATU Shipping does NOT:
To completely remove the package:
# Uninstall package files and optionally drop tables
php artisan atushipping:uninstall
# Remove from composer
composer remove vormia-folks/atu-shipping
Note: The uninstall command will:
routes/api.php, routes/web.php, and the Flux sidebar (when present)atu_shipping_* tables and prune this package’s migration rows (files under vendor/ remain until composer remove)Backup Location: A final backup is created in storage/app/atushipping-final-backup-{timestamp}/ containing:
config/atu-shipping.php)routes/api.php).env)MIT
For detailed implementation guides and architecture documentation, see:
If migrations fail:
If options() returns an empty array:
CartInterface or OrderInterface)If a rule is not being applied:
Contributions are welcome! Please feel free to submit a Pull Request.
For issues, questions, or contributions:
Package constant Vormia\ATUShipping\ATUShipping::VERSION tracks the in-code release label (use Git tags as the source of truth for Composer installs; this repository does not duplicate a version field in composer.json).
Built with ❤️ for the A2 Commerce ecosystem