Skip to content

COD Management Service

The COD Management Service is a dedicated microservice for managing Cash on Delivery (COD) orders, shipments, remittances, disputes, and partner integrations. It serves as the central hub for tracking the lifecycle of COD payments from order creation to final settlement.

Features

  • Order Management: Create and track COD orders with multi-shipment support.
  • Financial Reconciliation: Track expected vs. collected vs. remitted amounts.
  • Settlement: Support for manual and bulk settlement of orders.
  • Dispute Management: Raise and track disputes for discrepancies in collections or remittances.
  • Partner Integration: Webhooks for real-time updates from logistics partners (e.g., Delhivery).
  • Search & Filtering: diverse filtering options for reporting and dashboards.

API Documentation

Base URL

All endpoints are prefixed with /gateway/cod.

Authentication

Most endpoints require the following headers for identifying the tenant and user:

  • x-tenant-id: The UUID of the tenant.
  • x-user-id: The UUID of the authenticated user.
  • Authorization OR api-key: Required for authentication.

1. Health Check

Endpoint: GET /gateway/cod/ping
Access: Public
Description: Simple health check to verify service availability.

Response:

{
"status": "ok",
"message": "pong",
"timestamp": "2024-02-05T12:00:00.000Z"
}

2. Create COD Order

Endpoint: POST /gateway/cod/create
Access: Authenticated
Description: Creates a new COD order. This process involves:

  1. Validating the partner and their remittance configuration.
  2. creating the order locally.
  3. Pushing the order to the external Delivery Vertical/Partner API.

Request Body:

{
"orderId": "PRG-ORD-1001",
"codAmount": 1299.00,
"currency": "INR", // Optional, default INR
"partnerId": "DELHIVERY_001",
"partnerService": "SURFACE_10KG",
"shipments": [
{
"awbNumber": "123456789012",
"thirdPartyAwb": "TP-987654" // Optional
}
],
"metadata": [ // Optional
{ "key": "customer_segment", "value": "vip" }
]
}

Success Response (201 Created):

{
"success": true,
"message": "COD Order created successfully",
"data": {
"codId": "COD-100001",
"orderId": "PRG-ORD-1001",
"status": "CREATED",
"codStatus": "PENDING",
...
}
}

Error Scenarios:

  1. Partner Configuration Missing (400 Bad Request):
    {
    "message": "COD features is not configured for this account",
    "error": "Bad Request",
    "statusCode": 400
    }
  2. Order Already Exists (409 Conflict):
    {
    "message": "Order with ID PRG-ORD-1001 already exists",
    "error": "Conflict",
    "statusCode": 409
    }
  3. Delivery Partner Error (502 Bad Gateway / Dynamic): If the external partner API fails, the local transaction is rolled back.
    {
    "message": "Failed to push order to partner: Invalid AWB",
    "error": "PartnerError",
    "statusCode": 400
    }

3. List COD Orders

Endpoint: GET /gateway/cod/orders
Access: Authenticated
Description: Retrieve a paginated list of COD orders with advanced filtering.

Query Parameters:

  • page: Page number (default: 1)
  • limit: Items per page (default: 20)
  • orderStatus: Filter by status (e.g., CREATED,DELIVERED)
  • codStatus: Filter by payment status (e.g., PENDING,SETTLED)
  • search: General search string
  • startDate / endDate: Filter by creation date
  • partnerId: Filter by logistics partner

Response:

{
"success": true,
"message": "COD orders fetched successfully",
"data": {
"pagination": {
"page": 1,
"limit": 20,
"totalRecords": 50,
"totalPages": 3
},
"codOrders": [ ... ]
}
}

3. Get COD Listing Filters

Endpoint: GET /gateway/cod/filters
Access: Authenticated
Description: Returns valid filter configurations (operators, fields, static options) for frontend listing pages.

