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_ID from the legacy system
  • Order status is set to COMPLETED immediately

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 no commandId support. 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

  1. User Creates Session (via mobile app)
  2. Server Creates push_weight Command → Terminal executes
  3. After Weight Pushed, Server Creates pull_state Command → Terminal executes to lock itself
  4. User Prolongs Session (via mobile app)
  5. User Creates Order (via mobile app) — receives payment URL
  6. Server Creates upload_photos Command → Terminal calls batch upload endpoint with commandId → command auto-completes
  7. User Pays → Webhook → Order completes → Session ends automatically
  8. 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

ParamDefault
limit50
offset0
startDate—
endDate—