Skip to content

Quickstart

  1. The restaurant owner registers your device in Sitora Biz against one station, declaring its capabilities and (for a smart POS) the launch reference for the co-resident payment application.
  2. The owner issues a one-time enrollment code and reads it to you or types it into the device.
  3. Your device claims the code once and receives its credential — shown exactly once.
  4. Poll, act, report.
  5. Pass the conformance suite. A passing run is recorded as a certification artifact per capability.

Ask Sitora for a sandbox filial and the installation seeds one for you. It carries a station, a customer display, a smart-POS companion, a cashier who actually holds the payment permission, and a provider configuration in its test environment. You are handed the device credentials and the cashier sign-in once.

Everything behaves exactly as production does: same endpoints, same throttles, same refusal codes, same kill switches.

Terminal window
# 1. Claim the one-time enrollment code (anonymous — the code is the secret)
curl -X POST -H 'Content-Type: application/json' \
-d '{"code":"<enrollment-code>"}' \
"https://<host>/api/payments/v1/devices/enroll/"
# 2. Check in. Do this on a timer — three minutes without a heartbeat and
# the device counts as offline, so the routes that need it stop being
# offered to the cashier. Every 30 seconds leaves room for a lost packet.
curl -X POST -H "Authorization: Bearer sit_pd_..." \
-H 'Content-Type: application/json' -d '{"summary":{"battery":91}}' \
"https://<host>/api/payments/v1/devices/heartbeat/"
# 3. Poll for work (smart POS)
curl -H "Authorization: Bearer sit_pd_..." \
-H 'If-None-Match: "<last-etag>"' \
"https://<host>/api/payments/v1/devices/assignment/"
# 3b. …or for what the guest should see (customer display)
curl -H "Authorization: Bearer sit_pd_..." \
"https://<host>/api/payments/v1/devices/display/"
# 4. Report what the payment application returned
curl -X POST -H "Authorization: Bearer sit_pd_..." \
-H 'Content-Type: application/json' \
-d '{"intent_id":42,"outcome":"reported_success",
"provider_reference":"RRN-000123","provider_code":"00",
"client_idempotency_key":"collection-42-1"}' \
"https://<host>/api/payments/v1/devices/assignment/report/"

Step 4 does not pay the order. See Smart POS handoff.

Both polling reads support If-None-Match; an unchanged state answers 304 with no body.

Sitora sets the cadence, not you. Every response from both reads — 200 and 304 alike — carries the seconds to wait before asking again, in two headers holding the same number:

X-Sitora-Poll-After: <seconds>
Retry-After: <seconds>

Wait that long, then poll again, and do not hard-code the value: Sitora can raise it fleet-wide with no release of yours, which is how a busy day gets handled by slowing devices down instead of refusing them. Today the display asks for two seconds and the companion for three. Retry-After on a successful response is pacing, not an error.

Throttles are per credential and are enforcement of last resort, not the cadence. A device that obeys the header never meets one.

Certification is earned in your sandbox. Sitora runs the conformance suite there on request, and the suite drives the real API as a cashier, a device, and the filial’s owner. It verifies, among other scenarios:

  • cash and attested-terminal collection settling through Sitora’s single payment seam;
  • the smart-POS handoff, including that a reported success leaves the order unpaid until a cashier attests it;
  • idempotent replay of a duplicate report;
  • a dynamic-QR payment confirmed by a real provider callback, and a duplicate callback replaying identically;
  • money a provider asserts for a transaction Sitora never registered surfacing as an unmatched-money issue rather than silently paying something;
  • kill-switch compliance, including that cash keeps collecting through a platform freeze;
  • an offline device removing its own routes, and a heartbeat restoring them;
  • reconciliation against an imported provider statement giving every difference a name, and a closed difference not returning on the next run.

A run leaves nothing behind: it releases the station lease, revokes the device credential it minted, and ends its owner session, so the suite can be re-run as often as you need against one sandbox.

A recorded run writes one immutable certification artifact per capability exercised. Certification is per provider × capability: passing for one hardware verb never certifies another.