Order lifecycle
Orders progress through six distinct states:| Status | Description | Who Updates |
|---|---|---|
placed | Order created, awaiting payment verification | System |
accepted | Payment confirmed, store accepts order | Store employee |
processing | Store is preparing the order | Store employee |
ready | Order is ready for customer pickup | Store employee |
picked_up | Customer collected the order | Store employee (via OTP) |
cancelled | Order cancelled (payment failed, timeout, or no-show) | System or store |
The system enforces strict state transitions. For example, an order cannot jump from
placed directly to ready - it must progress through accepted and processing first.Creating orders
The order creation process involves a two-step checkout flow for security and accuracy.Create checkout session
Generate a temporary checkout token containing cart details and payment information.
Checkout session
backend/src/controllers/orderController.js
Order creation
backend/src/controllers/orderController.js
Order status updates
Store employees update order status as they process orders. The system validates each state transition.backend/src/controllers/orderController.js
Valid status transitions
Valid status transitions
placed→accepted: Store confirms paymentaccepted→processing: Store starts preparingprocessing→ready: Order is complete and ready for pickupready→picked_up: Customer collects order (requires OTP verification)
picked_up can transition to cancelled.Automatic timeout sweeps
The system runs automatic cleanup operations to cancel stale orders and apply no-show penalties.backend/src/controllers/orderController.js
The timeout sweep runs at most once every 30 seconds to avoid excessive database queries. It’s triggered automatically on most order-related operations.
Timeout configuration
You can configure timeout durations via environment variables:| Variable | Default | Description |
|---|---|---|
UNPAID_ORDER_TIMEOUT_MINUTES | 8 | Cancel orders with pending payment |
READY_NO_SHOW_TIMEOUT_MINUTES | 20 | Cancel ready orders not collected |
ORDER_COMMITMENT_TIMEOUT_MINUTES | 4 | Time limit for commitment confirmation |
Customer commitment system
Users with a history of no-shows must confirm they’re on their way before the store starts preparing their order.Trust tiers
backend/src/controllers/orderController.js
| Tier | Criteria | Requirements |
|---|---|---|
| good | 0-1 no-shows | No additional requirements |
| watch | 2+ no-shows | Must confirm commitment before store accepts |
| restricted | 3+ no-shows | Cannot place orders for 14 days (default) |
Confirming commitment
backend/src/controllers/orderController.js
Real-time polling
Customers can poll for order status updates to track their order in real-time.backend/src/controllers/orderController.js
The polling endpoint uses
.lean() queries for better performance since it doesn’t need to modify the documents. This reduces memory overhead and query time.Order data structure
backend/src/models/Order.js
API endpoints
| Endpoint | Method | Description | Auth |
|---|---|---|---|
/api/orders/checkout | POST | Create checkout session | Customer |
/api/orders | POST | Create order from checkout | Customer |
/api/orders | GET | List orders (filtered by role) | Any |
/api/orders/:id | GET | Get order details | Owner/Store |
/api/orders/:id/payment-status | PATCH | Update payment status | Store |
/api/orders/:id/status | PATCH | Update order status | Store |
/api/orders/:id/commitment | POST | Confirm customer commitment | Customer |
/api/orders/:id/poll | GET | Poll order status | Owner/Store |