Идемпотентность, ошибки и лимиты
После таймаута непонятно, прошёл запрос или нет. Повторите ту же операцию с тем же Idempotency-Key, чтобы не создать второй инвойс.
Один ключ на действие
Заголовок раздела «Один ключ на действие»- До первого запроса создайте уникальный ключ и сохраните рядом с инвойсом в вашей системе.
- Передайте его в
Idempotency-Keyпри создании или изменении бизнес-объекта. - После таймаута повторите тот же метод, путь и тело с тем же ключом.
- Для нового действия создайте новый ключ.
Ключ должен быть непустым и не длиннее 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_*.