pathao-courier
v1.0.2
Published
TypeScript SDK for Pathao Courier Merchant API with comprehensive webhook support
Downloads
87
Readme
Pathao Courier SDK
A modern, type-safe TypeScript SDK for the Pathao Courier Merchant API with comprehensive webhook support.
Features
- ✅ Full TypeScript Support - Complete type definitions for all API endpoints
- ✅ OAuth 2.0 Authentication - Automatic token management and refresh
- ✅ Webhook Handling - Built-in webhook handlers for Express, Fastify, and generic frameworks
- ✅ Input Validation - Automatic validation of request parameters
- ✅ Error Handling - Custom error classes with detailed error messages
- ✅ Framework Agnostic - Works with any Node.js framework
- ✅ Tree-shakeable - Optimized for bundle size
- ✅ Well Documented - Comprehensive documentation and examples
Installation
# npm
npm install pathao-courier
# yarn
yarn add pathao-courier
# pnpm
pnpm add pathao-courier⚠️ TypeScript Configuration Required
If you're using TypeScript and importing from 'pathao-courier/webhooks', you must update your tsconfig.json:
{
"compilerOptions": {
"moduleResolution": "node16" // or "nodenext" or "bundler"
}
}Without this, you'll get: Cannot find module 'pathao-courier/webhooks'
See TypeScript Support section for more details.
Quick Start
Basic Usage
import { PathaoClient } from 'pathao-courier';
// Initialize the client
const client = new PathaoClient({
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
username: '[email protected]',
password: 'your-password',
environment: 'sandbox', // or 'production'
});
// Create a store
const store = await client.stores.create({
name: 'My Store',
contact_name: 'John Doe',
contact_number: '01712345678',
address: 'House 123, Road 4, Sector 10, Uttara, Dhaka-1230, Bangladesh',
city_id: 1,
zone_id: 298,
area_id: 37,
});
// Create an order
const order = await client.orders.create({
store_id: 123456,
merchant_order_id: 'ORD-12345',
recipient_name: 'Jane Smith',
recipient_phone: '01787654321',
recipient_address: 'House 456, Road 8, Dhanmondi, Dhaka-1205, Bangladesh',
delivery_type: 48, // Normal Delivery
item_type: 2, // Parcel
item_quantity: 1,
item_weight: 0.5,
amount_to_collect: 1000,
});
console.log(`Order created: ${order.data.consignment_id}`);
// Get order info
const orderInfo = await client.orders.getInfo(order.data.consignment_id);
console.log(`Status: ${orderInfo.data.order_status}`);
// Calculate price
const price = await client.pricing.calculate({
store_id: 123456,
item_type: 2,
delivery_type: 48,
item_weight: 0.5,
recipient_city: 1,
recipient_zone: 298,
});
console.log(`Delivery fee: ${price.data.final_price} BDT`);API Reference
Complete API Methods Table
| Service | Method | Description | Parameters | Returns |
| ------------------- | -------------------------- | -------------------------------- | ---------------------------- | ----------------------------- |
| Stores | create | Create a new store | CreateStoreRequest | CreateStoreResponse |
| | list | Get list of stores | - | StoreListResponse |
| Orders | create | Create a single order | CreateOrderRequest | CreateOrderResponse |
| | createBulk | Create multiple orders | BulkOrderRequest | BulkOrderResponse |
| | getInfo | Get order info by consignment ID | consignmentId: string | OrderInfoResponse |
| Locations | getCities | Get list of all cities | - | CityListResponse |
| | getZones | Get zones for a city | cityId: number | ZoneListResponse |
| | getAreas | Get areas for a zone | zoneId: number | AreaListResponse |
| Pricing | calculate | Calculate delivery price | PriceCalculationRequest | PriceCalculationResponse |
Webhook Utilities Table
| Utility | Description | Framework | Returns |
| -------------------------------------- | ---------------------------------- | --------- | ----------------------------------- |
| PathaoWebhookHandler | Main webhook handler class | Any | Class instance |
| createPathaoExpressWebhookHandler | Express.js middleware for webhooks | Express | (req, res, next) => Promise<void> |
| createPathaoFastifyWebhookHandler | Fastify route handler for webhooks | Fastify | (req, reply) => Promise<void> |
| createPathaoGenericWebhookHandler | Generic handler for any framework | Any | (req, res) => Promise<void> |
Webhook Handler Methods
| Method | Description | Parameters | Returns |
| ------------------ | ---------------------------------------- | ---------------------------------------- | -------------------------- |
| handle | Process webhook payload | body: unknown, authHeader?: string | Promise<WebhookResponse> |
| express | Get Express middleware handler | - | Express middleware |
| fastify | Get Fastify route handler | - | Fastify handler |
| generic | Get generic framework handler | - | Generic handler |
| onOrderCreated | Set handler for order.created webhooks | handler: (payload) => void | this |
| onOrderDelivered | Set handler for order.delivered webhooks | handler: (payload) => void | this |
| on | Listen to webhook events (EventEmitter) | event: PathaoWebhookEvent, listener | this |
Error Classes Table
| Error Class | Description | Properties |
| ------------------------------ | ----------------------------------------- | --------------------------------------------------------- |
| PathaoError | Base error class for all Pathao errors | message: string, statusCode?: number, code?: string |
| PathaoApiError | API request/response errors | message: string, statusCode: number, response?: unknown |
| PathaoValidationError | Input validation errors | message: string, field?: string |
| PathaoAuthError | Authentication errors | message: string |
| PathaoWebhookError | Webhook processing errors | message: string |
Type Definitions & Enums
| Category | Name | Description |
| ------------------ | ---------------------------------- | --------------------------------------------------------------------------------------------------------- |
| Enums | PathaoWebhookEvent | Webhook event names (WEBHOOK, ORDER_CREATED, ORDER_DELIVERED, etc., ERROR) |
| | DeliveryType | Delivery type values (Normal = 48, OnDemand = 12) |
| | ItemType | Item type values (Document = 1, Parcel = 2) |
| Request Types | CreateStoreRequest | Store creation request payload |
| | CreateOrderRequest | Order creation request payload |
| | BulkOrderRequest | Bulk order creation payload |
| | PriceCalculationRequest | Price calculation request payload |
| Response Types | CreateStoreResponse | Store creation response |
| | CreateOrderResponse | Order creation response |
| | OrderInfoResponse | Order info response |
| | WebhookResponse | Webhook processing response |
| Webhook Types | OrderCreatedWebhook | Order created webhook payload |
| | OrderDeliveredWebhook | Order delivered webhook payload |
| | WebhookPayload | Union type for all webhook payloads |
Validation Utilities
| Function | Description | Parameters | Throws |
| -------------------------- | ---------------------------------------------------------------- | ----------------------------------- | -------------------------- |
| validateStoreName | Validate store name (3-50 chars) | name: string | PathaoValidationError |
| validateContactName | Validate contact name (3-50 chars) | name: string | PathaoValidationError |
| validatePhoneNumber | Validate phone number (11 digits) | phone: string, fieldName?: string | PathaoValidationError |
| validateRecipientName | Validate recipient name (3-100 chars) | name: string | PathaoValidationError |
| validateRecipientAddress | Validate recipient address (10-220 chars) | address: string | PathaoValidationError |
| validateItemWeight | Validate item weight (0.5-10 kg) | weight: number \| string | PathaoValidationError |
| validateItemQuantity | Validate item quantity (positive integer) | quantity: number | PathaoValidationError |
| validateAmountToCollect | Validate amount to collect (non-negative) | amount: number | PathaoValidationError |
API Reference
Stores
Create Store
const store = await client.stores.create({
name: 'My Store', // Required: 3-50 characters
contact_name: 'John Doe', // Required: 3-50 characters
contact_number: '01712345678', // Required: 11 digits
secondary_contact: '01512345678', // Optional: 11 digits
otp_number: '01712345678', // Optional: 11 digits
address: 'House 123, Road 4, Sector 10, Uttara, Dhaka-1230, Bangladesh', // Required: 15-120 characters
city_id: 1, // Required
zone_id: 298, // Required
area_id: 37, // Required
});List Stores
const stores = await client.stores.list();
console.log(`Total stores: ${stores.data.total}`);Orders
Create Single Order
const order = await client.orders.create({
store_id: 123456, // Required
merchant_order_id: 'ORD-12345', // Optional
recipient_name: 'Jane Smith', // Required: 3-100 characters
recipient_phone: '01787654321', // Required: 11 digits
recipient_secondary_phone: '01587654321', // Optional: 11 digits
recipient_address: 'House 456, Road 8, Dhanmondi, Dhaka-1205, Bangladesh', // Required: 10-220 characters
recipient_city: 1, // Optional (auto-detected if not provided)
recipient_zone: 298, // Optional (auto-detected if not provided)
recipient_area: 37, // Optional (auto-detected if not provided)
delivery_type: 48, // Required: 48 = Normal, 12 = On Demand
item_type: 2, // Required: 1 = Document, 2 = Parcel
special_instruction: 'Handle with care', // Optional
item_quantity: 1, // Required: positive integer
item_weight: 0.5, // Required: 0.5-10 kg
item_description: 'Electronics', // Optional
amount_to_collect: 1000, // Required: non-negative integer
});Create Bulk Orders
const orders = await client.orders.createBulk({
orders: [
{
store_id: 123456,
recipient_name: 'John Doe',
recipient_phone: '01712345678',
recipient_address: '123 Main St, Dhaka',
delivery_type: 48,
item_type: 2,
item_quantity: 1,
item_weight: 0.5,
amount_to_collect: 1000,
},
{
store_id: 123456,
recipient_name: 'Jane Smith',
recipient_phone: '01787654321',
recipient_address: '456 Oak Ave, Dhaka',
delivery_type: 48,
item_type: 2,
item_quantity: 1,
item_weight: 0.5,
amount_to_collect: 2000,
},
],
});Get Order Info
const orderInfo = await client.orders.getInfo('DL121224VS8TTJ');
console.log(`Status: ${orderInfo.data.order_status}`);Locations
Get Cities
const cities = await client.locations.getCities();
console.log(`Available cities: ${cities.data.data.length}`);Get Zones
const zones = await client.locations.getZones(1); // City ID
console.log(`Available zones: ${zones.data.data.length}`);Get Areas
const areas = await client.locations.getAreas(298); // Zone ID
console.log(`Available areas: ${areas.data.data.length}`);Pricing
Calculate Price
const price = await client.pricing.calculate({
store_id: 123456,
item_type: 2, // Parcel
delivery_type: 48, // Normal Delivery
item_weight: 0.5, // kg
recipient_city: 1,
recipient_zone: 298,
});
console.log(`Delivery fee: ${price.data.final_price} BDT`);
console.log(`Base price: ${price.data.price} BDT`);
console.log(`Discount: ${price.data.discount} BDT`);Webhook Integration
The SDK provides comprehensive webhook handling utilities to help you build webhook endpoints quickly.
Express.js Example
Recommended: Use handler instance directly
import express from 'express';
import { PathaoWebhookHandler, PathaoWebhookEvent } from 'pathao-courier/webhooks';
const app = express();
app.use(express.json());
// Create handler instance and set up callbacks
const webhookHandler = new PathaoWebhookHandler({
webhookSecret: 'your-webhook-secret',
integrationSecret: 'f3992ecc-59da-4cbe-a049-a13da2018d51', // For test responses
});
webhookHandler.onOrderCreated(async (payload) => {
console.log('Order created:', payload);
// Handle order creation
// e.g., update database, send notification, etc.
});
webhookHandler.onOrderDelivered(async (payload) => {
console.log('Order delivered:', payload);
// Handle delivery completion
});
// Use the handler directly as Express route handler
app.post('/pathao-webhook', webhookHandler.express());Alternative: Using adapter function
import express from 'express';
import { createPathaoExpressWebhookHandler } from 'pathao-courier/webhooks';
const app = express();
app.use(express.json());
const webhookHandler = createPathaoExpressWebhookHandler({
webhookSecret: 'your-webhook-secret',
});
app.post('/pathao-webhook', webhookHandler);Fastify Example
Recommended: Use handler instance directly
import Fastify from 'fastify';
import { PathaoWebhookHandler } from 'pathao-courier/webhooks';
const fastify = Fastify();
// Create handler instance and set up callbacks
const webhookHandler = new PathaoWebhookHandler({
webhookSecret: 'your-webhook-secret',
});
webhookHandler.onOrderDelivered(async (payload) => {
console.log('Order delivered:', payload);
});
// Use the handler directly as Fastify route handler
fastify.post('/pathao-webhook', webhookHandler.fastify());Alternative: Using adapter function
import Fastify from 'fastify';
import { createPathaoFastifyWebhookHandler } from 'pathao-courier/webhooks';
const fastify = Fastify();
const webhookHandler = createPathaoFastifyWebhookHandler({
webhookSecret: 'your-webhook-secret',
});
fastify.post('/pathao-webhook', webhookHandler);Generic Framework Example
Recommended: Use handler instance directly
import { PathaoWebhookHandler } from 'pathao-courier/webhooks';
// Create handler instance and set up callbacks
const webhookHandler = new PathaoWebhookHandler({
webhookSecret: 'your-webhook-secret',
});
webhookHandler.onOrderDelivered(async (payload) => {
console.log('Order delivered:', payload);
});
// Use with any framework
app.post('/pathao-webhook', async (req, res) => {
await webhookHandler.generic()(req, res);
});Manual Webhook Handling
import { PathaoWebhookHandler, PathaoWebhookEvent } from 'pathao-courier/webhooks';
const handler = new PathaoWebhookHandler({
webhookSecret: 'your-webhook-secret',
});
// Set up event listeners using PathaoWebhookEvent enum
handler.on(PathaoWebhookEvent.WEBHOOK, (payload) => {
console.log('Received webhook:', payload);
});
handler.on(PathaoWebhookEvent.ORDER_CREATED, (payload) => {
console.log('Order created:', payload);
});
handler.on(PathaoWebhookEvent.ORDER_DELIVERED, (payload) => {
console.log('Order delivered:', payload);
});
handler.on(PathaoWebhookEvent.ERROR, (error) => {
console.error('Webhook error:', error);
});
// Process webhook
const result = await handler.handle(request.body, request.headers['x-pathao-signature']);
if (result.status === 'success') {
// Webhook processed successfully
} else {
// Handle error
console.error(result.message);
}Webhook Events
The PathaoWebhookHandler emits events that you can listen to using the PathaoWebhookEvent enum:
PathaoWebhookEvent.WEBHOOK- Emitted for any Pathao webhook payload after successful parsing and authenticationPathaoWebhookEvent.ORDER_CREATED- Emitted when an order is createdPathaoWebhookEvent.ORDER_DELIVERED- Emitted when an order is deliveredPathaoWebhookEvent.ORDER_PICKED- Emitted when an order is picked upPathaoWebhookEvent.STORE_CREATED- Emitted when a store is createdPathaoWebhookEvent.ERROR- Emitted when an error occurs during webhook processing
import { PathaoWebhookHandler, PathaoWebhookEvent } from 'pathao-courier/webhooks';
const handler = new PathaoWebhookHandler({ webhookSecret: 'your-webhook-secret' });
// Listen to all webhooks
handler.on(PathaoWebhookEvent.WEBHOOK, (payload) => {
console.log('Any Pathao webhook received:', payload);
});
// Listen to specific webhook types
handler.on(PathaoWebhookEvent.ORDER_DELIVERED, (payload) => {
// payload is typed as OrderDeliveredWebhook
console.log('Consignment ID:', payload.consignment_id);
console.log('Collected Amount:', payload.collected_amount);
});
// Handle errors
handler.on(PathaoWebhookEvent.ERROR, (error) => {
console.error('Pathao webhook processing error:', error);
});Webhook Payload Types
The SDK provides TypeScript types for webhook payloads:
import type {
OrderCreatedWebhook,
OrderDeliveredWebhook,
WebhookPayload,
} from 'pathao-courier';
// Type-safe webhook handling
handler.onOrderDelivered((payload: OrderDeliveredWebhook) => {
// payload is fully typed
console.log(payload.consignment_id);
console.log(payload.collected_amount);
console.log(payload.event); // Type: "order.delivered"
});Token Management
The SDK automatically manages OAuth 2.0 tokens, including automatic refresh. You can optionally provide callbacks for custom token storage:
import { PathaoClient } from 'pathao-courier';
import type { StoredToken } from 'pathao-courier';
// Custom token storage
const client = new PathaoClient({
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
username: '[email protected]',
password: 'your-password',
environment: 'sandbox',
onTokenUpdate: async (token: StoredToken) => {
// Save token to database
await db.saveToken(token);
},
onTokenLoad: async (): Promise<StoredToken | null> => {
// Load token from database
return await db.loadToken();
},
});Error Handling
The SDK provides custom error classes for better error handling:
import {
PathaoError,
PathaoApiError,
PathaoValidationError,
PathaoAuthError,
PathaoWebhookError,
} from 'pathao-courier';
try {
await client.orders.create(orderData);
} catch (error) {
if (error instanceof PathaoValidationError) {
console.error('Validation error:', error.message);
console.error('Field:', error.field);
} else if (error instanceof PathaoApiError) {
console.error('API error:', error.message);
console.error('Status code:', error.statusCode);
} else if (error instanceof PathaoAuthError) {
console.error('Authentication error:', error.message);
} else if (error instanceof PathaoError) {
console.error('Pathao error:', error.message);
}
}TypeScript Support
The SDK is written in TypeScript and provides full type definitions.
Module Resolution
If you encounter module resolution errors when importing from 'pathao-courier/webhooks', ensure your tsconfig.json uses one of these moduleResolution settings:
"node16"(recommended for Node.js projects)"nodenext"(recommended for modern Node.js projects)"bundler"(recommended for bundler-based projects)
Example tsconfig.json:
{
"compilerOptions": {
"moduleResolution": "node16"
// ... other options
}
}Type Definitions
The SDK provides full type definitions:
import type {
CreateOrderRequest,
CreateOrderResponse,
OrderInfoResponse,
WebhookPayload,
} from 'pathao-courier';
// All types are exported and available
const orderRequest: CreateOrderRequest = {
// TypeScript will autocomplete and validate
};Development
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Lint
npm run lint
# Format code
npm run format
# Generate documentation
npm run docsLicense
MIT
Support
For API documentation and support, please visit the Pathao Courier Portal.
