Order Creation Flows
There are two distinct flows for creating orders. See integration-guide for architecture overview.
1. Terminal-Driven Flow
The terminal controls the entire process (walk-up kiosk mode).
Create Session → Prolong/End Session → Create Order → Upload Photos
1.1 Create Session
Endpoint: POST /api/terminal/scales/{scaleId}/sessions
Locks the scale to prevent mobile app users from creating orders.
1.2 Prolong or End Session
Endpoint: PATCH /api/terminal/scales/{scaleId}/sessions/{sessionId}
Extends the session lock duration.
1.3 Create Order
Endpoint: POST /api/terminal/scales/{scaleId}/orders
Creates a completed order after payment is received at the terminal.
Important:
- The session is automatically ended when the order is created
- The order ID must be unique (terminal-generated) and equal to
WEIGHT_RESULT_IDfrom the legacy system- Order status is set to
COMPLETEDimmediately
1.4 Upload Photos (Batch)
Endpoint: POST /api/terminal/scales/{scaleId}/orders/{orderId}/photos/batch
Uploads photos from one or more cameras in a single request. Pass commandId to auto-complete the upload_photos command.
Request: multipart/form-data — repeated fields (parallel arrays, order-aligned):
commandId: <uuid> (optional) — upload_photos command to auto-complete
cameraId: <camera-uuid> (repeated, one per photo)
file: <binary image> (repeated, one per photo)
Example (two cameras):
commandId: 7a1b2c3d-...
cameraId: aaa-...
file: [camera 1 image]
cameraId: bbb-...
file: [camera 2 image]
Response: 201 — array of uploaded photo objects.
⚠️ Deprecated:
POST /api/terminal/orders/{orderId}/cameras/{cameraId}/photos— single-photo endpoint with nocommandIdsupport. Use the batch endpoint instead.
2. User/Mobile App-Driven Flow
A mobile app user initiates the flow; the terminal responds to server commands.
User Creates Session → push_weight command → Terminal patches weight
→ User creates Checkout → User pays → upload_photos command → Terminal uploads → Done
Full Flow Steps
- User Creates Session (via mobile app)
- Server Creates
push_weightCommand → Terminal executes - After Weight Pushed, Server Creates
pull_stateCommand → Terminal executes to lock itself - User Prolongs Session (via mobile app)
- User Creates Order (via mobile app) — receives payment URL
- Server Creates
upload_photosCommand → Terminal calls batch upload endpoint withcommandId→ command auto-completes - User Pays → Webhook → Order completes → Session ends automatically
- Scale Unlocks via WebSocket update
Terminal Detects New Session
Terminal subscribes to scales UPDATE events. When activeSessionId changes, call GET /api/terminal/scales/{scaleId} for full state.
supabase
.channel('scales')
.on('postgres_changes',
{ event: 'UPDATE', schema: 'public', table: 'scales' },
(payload) => {
if (payload.new.id === myScaleId) {
handleScaleUpdate(payload.new);
}
}
)
.subscribe();Terminal Receives Commands
Terminal subscribes to scale_commands INSERT events:
supabase
.channel('scale_commands')
.on('postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'scale_commands' },
(payload) => {
if (payload.new.scaleId === myScaleId) {
handleNewCommand(payload.new);
}
}
)
.subscribe();Get Pending Commands
Endpoint: GET /api/terminal/scales/{scaleId}/commands
| Param | Default |
|---|---|
limit | 50 |
offset | 0 |
startDate | — |
endDate | — |
Related
- scale-commands — command types (
push_weight,pull_state,upload_photos) and status flow - websocket-realtime — raw WebSocket connection for Supabase Realtime
- integration-guide — architecture overview and best practices