Order Lifecycle
An order moves through two systems. This page traces it end to end and defines the canonical shapes at each step.
The journey
1. Member checks out in the Swoop app
2. swoop-api publishes orderPlaced → Pub/Sub → POST /pubsub/push
3. Adapter re-fetches the authoritative order from swoop-api (GraphQL)
4. Adapter builds a CanonicalOrder and routes by location → your Provider
5. Provider.CreateOrder pushes a to-go ticket → returns OrderRef
6. Your POS advances the ticket and posts a webhook → POST /webhook/{provider}
7. WebhookTranslator → StatusEvent → Swoop updates the member's order live
Step 3 matters: the
orderPlacedevent payload is not a stable contract. The adapter treats it only as a signal and re-fetches the full, authoritative order by id. Your provider only ever sees the resultingCanonicalOrder.
CanonicalOrder
What your Provider.CreateOrder receives:
| Field | Type | Notes |
|---|---|---|
swoopOrderId |
string | Stable id; use as the idempotency key |
locationId |
string | Club id; already routed to your provider |
member |
Member |
id, name, email, phone — the order is tied to a known member |
fulfillment |
Fulfillment |
type (delivery/pickup) + destination |
items[] |
LineItem |
swoopItemId, name, quantity, notes, ageRestricted, modifiers[] |
money |
Money |
subtotal, tax, tip, fee, total, currency |
notes |
string | Order-level instructions |
placedAt |
date-time | When the member ordered |
ageRestricted flags alcohol so your POS can enforce an age check. tax is Swoop's
computed value — some POS systems compute their own and ignore it.
See the CanonicalOrder schema in the API reference for the full
definition and a worked example.
Status model
Map your POS's native events onto these seven canonical statuses:
| Canonical status | Meaning |
|---|---|
received |
POS accepted / acknowledged the order |
in_progress |
Kitchen is preparing it |
ready |
Ready for pickup, or to be run out for delivery |
en_route |
Out for delivery |
completed |
Delivered / picked up / closed |
cancelled |
Cancelled |
failed |
POS rejected or failed the order |
You don't emit every status — emit the ones your POS actually signals. Swoop maps each to the member-facing state, accounting for delivery vs pickup.
StatusEvent
What your WebhookTranslator produces from a raw webhook:
| Field | Type | Notes |
|---|---|---|
swoopOrderId |
string | Which Swoop order this applies to |
status |
OrderStatus |
One of the seven above |
providerOrderId |
string | Your POS order id, if the webhook carries it |
reason |
string | Failure/cancellation reason, if any |
Return nil (no event) for webhooks that aren't an order-status change you map — the
adapter acks and ignores them.