Skip to main content

Orders Live

Order tracking + history — for both consumers (their orders) and sellers (orders to fulfill).

1. Overview

Once a checkout creates a StoreOrder, both sides get a view: consumer sees status updates as the seller progresses (pending → accepted → preparing → ready / out_for_delivery → delivered), seller sees a kanban-style list with action buttons (Accept, Decline, Start Preparing, etc.).

Cancellation is supported on both sides with optional reason capture (added 2026-04-17 for the offline-launch flow where sellers verify orders by phone first).

2. User journey

Consumer

  1. Profile → My Orders OR direct deep link from order confirmation email
  2. See unified chronological list (store + eats orders, both sources merged)
  3. Tap an order → status timeline + items + delivery address
  4. If still pending → Cancel button available

Seller

  1. Seller dashboard → Orders tab
  2. See live kanban (pending / accepted / preparing / ready / out for delivery / delivered / cancelled)
  3. Pending orders show customer phone as tel: link with "Call to Confirm" badge
  4. Decline → prompt for optional cancellation reason (max 500 chars, persisted to DB)

3. Web ↔ Mobile parity

CapabilityWebMobile
Consumer order list/orders (unified store + eats)orders.tsx (store-orders only)
Order detail/orders/[id]order/[id].tsx
Cancel own orderpending onlypending only
Seller order kanban/seller/stores/[id] Orders tab❌ Seller is web-only
Tel: link + Call to Confirm
Cancellation reason capturewindow.prompt

4. Key components

  • Web consumer: src/app/(consumer)/orders/page.tsx, src/app/(consumer)/orders/[id]/page.tsx
  • Web seller: src/app/seller/stores/[id]/page.tsx (Orders tab section)
  • Mobile consumer: mobile/app/orders.tsx, mobile/app/order/[id].tsx
  • Status helpers: src/lib/fulfillment.tsgetValidStatusTransitions, getStatusLabel, canAcceptOrders, validatePickupTime

5. APIs

EndpointMethodPurpose
/api/store-ordersGETList own orders (consumer)
/api/store-orders/[id]GETSingle order detail with items
/api/store-orders/[id]/cancelPATCHConsumer cancel (only if pending)
/api/seller/stores/[id]/ordersGET, PATCHSeller list + status updates (accepts cancellationReason on cancel)
/api/orders/consumerGETUnified store + eats list (web only)
/api/orders/[id]/statusPATCHEats status update (legacy, eats archived)

6. Database touchpoints

  • StoreOrder — primary entity. Status, payment, fulfillment, timestamps for every status (acceptedAt, preparingAt, etc.)
  • StoreOrderItem — line items with frozen price + name (so historical orders survive product edits)
  • Order (eats) — historical eats orders preserved (not creating new ones)
  • Notification (consumer) + SellerNotification — push channel rows
  • EmailLog — order confirmation send tracked

7. Business logic

Status flow (StoreOrder)

  • Delivery: pending → accepted → preparing → ready → out_for_delivery → delivered → completed
  • Pickup: pending → accepted → preparing → ready_for_pickup → completed
  • Either: * → cancelled (only from pending/accepted for consumer; any non-terminal state for seller)
  • Each transition is enforced by getValidStatusTransitions(currentStatus, fulfillmentType)

Status timestamps (analytics gold)

Every transition records a timestamp (acceptedAt, preparingAt, readyAt, etc.). These power per-store delivery time analytics, prep-time accuracy, etc.

Cancellation reason capture

  • On status='cancelled', the API accepts an optional cancellationReason string (max 500 chars)
  • Persisted to StoreOrder.cancellationReason
  • Surfaced in admin views + seller dashboard

Auto-assign delivery partner

  • For delivery orders that aren't selfDelivery, on status='accepted' or 'preparing' the system fires assignDeliveryPartner() (non-blocking)
  • Algorithm: Haversine + smart scoring (distance + load + rating) — see src/lib/delivery-engine.ts

Reel attribution on order completion

  • If the order came from a tagged reel (within 24h click-to-purchase window), the linked ReelEarning row is confirmed on delivered and reversed on cancelled

8. Feature flags / env vars

None directly. PAYMENTS_ONLINE_ENABLED indirectly affects orders (online payments create orders via a different code path).

9. Tests

  • tests/build-integrity.test.ts — order status transitions, status timestamps
  • tests/store-product-flow.test.ts — checkout → order creation
  • tests/offline-only-launch.test.ts — cancellation reason capture

10. Known gotchas

  • Mobile orders screen lists store-orders ONLY — eats are tracked via the live restaurant order screen, not the orders list. Web shows both because eats orders are historical.
  • Status transitions are server-enforced — client can't push an invalid transition. Returns 400 with helpful error.
  • Customer phone is shown to seller as tel: link — tap-to-call directly from the order card. Crucial for the offline-launch verification flow.
  • Cancellation reason is OPTIONAL but recommended. Browser window.prompt is the simplest UX; can be upgraded to a custom modal post-launch.
  • Auto-cancel on payment timeout: online orders that don't complete within 5 min (PAYMENT_TIMEOUT_MS) are auto-cancelled by /api/payments/cleanup cron.