Smart POS handoff
Bu sahifa hali sizning tilingizga tarjima qilinmagan.
A smart POS collects money through a certified payment application that already lives on the device. Sitora never sees the card, the PIN, or the provider session — it hands your companion a described collection and records what comes back.
Lifecycle
Section titled “Lifecycle”cashier picks the smart_pos route │ ▼ intent created ──── your poll ────▶ presented │ │ │ payment app runs │ │ │ your report │ ▼ │ processing │ │ │ cashier attests (or cancels) ▼ ▼ expired succeededThe route is only offered to the cashier when a live handoff device is attached to the station. “Live” means actively heartbeating — a companion that goes quiet has its route withdrawn rather than being handed work nothing will collect.
Getting the assignment
Section titled “Getting the assignment”GET /api/payments/v1/devices/assignment/If-None-Match: "<last etag>"{ "assignment": { "intent_id": 42, "intent_display_number": 7, "order_display_number": 118, "station_name": "Kassa 1", "amount": "100000.00", "currency": "UZS", "status": "presented", "handoff_target": "uz.example.payapp", "expires_at": "2026-08-09T12:15:00Z" }, "server_time": "2026-08-09T12:00:11Z"}assignment is null when there is nothing to collect. Fetching a fresh
assignment records it as presented — that transition is the only state
change a device can cause on its own.
handoff_target is the launch reference the restaurant owner configured for
this device. Sitora treats it as opaque: it is never parsed, matched, or
branched on. If your companion already knows what it launches, leave it
blank.
expires_at is real. An intent that lapses is expired and the cashier has
to create a new one, so do not sit on an assignment.
Reporting the outcome
Section titled “Reporting the outcome”POST /api/payments/v1/devices/assignment/report/{ "intent_id": 42, "outcome": "reported_success", "provider_reference": "RRN-000123", "provider_code": "00", "client_idempotency_key": "collection-42-attempt-1"}| Outcome | Use when |
|---|---|
reported_success |
The payment application returned an approval |
reported_declined |
It returned a decline |
reported_cancelled |
The guest or cashier abandoned it in the app |
reported_unknown |
It returned nothing usable, or you timed out waiting |
provider_reference is the application’s own reference for the attempt — an
RRN, a slip number. It becomes the reference the cashier’s attestation
inherits, which is the practical payoff of integrating: nobody retypes a
number off a paper slip.
provider_code is your coded result, kept verbatim as machine vocabulary.
It is never rendered to staff as a message.
Send client_idempotency_key. A retry with the same key returns the
original outcome instead of recording a second report.
What a report does and does not do
Section titled “What a report does and does not do”It moves the intent to processing and shows the cashier what you said.
It does not:
- create a transaction,
- mark the order paid,
- terminate the intent, in either direction.
If you report a decline and the cashier’s screen still offers “settle”, that is correct behaviour, not a bug: a device-declared decline that was wrong would release the order for a second collection, so Sitora keeps the human in the loop for both answers. Report honestly and let the cashier decide.
reported_unknown is a first-class answer. A timed-out collection has an
unknown outcome, and saying so is far better than guessing — the cashier can
check the terminal and attest or cancel from what they actually see.
Refusals
Section titled “Refusals”| Status | Code | Meaning |
|---|---|---|
404 |
handoff_not_assigned |
That intent is not assigned to this device |
409 |
intent_not_actionable |
Already settled, cancelled, or expired |
403 |
(standing reason) | Your device or station lost standing |
A 409 carrying "status": "expired" means the intent lapsed while your
application was running. Do not retry it; the collection has to start again
from the cashier.