Skip to content

Orders

An order's life after checkout, its status flow, and where the three third parties move it along.

How this page was verified

Read on 2026-09-15 from the backend orders module (service, cron, resolvers), the storefront /user/my-order, and the admin /admin/orders (view only).

The model and statuses

Tables: orders, order_items, order_addresses. Status values (utils/order-status.const.ts):

StatusMeaning
pending_paymentcreated, waiting for the customer to pay
processingpaid (DOKU success), being prepared
shippedhanded to the courier / picked by the WMS
completeddelivered
canceledcancelled (by the customer, or expired unpaid)

What moves an order between statuses

The order is created pending_payment by createOrder() (see Cart and checkout). After that, the three third parties drive it — each through its inbound webhook:

  • DOKUwebhook-payments.service.ts: on transaction.status === 'SUCCESS' the order goes to processing.
  • WMSwebhook-wms.service.ts: an inbound WMS sales-order event moves the order to shipped (delivery processing).
  • Biteshipwebhook-deliveries.service.ts: maps Biteship tracking to delivery shipped / delivered; on delivered the order goes to completed.

See Third parties for how the callbacks arrive.

The expiry cron

OrdersCronService.handleOrderPaymentExpiry (src/orders/services/orders-cron.service.ts) runs every minute. It finds pending_payment orders past paymentExpiredAt, re-checks the DOKU status, and cancels the expired ones — cancelling the WMS order and the Biteship draft too. This is the only cron in the backend.

Resolvers

  • CMS (orders.resolver): orders, order, orderTransactionMetrics.
  • Storefront (storefront-orders.resolver): frontMemberOrders(search, status), frontMemberOrder(orderId), frontCancelMemberOrder(orderId).
  • REST (orders controller): GET excel export, test-email endpoints, and a fix endpoint fix/update-order-wms-status/:orderId.

Storefront

/user/my-order (src/app/user/my-order/page.tsx) — order history with ?status= tabs (e.g. pending_payment). UI in src/modules/my-order/components/ (item, detail, status tabs, status badge, search). "Pay again" re-opens DOKU from the order detail. Cancel calls frontCancelMemberOrder.

Admin

/admin/orders is view only — list page.tsx and [slug] detail. src/lib/orders/index.ts has only orders and order queries, no mutations, so status changes are not wired in the admin; the webhooks drive them.

Gotchas

  • The admin cannot change an order's status. Status flows from the webhooks, not from a button.
  • Order number prefix is EXSPORT_ORDER_NO_PREFIX; notification emails are gated by EXSPORT_ORDER_SHOULD_SEND_NOTIF_EMAIL.