shipkit-bd / laravel-courier-bd
Unified Bangladeshi Courier Package for Laravel (Pathao, RedX, Steadfast)
Requires
- php: ^8.1
- illuminate/database: ^10.0|^11.0
- illuminate/http: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0|^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-20 14:36:50 UTC
README
A unified Laravel package that provides a single, consistent driver-based API interface for integrating multiple Bangladeshi courier services: Steadfast, Pathao, RedX, eCourier, and Paperfly.
Built with first-class support for SaaS E-Commerce platforms, Cloud POS retail outlets, and Multi-Vendor Marketplaces.
Key Features
- ๐ 5 Unified Couriers: Steadfast, Pathao, RedX, eCourier, and Paperfly with consistent methods (
createOrder,track,cancelOrder,calculateFee). - ๐ Bangladesh Geo & Location Engine: Built-in 64 Districts, Thanas, and Postal Codes resolver with auto-mapping to Pathao/RedX numeric IDs (
CourierGeo::resolve(...)). - ๐ข SaaS Multi-Tenancy: Isolated runtime credentials per store/tenant without global config race conditions (
Courier::forTenant($tenant)). - ๐ช POS Multi-Branch Pickups: Outlet-specific pickup stores for multi-branch retail cashiers (
pickupStoreId). - ๐ท๏ธ Thermal Shipping Labels & Barcodes: Instant 4x6" sticky label PDFs and Code128 barcodes/SVGs for 80mm POS receipts (
getLabel(...)). - ๐ Reverse Logistics & Fixed Returns: Distinct
Returned,ReturnInTransit,ReturnPendingtracking plus dedicated return orders (createReturnOrder(...)). - ๐ฆ Bulk Order Dispatch: Dispatch 50โ500 parcels in a single batch (
createBulkOrders(...)). - ๐งช Developer Testing Harness: First-class
Courier::fake()with assertion helpers (assertOrderCreated,assertOrderCancelled, etc.). - ๐ก Fee Comparison Engine:
Courier::compareFees($order)dynamically queries all enabled couriers and sorts them from cheapest to most expensive. - ๐ Multi-Tenant Webhooks: Auto-listening endpoints (
/shipkit/webhooks/{courier}and/shipkit/webhooks/{tenant_id}/{courier}) dispatching granular domain events.
Installation
Install the package via Composer:
composer require shipkit-bd/laravel-courier-bd
Publish the configuration file and database migrations:
php artisan shipkit:install
Run database migrations (optional, if automatic shipment logging is enabled):
php artisan migrate
Environment Configuration
Add your courier credentials to your .env file:
COURIER_DEFAULT_DRIVER=steadfast COURIER_AUTO_LOG=true # Steadfast Courier Credentials STEADFAST_SANDBOX=false STEADFAST_API_KEY=your_steadfast_api_key STEADFAST_SECRET_KEY=your_steadfast_secret_key # Pathao Courier Credentials PATHAO_SANDBOX=true PATHAO_CLIENT_ID=your_client_id PATHAO_CLIENT_SECRET=your_client_secret PATHAO_USERNAME=your_merchant_username PATHAO_PASSWORD=your_merchant_password PATHAO_STORE_ID=your_store_id # RedX Courier Credentials REDX_SANDBOX=true REDX_API_TOKEN=your_redx_api_token # eCourier Credentials ECOURIER_SANDBOX=false ECOURIER_APP_KEY=your_ecourier_app_key ECOURIER_SECRET_KEY=your_ecourier_secret_key ECOURIER_USER_ID=your_ecourier_user_id # Paperfly Credentials PAPERFLY_SANDBOX=false PAPERFLY_USERNAME=your_paperfly_username PAPERFLY_PASSWORD=your_paperfly_password PAPERFLY_KEY=your_paperfly_key
Usage Guide
1. Creating a Shipment Order
use Shipkit\CourierBD\Facades\Courier; use Shipkit\CourierBD\DTOs\OrderRequest; $order = new OrderRequest( merchantOrderId: 'INV-2026-001', recipientName: 'Abul Hossain', recipientPhone: '01711223344', recipientAddress: 'House 12, Road 5, Dhanmondi, Dhaka', district: 'Dhaka', thana: 'Dhanmondi', postalCode: '1205', amountToCollect: 1500.00, // COD Amount itemWeight: 1.0, // kg itemDescription: 'Cotton Polo Shirt x 2', specialInstruction: 'Handle with care' ); // Create shipment with default driver $response = Courier::createOrder($order); echo $response->consignmentId; // e.g. ST100200 echo $response->status->label(); // Pending echo $response->trackingUrl; // Tracking URL
2. Multi-Branch POS Pickup
For physical retail POS outlets, specify which branch warehouse the rider must pick up from:
$order = new OrderRequest( merchantOrderId: 'POS-DHK-101', recipientName: 'Karim Ullah', recipientPhone: '01811223344', recipientAddress: 'Agrabad, Chattogram', amountToCollect: 2400.00, pickupStoreId: $outlet->pathao_store_id // Overrides default store ); $response = Courier::via('pathao')->createOrder($order);
3. Thermal Label & Barcode Generation (AWB)
Instant 4x6" PDF label or inline SVG barcode for POS receipts:
$label = Courier::getLabel($consignmentId); echo $label->pdfUrl; // Link to printable PDF label echo $label->barcodeSvg; // Inline SVG ready for 80mm/58mm thermal POS slips
4. Reverse Logistics & Returns
Create customer return/exchange shipments:
use Shipkit\CourierBD\DTOs\ReturnOrderRequest; $returnReq = new ReturnOrderRequest( merchantOrderId: 'RET-001', customerName: 'Rahim', customerPhone: '01711000000', customerAddress: 'Mirpur 10, Dhaka', originalConsignmentId: 'ST100200', reason: 'Size exchange requested' ); $returnResponse = Courier::createReturnOrder($returnReq); echo $returnResponse->returnConsignmentId;
5. Multi-Tenant SaaS Integration
Supply isolated tenant credentials at runtime:
// Using tenant model implementing HasCourierCredentials $response = Courier::forTenant($tenantStore) ->via('steadfast') ->createOrder($order); // Or using on-the-fly config array $customDriver = Courier::withConfig([ 'api_key' => $vendor->steadfast_api_key, 'secret_key' => $vendor->steadfast_secret_key, ], 'steadfast');
6. Bangladesh Geo & Location Engine
use Shipkit\CourierBD\Facades\CourierGeo; $resolved = CourierGeo::resolve( district: 'Chattogram', thana: 'Panchlaish', postalCode: '4203' ); echo $resolved->pathaoCityId; // 2 echo $resolved->pathaoZoneId; // 101 echo $resolved->redxAreaId; // 201 echo $resolved->isInsideDhaka ? 'Yes' : 'No'; // No
7. Fee Comparison Engine โญ
Find the cheapest courier for an order dynamically:
$rates = Courier::compareFees($order); // Automatically dispatch with cheapest courier! $cheapest = $rates[0]['courier']; $response = Courier::via($cheapest)->createOrder($order);
8. Testing with Courier::fake()
Test your checkout flows without making real HTTP requests:
use Shipkit\CourierBD\Facades\Courier; public function test_checkout_creates_shipment(): void { Courier::fake([ 'steadfast' => ['consignmentId' => 'CID-FAKE-01'] ]); // Run your application checkout logic... Courier::assertOrderCreated('steadfast', function ($order) { return $order->amountToCollect === 1500.00; }); Courier::assertOrderNotCreated('pathao'); }
Courier Feature Matrix
| Feature | Steadfast | Pathao | RedX | eCourier | Paperfly |
|---|---|---|---|---|---|
| Order Creation | โ | โ | โ | โ | โ |
| Parcel Tracking | โ | โ | โ | โ | โ |
| Cancellation | โ | โ | โ | โ | โ |
| Fee Calculation | โ | โ | โ | โ | โ |
| Label / AWB | โ | โ | โ | โ | โ |
| Bulk Dispatch | โ | ๐ | ๐ | ๐ | ๐ |
| Reverse Returns | ๐ | ๐ | ๐ | โ | ๐ |
| Balance / COD | โ | ๐ | ๐ | ๐ | ๐ |
| Coverage | 64 Districts | 64 Districts | 64 Districts | 64 Districts | 64 Districts |
(Legend: โ Fully supported via API | ๐ Driver proxy / in development)
Testing
Run tests with PHPUnit:
vendor/bin/phpunit
License
The MIT License (MIT). Please see License File for more information.