Тема
Ошибки и границы контракта
Ошибки
Формат — RFC 9457 Problem Details, Content-Type: application/problem+json. Тексты в detail готовы к показу кассиру и локализуются заголовком Accept-Language (ru по умолчанию, uz — узбекская латиница). Разбирать detail программно не нужно и не следует: ориентируйтесь на HTTP-код и type.
| Код | Когда | Что делать кассе |
|---|---|---|
400 | пустой чек, отрицательная цена, нет consumerId и phone | ошибка в вашем запросе, показать кассиру и не повторять |
401 | ключ не предъявлен, неверен, отозван, либо заблокирован мерчант или уволен сотрудник-автор | не повторять; сообщить владельцу, что нужен новый ключ |
404 | клиент не найден; по code — код неверен или истёк | по телефону — продать как анонимный чек; по коду — попросить клиента показать QR заново (код живёт 5 минут) |
409 | повтор по idempotencyKey | считать успехом, взять existingSaleId |
422 | нарушено бизнес-правило (например, списать больше допустимого); для чека с consumerId — клиент не опознан (поиск не делали или он был давно: больше 7 суток, а при списании баллов — больше 15 минут); в GET /consumers/resolve — не передан ни code, ни phone, либо владелец отключил поиск по телефону | показать detail кассиру; при неопознанном клиенте — заново GET /consumers/resolve; при отключённом поиске по телефону — просить код из QR |
429 | превышен лимит частоты: поиск клиента — 30 в минуту на сотрудника ключа и 120 на мерчанта, неудачные поиски по коду — 10 в минуту на сотрудника ключа, предпросмотр — 600 в минуту на ключ | повторить через Retry-After секунд |
5xx | сбой на стороне uget | повторить с тем же idempotencyKey с нарастающей паузой |
401намеренно не различает «ключа нет» и «ключ отозван» — чтобы перебором нельзя было выяснить, существует ли ключ. Если касса внезапно получает 401, ключ отозван или выпущен заново.
Ретраи. Повторять можно и нужно только POST /sales (с тем же ключом идемпотентности) и GET /consumers/resolve. Предпросмотр повторять бессмысленно — просто запросите заново. Разумная схема: 3 попытки с паузами 1с, 3с, 10с, дальше — предложить кассиру провести чек без uget.
Границы контракта
Не пробелы, а осознанные решения:
- Одна точка — один ключ. Точка берётся из ключа, а не из тела запроса: иначе чужая касса того же мерчанта записывала бы продажи на любую точку. Сети с десятками касс получают десятки ключей; предусмотрите хранение ключа на уровне точки, а не одного глобального.
- Смена остаётся у вас. uget не ведёт вашу смену и не просит её номер: две системы учёта смен рассинхронизируются на первом же сбое связи. Отчёт по точке строится по продажам за период.
- Частичный возврат есть, но не для любого чека — условия и причины отказов в 4.4. Чек с акцией, подарком, штампами, сертификатом или картой возвращается целиком.
- Лимиты частоты действуют на поиск клиента и предпросмотр (числа — в разделе «Ошибки»). На проводку продажи и возврат отдельного лимита пока нет, но отсутствие
429не значит, что поток можно не ограничивать: держите разумный темп.