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

Идемпотентность, ошибки и лимиты

После таймаута непонятно, прошёл запрос или нет. Повторите ту же операцию с тем же Idempotency-Key, чтобы не создать второй инвойс.

  1. До первого запроса создайте уникальный ключ и сохраните рядом с инвойсом в вашей системе.
  2. Передайте его в Idempotency-Key при создании или изменении бизнес-объекта.
  3. После таймаута повторите тот же метод, путь и тело с тем же ключом.
  4. Для нового действия создайте новый ключ.

Ключ должен быть непустым и не длиннее 128 байт. Повтор завершённого действия вернёт сохранённый ответ. Другое тело с тем же ключом даст 409 idempotency_conflict.

Это относится к изменениям инвойсов, магазинов, ключей, вебхуков и другим бизнес-операциям. GET-запросы и запросы входа не используют этот механизм. Требования указаны у каждого метода.

external_id связывает инвойс или депозит с записью в вашей системе, но не заменяет ключ идемпотентности.

Пример:

{"error":{"code":"idempotency_conflict","message":"idempotency_conflict"}}

В программе используйте error.code. Сначала проверьте HTTP-статус, потом разбирайте тело ответа.

Код Что делать
unauthorized Проверить ключ, права и ограничение IP. Если сессия истекла — войти заново.
mfa_required Подтвердить второй фактор с токеном сессии.
onboarding_required Завершить /onboarding перед работой с магазинами.
idempotency_key_required Передать сохранённый непустой ключ до 128 байт.
idempotency_conflict Найти исходный запрос. Не создавать второй инвойс молча.
json_content_type_required / invalid_json Отправить Content-Type: application/json и только описанные поля.
unsupported_network / unsupported_asset Выбрать поддерживаемую сеть и токен.
network_not_ready / asset_not_ready Дождаться готовности или выбрать другой доступный маршрут.
amount_below_minimum / fee_exceeds_amount Проверить сумму, знаки токена и условия магазина.
shop_archived / shop_not_found Проверить магазин и права доступа.
invalid_expires_in Передать 1d, 7d, 30d, 180d или 365d и только при создании инвойса. У депозитов нет срока.
invalid_assets / issuance_in_group Передать разные пары {chain_id, token} без chain_id и token; отменять или отключать группу по её собственному id. См. несколько токенов или сетей.
solana_setup_required / tron_setup_required Сначала задать получателя Solana или Tron у магазина.
invoice_amount_limit / sandbox_amount_limit Уменьшить сумму до лимита.
active_invoice_limit_reached / deposit_address_limit_reached Отменить ненужные инвойсы или отключить ненужные депозиты либо попросить Invoise поднять лимит.
api_key_limit_reached / too_many_allowed_ips / webhook_limit_reached Отозвать неиспользуемые ключи, сократить список IP или использовать существующий адрес вебхука.
team_limit_reached Удалить участника или отозвать приглашение либо попросить Invoise поднять лимит.
account_disabled Сотрудники Invoise заблокировали аккаунт; причина — в error.details. См. заблокированные аккаунты.
rate_limited Подождать столько секунд, сколько указано в Retry-After, и повторить.

Если запрос превышает лимит, Invoise отклоняет его с обычным телом ошибки и кодом из таблицы.

Лимит Значение Ошибка
Сумма одного инвойса 1 000 000 токенов 400 invoice_amount_limit
Сумма одного инвойса или имитированного перевода в Sandbox 10 000 токенов 400 sandbox_amount_limit
Активные инвойсы мерчанта 2 000 400 active_invoice_limit_reached
Активные депозитные адреса мерчанта в одном семействе сетей EVM 10 000, Tron 10 000, Solana 10 400 deposit_address_limit_reached
Неотозванные API-ключи магазина 10 400 api_key_limit_reached
Разрешённые IP-адреса или CIDR-диапазоны одного ключа 10 400 too_many_allowed_ips
Адреса вебхуков магазина 10 400 webhook_limit_reached
Участники и ожидающие приглашения мерчанта 10 400 team_limit_reached
Запросы в минуту 1 200, из них не больше 120 не-GET 429 rate_limited

Лимиты сумм указаны в целых токенах, а не в минимальных единицах. Все поддерживаемые токены — долларовые стейблкоины, поэтому 1 000 000 токенов — это около $1 000 000.

Инвойс активен, пока он не оплачен, не отменён и не истёк. Инвойс с несколькими сетями считается один раз. Депозитный адрес активен, пока его не отключили; каждая сеть депозита — отдельный адрес. Sandbox и боевой режим считаются отдельно для обоих лимитов. Сотрудники Invoise могут изменить для мерчанта лимиты инвойсов, депозитных адресов и команды.

Лимит команды проверяется и при приглашении, и при его принятии. URL адреса вебхука можно изменить, поэтому существующий адрес можно использовать вместо нового.

Запросы считаются по API-ключу, по сессии в интерфейсе или, без авторизации, по IP клиента. Ответ 429 содержит Retry-After: 60.

При таймаутах и временных серверных ошибках сохраняйте тот же ключ и увеличивайте задержку. При 429 подождите столько секунд, сколько указано в Retry-After. Ошибки входных данных и доступа сначала исправьте.

Повторную доставку вебхуков делает Invoise. Надёжно сохраните событие, ответьте 2xx и обработайте его. Дубли отсеивайте по Invoise-Event-ID.

Старые маршруты /projects — аналоги /shops с общей областью идемпотентности. Для новых интеграций используйте /shops. В старых кодах ошибок может встречаться project_*.