Checkout Flow
Related docs:
Payment Architecture·Order Lifecycle
1. Overview
The Pakashop checkout is a two-step process composed as a single page with conditional rendering:
- Delivery Information — address collection.
- Payment Method — method selection, wallet number (MoMo), consent, and order submission.
The page assembles these components from frontend/src/components/checkout/:
| Component | Responsibility |
|---|---|
DeliveryForm.js | Zambian address form with all 10 provinces |
PaymentMethodSelector.js | Animated grid of MTN / Airtel / Zamtel / Card options |
MobileMoneyOverlay.js | Full-screen USSD waiting overlay with polling |
OrderSummary.js | Cart items, VAT breakdown, trust badges |
2. Step-by-Step User Journey
3. Delivery Form
Collects Zambian-specific delivery details. All labels use "delivery" (never "shipping").
Fields:
| Field | Validation |
|---|---|
| First Name | Required |
| Last Name | Required |
| Required, valid format | |
| Mobile Number | Required (delivery contact) |
| Delivery Address | Required |
| City | Required |
| Province | Required — select from all 10 Zambian provinces |
| Country | Fixed: Zambia |
On submission, formData is passed to Step 2 and the wallet number field is pre-filled from formData.phone.
4. Payment Method Selection
The PaymentMethodSelector renders a 2×2 grid of clickable cards:
| Method ID | Label | Type | Logo path |
|---|---|---|---|
MTN_MONEY | MTN Mobile Money | USSD push | /images/logos/.../mtn.svg |
AIRTEL_MONEY | Airtel Money | USSD push | /images/logos/.../airtel.svg |
ZAMTEL_MONEY | Zamtel Kwacha | USSD push | /images/logos/.../zamtel.png |
CARD | Visa / Mastercard | Redirect | visa.svg + mastercard.svg |
State: selectedMethod (default: MTN_MONEY).
5. Mobile Money Wallet Number
Conditionally rendered when selectedMethod !== 'CARD'.
- Label: "Enter Mobile Money Number"
- Pre-fill:
formData.phonefrom delivery form - Validation: Zambian number format (10 digits, starts with 097/096/095/077/076/075/095)
- Storage:
formData.mobileWalletNumber
6. DPA Consent Checkbox
Required for mobile money payments.
Text: "I confirm that the mobile money wallet is registered in my name and I agree to Pakashop's [Terms of Service]."
The checkbox enforces the Zambia Data Protection Act 2021 requirement for explicit consent before processing personal financial data.
The checkout process follows a coordinated sequence:
- Order Creation: A pending order is created in the database with the customer's delivery and item details.
- Payment Initiation: The chosen provider is called to generate a USSD push (for mobile money) or a hosted payment link (for card).
- Redirection/Overlay: The user is either redirected to a secure payment page or shown a local USSD status overlay.
8. USSD Polling Logic
To provide a real-time experience for mobile money users, the frontend continuously polls the backend for payment status updates every 5 seconds. This process remains active for up to 3 minutes, or until a terminal state (PAID or FAILED) is reached, at which point the user is automatically redirected to their order confirmation page.
9. Payment Callback Page (/payment/callback)
Landing page for card payment redirects. Also handles manual navigation for edge cases.
Logic:
- Extract
orderIdfromsearchParams. - If no
orderId: show generic error (mobile money payments are confirmed via polling on the checkout page, not here). - Call
GET /api/v1/payments/status/:orderIdonce. - If
PAID→ show success UI, clear cart, link to order. - If
PENDING→ start polling (3 s interval, 2 min timeout). - If
FAILED→ show failure UI, link back to checkout.
Success message: "Payment successful! Your order is being processed and will be delivered soon."
10. Error Handling
| Scenario | Behaviour |
|---|---|
| Order creation fails | Toast error, button re-enabled, user stays on checkout |
| Payment initiation fails | Toast with backend message, button re-enabled |
| USSD timeout (3 min) | Overlay dismissed, link to order page for status check |
| Card redirect fails | User lands on callback page with FAILED/PENDING status |
| Network error during poll | Poll continues; errors logged to console |