Kontentga o'tish

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.

cashier picks the smart_pos route
intent created ──── your poll ────▶ presented
│ │
│ payment app runs
│ │
│ your report
│ ▼
│ processing
│ │
│ cashier attests (or cancels)
▼ ▼
expired succeeded

The 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.

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.

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.

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.

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.