Перейти к содержимому

Передача на смарт-кассу

Смарт-касса принимает деньги через сертифицированное платёжное приложение, которое уже живёт на устройстве. Sitora никогда не видит карту, PIN или сессию провайдера — она передаёт вашему компаньону описанный приём денег и записывает, что вернулось.

кассир выбирает маршрут smart_pos
│
▼
намерение создано ── ваш опрос ──▶ presented
│ │
│ работает платёжное приложение
│ │
│ ваш отчёт
│ ▼
│ processing
│ │
│ кассир подтверждает (или отменяет)
▼ ▼
expired succeeded

Маршрут предлагается кассиру, только когда к кассе прикреплено живое устройство передачи. «Живое» значит активно шлющее heartbeat — у замолчавшего компаньона маршрут отбирают, а не выдают ему работу, которую никто не выполнит.

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 равен null, когда принимать нечего. Получение нового назначения записывает его как presented — это единственное изменение состояния, которое устройство может вызвать само по себе.

Каждый ответ, и 200, и 304, несёт X-Sitora-Poll-After и Retry-After с числом секунд до следующего опроса — сегодня их три. Этим числом владеет Sitora, и она может изменить его без вашего релиза.

handoff_target — это ссылка запуска, которую владелец ресторана настроил для этого устройства. Sitora считает её непрозрачной: её никогда не разбирают, не сопоставляют и не ветвятся по ней. Если ваш компаньон и так знает, что запускает, оставьте её пустой.

expires_at — настоящий. Истёкшее намерение становится expired, и кассиру приходится создавать новое, так что не сидите на назначении.

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"
}
Исход Когда использовать
reported_success Платёжное приложение вернуло одобрение
reported_declined Оно вернуло отказ
reported_cancelled Гость или кассир бросил операцию в приложении
reported_unknown Оно не вернуло ничего пригодного, или вы не дождались

provider_reference — собственная ссылка приложения на попытку: RRN, номер слипа. Она становится ссылкой, которую наследует подтверждение кассира, и в этом практическая выгода интеграции: никому не нужно перенабирать номер с бумажного слипа.

provider_code — ваш кодированный результат, хранимый дословно как машинный словарь. Сотрудникам он никогда не показывается как сообщение.

Присылайте client_idempotency_key. Повтор с тем же ключом возвращает исходный результат, а не записывает второй отчёт.

Он переводит намерение в processing и показывает кассиру, что вы сказали.

Он не:

  • создаёт транзакцию,
  • помечает заказ оплаченным,
  • завершает намерение — ни в ту, ни в другую сторону.

Если вы сообщили отказ, а на экране кассира всё ещё предлагается «провести», — это правильное поведение, а не баг: объявленный устройством отказ, окажись он ошибочным, освободил бы заказ для второго приёма денег, поэтому Sitora оставляет человека в контуре для обоих ответов. Отчитывайтесь честно и дайте решать кассиру.

reported_unknown — полноценный ответ. У операции, которая не дождалась ответа, исход неизвестен, и сказать об этом гораздо лучше, чем гадать: кассир может посмотреть на терминал и подтвердить или отменить по тому, что видит сам.

Статус Код Значение
404 handoff_not_assigned Это намерение не назначено на это устройство
409 intent_not_actionable Уже проведено, отменено или истекло
403 (причина правомочности, в detail) Ваше устройство или касса утратили правомочность
503 content_key_missing Эта установка Sitora сконфигурирована неверно; повтор не поможет

404 и 409 отвечают {"code": "..."} без detail, а 409 добавляет status намерения. 403 отклоняется ещё до того, как запрос дойдёт до этого эндпоинта, поэтому он называет причину прозой внутри detail — аутентификация объясняет, где прочитать эту причину как поле.

409 с "status": "expired" означает, что намерение истекло, пока работало ваше приложение. Не повторяйте его; приём денег придётся начинать заново от кассира.