{
"version": "1.0",
"resource": "codOrders",
"filters": [
{
"id": "codId",
"label": "COD ID",
"type": "text",
"operators": [
"EQUALS",
"CONTAINS"
]
},
{
"id": "orderId",
"label": "Order ID",
"type": "text",
"operators": [
"EQUALS",
"CONTAINS"
]
},
{
"id": "awbNumber",
"label": "AWB Number",
"type": "text",
"operators": [
"EQUALS",
"CONTAINS"
]
},
{
"id": "orderStatus",
"label": "Order Status",
"type": "select",
"operators": [
"IN"
],
"ui": {
"multiSelect": true
},
"dataSource": {
"type": "static",
"options": [
{
"label": "Created",
"value": "CREATED"
},
{
"label": "Partially Delivered",
"value": "PARTIALLY_DELIVERED"
},
{
"label": "Delivered",
"value": "DELIVERED"
}
]
}
},
{
"id": "codStatus",
"label": "COD Status",
"type": "select",
"operators": [
"IN"
],
"ui": {
"multiSelect": true
},
"dataSource": {
"type": "static",
"options": [
{
"label": "Pending",
"value": "PENDING"
},
{
"label": "Partially Settled",
"value": "PARTIALLY_SETTLED"
},
{
"label": "Settled",
"value": "SETTLED"
},
{
"label": "Disputed",
"value": "DISPUTED"
}
]
}
},
{
"id": "partnerId",
"label": "Logistics Partner",
"type": "select",
"operators": [
"IN"
],
"dataSource": {
"type": "static",
"options": [
{
"label": "Delhivery",
"value": "DELHIVERY"
},
{
"label": "XpressBees",
"value": "XPRESSBEES"
}
]
}
},
{
"id": "createdAt",
"label": "Order Date",
"type": "dateRange",
"operators": [
"BETWEEN"
],
"minKey": "startDate",
"maxKey": "endDate"
},
{
"id": "remittanceDate",
"label": "Remittance Date",
"type": "dateRange",
"operators": [
"BETWEEN"
],
"minKey": "remittanceStartDate",
"maxKey": "remittanceEndDate"
},
{
"id": "expectedAmount",
"label": "Expected Amount",
"type": "numberRange",
"operators": [
"BETWEEN"
],
"minKey": "minExpectedAmount",
"maxKey": "maxExpectedAmount"
},
{
"id": "collectedAmount",
"label": "Collected Amount",
"type": "numberRange",
"operators": [
"BETWEEN"
],
"minKey": "minCollectedAmount",
"maxKey": "maxCollectedAmount"
},
{
"id": "remittedAmount",
"label": "Remitted Amount",
"type": "numberRange",
"operators": [
"BETWEEN"
],
"minKey": "minRemittedAmount",
"maxKey": "maxRemittedAmount"
}
],
"sorting": {
"default": {
"field": "createdAt",
"order": "DESC"
},
"allowed": [
"createdAt",
"updatedAt",
"collectedAmount",
"remittedAmount"
]
},
"pagination": {
"defaultLimit": 20,
"allowedLimits": [
10,
20,
50,
100
]
}
}

Example Usage in lisitng api

GET /cod/orders?page=1&limit=20&orderStatus=CREATED,DELIVERED&codStatus=SETTLED&startDate=2024-01-01&endDate=2024-01-31&minCollectedAmount=100&maxCollectedAmount=5000&sortBy=createdAt&sortOrder=DESC

5. Get COD Order Details

Endpoint: GET /gateway/cod/orders/:id
Access: Authenticated
Description: Get full details of a specific COD order, including shipments, remittance history, documents, and disputes.


6. Update COD Order (Manual Settlement)

Endpoint: PATCH /gateway/cod/orders/:id
Access: Authenticated
Description: Manually update remittance details for an order. Often used for correcting records or manual reconciliation.

Request Body:

{
"remittedAmount": 1299.00,
"remittanceDetails": [
{
"remittedAmount": 1299.00,
"remittanceRef": "UTR-BANK-001",
"remittanceDate": "2024-02-05",
"remittanceMode": "NEFT",
"remarks": "Manual settlement"
}
]
}

7. Raise Dispute

Endpoint: POST /gateway/cod/orders/:id/dispute
Access: Authenticated
Description: Raise a dispute for a COD order (e.g., Short Collection, Excess Remittance).

Request Body:

{
"reason": "SHORT_COLLECTION",
"remarks": "Partner collected 500 instead of 1000"
}

8. Bulk Settle Orders

Endpoint: POST /gateway/cod/orders/bulk-settle
Access: Authenticated
Description: Settle multiple orders at once, typically from a bank statement or partner report.

Request Body:

{
"settlements": [
{
"codId": "COD-100001",
"remittedAmount": 1299.00,
"remittanceRef": "UTR-BULK-001",
"remittanceDate": "2024-02-05",
"isBulkRemitted": true
},
{
"codId": "COD-100002",
"remittedAmount": 500.00,
"remittanceRef": "UTR-BULK-001"
}
]
}

