Skip to main content

Orders

Endpoint reference: ✅ Verified live against production on 10 May 2026. Orders are the conversion event in your store — when a customer’s cart becomes a purchase. The Dr Green admin team manually approves each order before it ships, so expect an asynchronous lifecycle: place → pending → admin-verified → paid → shipped.

Order lifecycle (the high-level flow)

There’s no outbound webhook for status changes — your store must poll. See 06-webhooks.md § The polling pattern.

Endpoints


Status enums

🔒 The complete enum lists above are inferred from observed values (PENDING, VERIFIED, REJECTED confirmed live). Other values are likely supported but not yet captured. Defensively handle unknown statuses — render them as the raw string.

POST /dapp/orders — create an order

Creates an order from explicit line items + shipping + (optionally) the cart it came from. The shipping address must be one of the client’s shippings[] (referenced by id).

Request body

The shape follows CreateOrderDto. Verified pattern:

Canonical payload (for signing)

JSON.stringify(body) — compact, no whitespace.

Response

201 Created with the order’s id and invoiceNumber. The invoiceNumber is a 32-char random string Dr Green generates server-side — use it as your customer-facing reference. Don’t generate your own.

Idempotency warning

POST /dapp/orders is not idempotent. A retry creates a duplicate order. Two patterns to avoid this: Pattern 1 — pre-flight check. Before any retry, query GET /dapp/orders?page=1&limit=20 and look for a recent order matching the customer + total amount. If found, treat your original POST as having succeeded. Pattern 2 — your-side correlation ID. Generate a UUID at checkout, store order_in_flight: <uuid> in your store DB, only POST once. On any retry, check if the previous attempt eventually returned a 2xx (which you’d have logged) before retrying. See 04-errors.md § Idempotency for the full discussion.

Errors


GET /dapp/orders — list orders

Paginated list of all orders for the holder.

Query parameters

Response shape (verified)

🪲 _count is a Prisma-leaked field — it’s { orderLines: <count> }. Treat it as informational, not authoritative.
🪲 totalAmount, totalPrice, and localPrice.totalAmount are different things:
  • totalAmount and totalPrice are the same USD figure (mirroring of fields)
  • localPrice.totalAmount is the customer-currency equivalent (e.g. ZAR for South Africa) Use localPrice for display, totalAmount for accounting.

GET /dapp/orders/recent — recent orders

Same shape as GET /dapp/orders but always returns the most recent 10 (no pagination needed). Use this as a heartbeat polling target — cheap call that surfaces anything new across all customers.

Canonical payload

{}

GET /dapp/orders/summary — status counts

The keys are adminApproval values (not orderStatus). For an orderStatus breakdown over time, use /dapp/orders/status-breakdown with a date range.

GET /dapp/orders/chart-data and /status-breakdown

Both require startDate and endDate in YYYY-MM-DD format. Without them: 400.

Canonical payload (with date range)

startDate=2026-04-01&endDate=2026-05-01 🔒 Response shapes pending live capture with valid date ranges.

GET /dapp/orders/{orderId} — order detail

Full detail including line items with embedded strain info, transactions, and the multi-currency price breakdown.

Canonical payload

{}

Response shape (verified)

⚠️ The order detail wraps the data inside an extra orderDetails field — i.e. data.orderDetails, not data directly. Other endpoints don’t wrap like this. Mind the inconsistency.
🪲 totalAmount is in USD, localPrice.totalAmount is in the customer’s local currency. Don’t render totalAmount to the customer — use localPrice.totalAmount with localPrice.currency.
🪲 totalOrdered and totalQuantity are the same number in observed responses. The duplication is a backend wart.

Common patterns

Polling order status

Surface multi-currency totals

Detecting status changes between polls


Caching guidance


See also

  • Carts — orders are typically born from carts
  • Clients — orders are scoped to clients
  • StrainsorderLines[].strain fields and pricing snapshot
  • Sales — orders may be associated with a sales pipeline entry
  • 06-webhooks.md — why you have to poll