Тема
Идемпотентность
Связь рвётся, и касса повторяет запрос. Без защиты повтор начислил бы баллы дважды — это реальная проблема, из-за которой контракт устроен именно так.
Правило: один чек — один idempotencyKey, сгенерированный один раз и сохранённый до получения ответа. Генерируйте его в момент, когда кассир нажал «Оплатить», и переиспользуйте при каждом ретрае. Не генерируйте новый ключ на повторе — это создаст второй чек.
Повтор с уже использованным ключом возвращает 409 Conflict:
json
{
"status": 409,
"title": "Повторная операция",
"detail": "Запись с такими данными уже существует",
"existingSaleId": 90210,
"type": "https://docs.uget.uz/errors/conflict"
}409 с полем existingSaleId — это успех, а не ошибка. Первый запрос дошёл и чек проведён; возьмите existingSaleId и закройте продажу как успешную. Показывать кассиру ошибку в этом случае неверно — он проведёт чек второй раз вручную.
Ключ уникален в пределах мерчанта и живёт вечно: нельзя переиспользовать его для другого чека даже через год.