9. Partner Webhook

Endpoint: POST /gateway/cod/webhooks/partner
Access: Public (Signature Verification Recommended)
Description: Entry point for logistics partners to push updates. Handles Status Updates, Collections, Remittances, and Disputes.

Supported Event Types: STATUS_UPDATE, COLLECTION, REMITTANCE

1. Status Update Payload

Used to update the delivery status of the shipment.

{
"eventType": "STATUS_UPDATE",
"timestamp": "2024-02-05T10:00:00Z",
"partnerId": "DELHIVERY",
"payload": {
"orderId": "PRG-ORD-1001",
"thirdPartyAwb": "1234567890",
"status": "DELIVERED",
"statusCode": "DL",
"remarks": "Package delivered to neighbor"
}
}

2. Collection Payload

Used when the partner collects cash/payment from the customer.

{
"eventType": "COLLECTION",
"timestamp": "2024-02-05T10:30:00Z",
"partnerId": "DELHIVERY",
"payload": {
"orderId": "PRG-ORD-1001",
"collection": {
"amount": 1299.00,
"paymentMode": "CASH",
"collectedAt": "2024-02-05T09:30:00Z",
"agentName": "Ramesh Kumar",
"agentId": "AGT-99",
"reference": "TXN_CASH_001"
}
}
}

3. Remittance Payload

Used when the partner transfers the collected amount to the merchant.

{
"eventType": "REMITTANCE",
"timestamp": "2024-02-06T14:00:00Z",
"partnerId": "DELHIVERY",
"payload": {
"orderId": "PRG-ORD-1001",
"remittance": {
"amount": 1250.00,
"reference": "UTR-HDFC-998877",
"date": "2024-02-06",
"mode": "NEFT",
"remarks": "Settlement for Batch #55",
"remittedBy": "Finance System"
}
}
}

10. Service Webhook (Internal/Direct)

Endpoint: POST /service/cod/webhooks/partner
Access: Public (Internal Routing)
Description: Direct service-level webhook for processing partner payloads. This endpoint supports advanced payload structures and flexible identification using either orderId, awbNumber, or thirdPartyAwb.

Supported Event Types: STATUS_UPDATE, COLLECTION, REMITTANCE, DISPUTE, DOCUMENTS

Note: Multiple event objects (e.g., collection and status) can be sent in a single request. At least one of the event types or a status must be present.

Identification (Use any one)

{
"payload": {
"orderId": "PRG-ORD-1001",
"awbNumber": "AWB-778899",
"thirdPartyAwb": "3P-990011",
...
}
}

Status Update Payload

{
"payload": {
"orderId": "PRG-ORD-1001",
"status": "DELIVERED",
"remarks": "Package delivered to neighbor"
}
}

Collection Payload

{
"payload": {
"orderId": "PRG-ORD-1001",
"collection": {
"amount": 1299.00,
"paymentMode": "CASH",
"agentName": "Ramesh Kumar",
"agentId": "AGT-99",
"agentHub": "HUB-SOUTH-DELHI",
"hubContact": "+919876543210",
"reference": "TXN_CASH_001",
"remarks": "Collected at customer doorstep"
}
}
}

Remittance Payload

{
"payload": {
"orderId": "PRG-ORD-1001",
"remittance": {
"amount": 1250.00,
"reference": "UTR-HDFC-998877",
"mode": "NEFT",
"remarks": "Bulk settlement - Batch #55"
}
}
}

Dispute Payload

{
"payload": {
"orderId": "PRG-ORD-1001",
"dispute": {
"reason": "SHORT_COLLECTION",
"remarks": "Customer paid less than invoice amount",
"raisedBy": "PARTNER_OPS"
}
}
}

Documents Payload

{
"payload": {
"orderId": "PRG-ORD-1001",
"documents": [
{
"type": "POD",
"url": "https://storage.partner.com/pod/1001.jpg",
"description": "Proof of delivery signature"
}
]
}
}

Error Handling

The service uses standard HTTP status codes:

  • 200: Success
  • 201: Created
  • 400: Bad Request (Validation failure, Missing configuration)
  • 401/403: Unauthorized / Forbidden
  • 404: Not Found
  • 409: Conflict (Duplicate resources)
  • 500: Internal Server Error

All errors return a standardized JSON format:

{
"success": false,
"statusCode": 400,
"message": "Error description",
"error": "Error Type",
"path": "/request/path",
"timestamp": "ISO-Date"
}