Search by

shipkit-bd / laravel-courier-bd

atikhasan2090

Unified Bangladeshi Courier Package for Laravel (Pathao, RedX, Steadfast)

Package info

github.com/atikhasan2090/laravel-courier-bd

pkg:composer/shipkit-bd/laravel-courier-bd

Statistics

Installs: 5

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v2.0.0 2026-09-20 14:34 UTC

This package is auto-updated.

Last update: 2026-09-20 14:36:50 UTC


README

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.