Order Lifecycle
Related docs:
Checkout Flow·Payment Architecture
1. Order Status State Machine
2. Order Statuses
| Status | Description | Actor |
|---|---|---|
PENDING | Order created; payment not yet confirmed | System (on order creation) |
CONFIRMED | Payment received and verified via webhook | System (webhook handler) |
PROCESSING | Vendor has accepted and is preparing the order | Vendor / Admin |
SHIPPED | Order handed to agent ("Out for Delivery") | Delivery Agent |
DELIVERED | PIN-based confirmation completed | Delivery Agent / Customer |
CANCELLED | Order cancelled; no payment or pre-dispatch | Customer / Admin |
REFUNDED | Refund issued to customer | Admin |
3. Payment Status
| Status | Description |
|---|---|
PENDING | Payment initiated; awaiting confirmation |
PAID | Confirmed via webhook (InboundPayment.status = CAPTURED) |
FAILED | Gateway reported failure or timeout |
REFUNDED | Refund completed |
Payment status is stored on Order.paymentStatus and updated exclusively by webhook handlers (never by the frontend directly).
4. Settlement Status (per OrderItem)
| State | Description |
|---|---|
HELD | Funds in provider wallet; payout blocked |
RELEASABLE | Admin or system marks order delivered; payout authorised |
PAID_OUT | Payout instruction sent to PawaPay/Flutterwave |
5. Status Transition Actors
| Transition | Actor | API / Trigger |
|---|---|---|
| Created → PENDING | Customer | POST /api/v1/orders |
| PENDING → CONFIRMED | System | Webhook (deposit.completed / charge.completed) |
| CONFIRMED → PROCESSING | Vendor / Admin | Admin dashboard action |
| PROCESSING → SHIPPED | Vendor / Admin | Assign to Delivery Agent |
| SHIPPED → DELIVERED | Delivery Agent | PIN verification (POST /api/v1/delivery/agent/confirm) |
| Any → CANCELLED | Customer / Admin | PATCH /api/v1/orders/:id/cancel |
| HELD → RELEASABLE | System | Automatic on delivery confirmation |
| RELEASABLE → PAID_OUT | System | SettlementLedger.disburseVendorPayouts() |
6. Settlement Calculation
Per OrderItem, on payment confirmation:
vendorAmount = item.price × item.quantity × (1 − PLATFORM_COMMISSION_PCT)
platformFee = item.price × item.quantity × PLATFORM_COMMISSION_PCT
Default PLATFORM_COMMISSION_PCT = 0.05 (5%).
VAT (16%) is included in displayed prices and broken out for compliance. It does not affect the vendor/platform split calculation — the split is applied to the total including VAT.
7. Refund Scenarios
| Scenario | Steps |
|---|---|
| Customer cancels before payment | Order status → CANCELLED; no payment to refund |
| Customer cancels after payment, before dispatch | Admin initiates refund via PawaPayAdapter.processRefund() or FlutterwaveAdapter.processRefund() |
| Defective item returned after delivery | Admin verifies return → refund initiated; Order.status → REFUNDED |
| Partial refund (one item of multi-item order) | Not yet automated; admin processes manually via gateway dashboard |
8. Delivery Terminology
Pakashop is a Zambia-only platform. All references to movement of goods use delivery language:
| Replaced term | Pakashop term |
|---|---|
| Shipping | Delivery |
| Shipping address | Delivery address |
| Shipping & handling | Delivery fee |
| Shipped | Out for delivery |
| Free shipping | Free delivery |
The order status SHIPPED (stored in the DB for backward compatibility) is displayed to users as "Out for Delivery".
9. Multi-Vendor Order Splitting
A single order may contain items from multiple vendors (shops). The order is stored as one Order record with multiple OrderItem records, each linked to a different Shop.
- Settlement is calculated and disbursed per shop (vendor).
- The vendor dashboard shows only their items within a given order.
- If one vendor cancels their items, only their
OrderItemrecords are affected; the rest of the order continues normally (partial cancellation support is on the roadmap).