Koovira Dev Docs
20-modules/courier/overview.md

Module: Courier / Delivery Partner (courier / logistics)

Status: ๐ŸŸก Backend Only (6 real carrier adapters; near-zero stored credentials) ยท Last validated: 2026-09-06 ยท Priority: P1

Multi-carrier shipping integration for merchant parcels. Validated against classs/DeliveryPartnerCourierModule.php + classs/courier_providers/ + schema.

A. Purpose

Merchants ship orders via aggregated carriers (Shiprocket, Delhivery, DTDC, Shadowfax, Xpressbees, Shree Maruti) โ€” real cURL adapters in classs/courier_providers/. Revenue: per-shipment fee possible, none defined.

B. Actors

Merchant (shipper); carrier (external); admin. Enrollment logistics.

C. Entry points

/courier_intro.php, /courier_dashboard.php; merchant delivery_partner_shipments.php. External API: api/developer/shipping.php (scopes shipping.write :124, tracking.read :66). (corrected 2026-09-06: doc previously said shipping.manage; the scope literally required by devapi_require_scope() in that file is shipping.write.)

E. Feature registry (prefix CUR-)

IDFeatureActorMethodTablesStatus
CUR-001List supported vendorsmerchantlistSupportedVendors :734โ€”๐ŸŸข
CUR-002Save vendor credentialsmerchantsetVendorCredentials :894, getVendorCredentials :960credential store๐ŸŸก (mostly unset)
CUR-003Company shipping settingsmerchantgetCompanySettings :809, saveCompanySettings :828settings๐ŸŸข
CUR-004Pick vendor for payloadsystempickVendorForPayload :175โ€”๐ŸŸข
CUR-005Generate labelmerchantgetLabel(companyId, shipmentUid) :749courier_shipments๐ŸŸก
CUR-006Inbound webhook (status)carriergenerateWebhookSecret :864 + webhookcourier_shipments๐ŸŸก

G. Data model (2026-09-06)

courier_partners 9 (api_credentials_json NULL on all) ยท courier_shipments 4.

H. Financial impact

Shipping charges pass through to the order; no platform courier commission defined.

K. State machine (courier_shipments)

draft โ†’ booked โ†’ picked_up โ†’ in_transit โ†’ out_for_delivery โ†’ delivered / booking_failed / ndr_pending / rto_initiated/rto_delivered / cancelled (carrier webhook updates status). (corrected 2026-09-06: doc previously said created โ†’ label_generated โ†’ ... โ†’ rto. Code shows otherwise โ€” createShipmentDraft() (classs/DeliveryPartnerCourierModule.php:1018) defaults initialStatus to draft; getLabel() moves it straight to booked in the same update that writes awb_number/label_url (:1276-1286, on success) or to booking_failed (:1266, on failure) โ€” there is no separate label_generated state. Webhook status mapping (:419-425) emits picked_up/in_transit/out_for_delivery/delivered/rto_initiated/ cancelled, and :1801 also references a ndr_pending status; the exact string is rto_initiated/ rto_delivered, not bare rto.)

L / M / N

Errors: CUR-E001 code labels the active path "simulated" โ€” carriers won't actually ship until setVendorCredentials stores real keys (all courier_partners.api_credentials_json are NULL). Depends on the order module, external carrier APIs. Change-impact: storing credentials flips this from simulated to live โ€” re-test label generation + tracking webhook per carrier.