Looking to hire Laravel developers? Try LaraJobs

laravel-courier-bd maintained by shipkit-bd

Description
Unified Bangladeshi Courier Package for Laravel (Pathao, RedX, Steadfast)
Last update
2026/09/20 16:34 (dev-master)
License
Downloads
5

Comments
comments powered by Disqus

Laravel Courier BD (Shipkit) 📦

Latest Version on Packagist Total Downloads License PHP Version Laravel Version

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, ReturnPending tracking 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.