Orders
Order lifecycle
The statuses an order moves through, which app moves it at each step, cancellation, and the invoice documents.
An order is placed by the customer at checkout, handled by the store, and delivered by a driver. Its status says where it is.
Statuses#
stateDiagram-v2
[*] --> pending: checkout
pending --> accepted: store
accepted --> preparing: store assigns a driver
preparing --> out_for_delivery: driver picks up
out_for_delivery --> delivered: driver hands over
pending --> cancelled
accepted --> cancelled
preparing --> cancelled
out_for_delivery --> cancelled
delivered --> [*]
cancelled --> [*]
| Status | Meaning | Moved there by |
|---|---|---|
pending |
Placed, waiting for the store | Checkout |
accepted |
The store took the order | Merchant app |
preparing |
The store is picking it, and a driver is assigned | Merchant app, by assigning a driver |
out_for_delivery |
The driver has it | Driver app (or the store) |
delivered |
Handed to the customer | Driver app (or the store) |
cancelled |
Stopped before delivery | Customer (only while pending), store, driver or Tote |
delivered and cancelled are final.
Orders move one step at a time. Send the next status in the sequence. A skipped step or a step back returns 422, with a translated message naming both statuses: each step is a separate fact on the order's timeline and in Tote's reports, and a skip would record an acceptance or pickup that never happened.
The merchant app#
The store team works from two lists:
orders/current— every order not yet delivered or cancelled, newest first. Filter with?order_number=or?customer_name=.orders/history— finished orders.
Orders arrive in current the moment they are placed, before payment. Show is_paid prominently, and wait for it before preparing: the store team is pushed order_paid when it flips.
To move an order, call PUT orders/{order}/status with the next status.
POST orders/{order}/assign-driver with a driver_id assigns the driver and moves the order to preparing in the same call.
- The order must be
accepted, or alreadypreparingto replace its driver. Any other status returns422. - The driver must be an active member of the store's own team:
driverslists them (see Drivers & stores). Anyone else returns422with the message undererrors.driver_id.
The driver app#
orders/current— orders assigned to this driver that arepreparingorout_for_delivery. This is the driver's work list.orders— every order ever assigned to the driver, filterable by?status=.
The driver moves an assigned order with PUT orders/{order}/status: out_for_delivery at pickup, delivered at hand-over, or cancelled. Those are the only statuses a driver may send — accepted and preparing belong to the store — and the same one-step rule applies (422 otherwise). Updating an order assigned to someone else returns 403.
Cancelling#
| Who | When | How |
|---|---|---|
| Customer | Only while pending (otherwise 422); guests cannot cancel (403) |
POST orders/{order}/cancel |
| Store | Any time before delivery | status: cancelled on the status endpoint |
| Driver | An order assigned to them, before delivery | status: cancelled on the status endpoint |
Each takes an optional reason_code and a free-text reason. reason_code is only allowed together with status: cancelled:
customer_request, out_of_stock, store_closed, store_unresponsive, driver_unavailable, delivery_failed, payment_failed, duplicate_order, other
A customer cancellation with no reason_code is recorded as customer_request. Cancelling an order that is already delivered or cancelled returns 422.
Who is at fault matters to Tote's settlement with the store, so pick the code that matches what happened: a cancellation after the store started preparing can be charged to the store.
Cancelling a paid order does not refund it on the spot. Tote's operations team issues the refund, to the original card.
Notifications along the way#
Every status change pushes the customer (status_update). The store team is pushed on a new order and on a cancellation, and the driver when an order is assigned to them or cancelled. The full list is in Push notifications.
Invoices and credit notes#
The invoice and any credit note belong to the store: they carry the store's legal name, address, CR and VAT numbers, and are numbered in the store's own sequence ({store}-INV-000001, {store}-CN-000002). Tote issues them on the store's behalf and is named only on that line.
Once an order is paid (or delivered), the customer can download its tax documents. A cancelled order has none.
GET orders/{order}/documentslists theinvoice(number, date, total, VAT) and anycredit_notes, issued for example when part of the order is refunded through a Return.invoiceisnulluntil the order is due one.GET orders/{order}/invoiceandGET orders/{order}/credit-notes/{creditNote}return the PDFs. Both are limited to 20 downloads a minute, so cache the file rather than fetching it on every view.