Перейти к содержанию
STONS

Коды ошибок

Этот документ перечисляет все error.code, которые возвращают публичные маршруты /v1 и /checkout/v1, с HTTP-статусом, который использует сервис, и тем, что делать клиенту. Прочитайте его, когда пишете обработку ошибок интеграции.

Тело ошибки

Любой ответ API с ошибкой имеет одно и то же тело:

{ "error": { "code": "route_not_found", "message": "Route not found" } }
Поле Тип Смысл
error.code string Машиночитаемый код из перечня. Сервис не переименовывает и не удаляет коды; новые коды появляются в журнале изменений
error.message string Пояснение для человека на английском. Текст может меняться: не разбирайте его в коде
error.details array Есть, только если запрос не прошёл проверку по схеме: по элементу на каждую проблему, с path — где проблема (body.amount, params.id или body для лишнего поля) — и message. У validation_failed из более поздней проверки, например числа знаков суммы, details нет; её message начинается с имени поля

Каждый ответ, включая ошибки, содержит заголовок X-Request-Id. Сообщайте его значение оператору, когда сообщаете о проблеме: по нему находится запрос в логах. Если клиент сам передал X-Request-Id из 1–128 латинских букв, цифр и символов ., _, :, -, сервис использует его, иначе генерирует UUID.

Описание OpenAPI, GET /v1/openapi.json, объявляет один список кодов для всех маршрутов сервиса, включая внутренние. Публичный маршрут возвращает только коды из перечня ниже.

Два вида ответов такого тела не имеют:

  • HTTPS-прокси отвечает на путь вне /v1/ кодом 404 с пустым телом;
  • во время остановки API отвечает 503 с телом в другом формате.

Ответ, тело которого не в формате выше, обрабатывайте по HTTP-статусу.

Как обрабатывать ошибки

  • 400, 413, 415 — запрос неверный. Исправьте его: тот же запрос получит ту же ошибку.
  • 401 — проверьте ключ и имя заголовка.
  • 403 — мерчант отключён или не одобрен. Запросы будут отклоняться, пока это не изменит владелец или оператор.
  • 404 — проверьте путь и идентификатор.
  • 409 — запрос конфликтует с существующим объектом: ключ идемпотентности (order_id, reference) использован повторно с другими данными, или выбор токена на странице оплаты уже сделан либо уже невозможен. Не повторяйте тот же запрос.
  • 422 — запрос корректен, но его отклоняет бизнес-правило; код называет правило. Тот же запрос получит ту же ошибку, пока не изменится настройка, стоящая за правилом.
  • 429 — повторите через число секунд из заголовка retry-after.
  • 500, 503 — проблема сервиса. Повторите позже с растущей задержкой и тем же ключом идемпотентности: order_id для инвойса, reference для выплаты. Повтор не создаёт второй объект.
  • Кода нет в перечне — обработайте ответ по классу HTTP-статуса: 4xx — ошибка в запросе, 5xx — проблема сервиса.

Перечень

HTTP error.code Маршруты Когда Что делать клиенту
400 validation_failed все Тело, путь или параметры не проходят проверку: поле отсутствует, лишнее, null или неверного формата. Или не проходит более поздняя проверка поля: формат или число знаков суммы, точность цены, external_user_id в режиме per_user Исправить поле, названное в details или в начале message
400, 413, 415 bad_request маршруты с телом запроса Тело — не JSON или пустое при Content-Type: application/json (400), больше 16 КиБ (413) или с неподдерживаемым Content-Type (415) Отправлять JSON-объект с Content-Type: application/json
401 unauthorized /v1 Нет заголовка X-Api-Key, либо ключ неверного формата, неизвестен, отозван или его секрет не совпадает Проверить ключ. Причина намеренно не уточняется — см. аутентификацию
403 merchant_disabled /v1 Мерчант отключён — оператором или владельцем в кабинете Включить проект в кабинете. Если проект выключил оператор, включить его может только оператор
403 merchant_not_approved POST /v1/invoices, POST /v1/addresses, POST /checkout/v1/invoices/{id}/select Мерчант ещё не одобрен после проверки или отклонён Дождаться проверки. Причину отклонения владелец видит в кабинете и может исправить заявку и отправить её снова. Повтор с order_id существующего инвойса возвращает этот инвойс
404 route_not_found любой путь под /v1 или /checkout/v1 Нет маршрута с таким методом и путём Проверить метод и путь
404 invoice_not_found GET /v1/invoices/{id}, GET /checkout/v1/invoices/{id}, POST /checkout/v1/invoices/{id}/select Инвойса нет или он принадлежит другому мерчанту. На маршрутах /checkout/v1 ещё: мерчант отключён Проверить идентификатор
404 payout_not_found GET /v1/payouts/{id} Выплаты нет или она принадлежит другому мерчанту Проверить идентификатор
404 deposit_not_found GET /v1/deposits/{tx_hash} В транзакции нет перевода на адрес мерчанта: сервис её не знает, она шла только другим мерчантам или её блок ещё не просканирован Проверить хэш. Для только что отправленной транзакции повторить позже — см. проверку перевода
409 address_mode_mismatch POST /v1/addresses Мерчант работает в режиме per_invoice Брать адрес из инвойса — см. режимы
409 order_id_conflict POST /v1/invoices Инвойс с этим order_id есть с другим активом, суммой, currencies, external_user_id, return_url или cancel_url Проверить, не используется ли order_id повторно для другого заказа, — см. идемпотентность
409 reference_conflict POST /v1/payouts Выплата с этим reference есть с другим активом, адресом или суммой Проверить, не используется ли reference повторно для другой выплаты
409 asset_already_selected POST /checkout/v1/invoices/{id}/select У инвойса уже другой актив. Выбор окончательный Показать покупателю инвойс с его токеном
409 invoice_expired POST /checkout/v1/invoices/{id}/select Дедлайн инвойса прошёл или инвойс уже не в статусе created Показать покупателю состояние инвойса
422 address_mode_disabled POST /v1/addresses, POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Платформа временно приостановила режим адресов мерчанта Сообщить покупателю, что оплата сейчас недоступна, и повторить позже. Повтор с order_id существующего инвойса возвращает этот инвойс; переводы на уже выданные адреса зачисляются как обычно — см. режим на паузе
422 mode_not_allowed POST /v1/addresses, POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Режим адресов этого проекта ему не разрешён: оператор разрешает режим по проектам (ADR-0066) Обратиться к оператору. Переводы на уже выданные адреса зачисляются как обычно
422 asset_not_supported POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Актив неизвестен или не принимается к оплате Использовать актив из таблицы активов, который оплачивает инвойсы
422 asset_not_payable POST /v1/payouts В этом активе сервис не делает выплат: он неизвестен, неактивен или только для приёма Использовать актив из таблицы активов, в котором есть выплаты
422 asset_payments_disabled POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Оператор временно выключил приём в активе Предложить другой актив или повторить позже. Повтор с order_id существующего инвойса возвращает этот инвойс
422 asset_disabled_by_merchant POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Приём в активе выключен в настройках проекта Предложить другой актив или включить токен в разделе проекта «Токены» в кабинете. Повтор с order_id существующего инвойса возвращает этот инвойс
422 asset_payouts_disabled POST /v1/payouts Оператор временно выключил выплаты в активе Повторить позже с тем же reference. Выплаты, созданные раньше, исполняются как обычно
422 amount_below_minimum POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Сумма или цена меньше минимального депозита актива Увеличить сумму или выбрать другой актив
422 asset_required POST /v1/invoices Нет asset, а в установке нет страницы оплаты, где покупатель выбрал бы токен Передать asset
422 no_payable_assets POST /v1/invoices Нет ни asset, ни currencies, а мерчант сейчас не принимает ни одного актива, у которого есть курс Включить токен в настройках проекта или передать asset
422 asset_not_offered POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Актив нельзя предложить для цены в долларах США: у сервиса нет для него курса; на маршруте выбора ещё: его нет в currencies инвойса Выбрать другой актив
422 redirect_url_not_allowed POST /v1/invoices return_url или cancel_url не на сайте мерчанта Использовать адрес на сайте проекта или на сайте адреса проекта того же вида — см. адреса возврата
422 address_not_whitelisted POST /v1/payouts Адреса нет в вайтлисте мерчанта по этому активу, или задержка перед его первым использованием ещё не прошла. Сообщение называет, какой из двух случаев См. куда можно платить. Ответ не зависит от суммы
429 rate_limited /v1, /checkout/v1 Превышен лимит запросов Повторить через число секунд из заголовка retry-after — см. лимиты запросов
500 internal_error все Необработанная ошибка сервиса. Подробности пишутся в лог сервиса, а не в ответ Повторить позже с тем же ключом идемпотентности. При повторении сообщить X-Request-Id
503 service_unavailable POST /v1/addresses, POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Сервис не может вывести новый адрес в текущей конфигурации; сообщение называет причину Повторить позже. Если не проходит, обратиться к оператору
503 addresses_exhausted POST /v1/addresses, POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Закончились индексы деривации адресов: заняты все 2^31. Практически недостижимо Обратиться к оператору
503 network_fee_quote_unavailable POST /v1/invoices У проекта осталась прежняя настройка «комиссию сети платит покупатель», поэтому новый инвойс не создаётся. Повтор с order_id существующего инвойса возвращает этот инвойс Владелец сохраняет «Кто платит комиссии» в настройках проекта в кабинете; затем повторить
503 rate_unavailable POST /v1/invoices, POST /checkout/v1/invoices/{id}/select Сейчас нет свежего курса: при создании инвойса без asset — ни у одного разрешённого токена, при выборе — у монеты выбранного актива. Ничего не создаётся и не записывается. Повтор с order_id существующего инвойса возвращает этот инвойс Повторить позже с растущей задержкой и тем же order_id. На странице оплаты — предложить другой токен или попросить покупателя попробовать позже. Если не проходит, обратиться к оператору
503 payouts_halted POST /v1/payouts Выплаты остановлены — по этому активу или целиком; сообщение говорит, какой из двух случаев. Причина не раскрывается Повторить позже с тем же reference. Повтор существующего reference возвращает эту выплату и во время остановки

Примеры

Несуществующий путь:

curl -s https://api.stons.io/v1/unknown

404:

{"error":{"code":"route_not_found","message":"Route not found"}}

Запрос к POST /v1/invoices с "expires_in": 60 не проходит проверку по схеме, и details перечисляет все проблемные поля:

{
  "error": {
    "code": "validation_failed",
    "message": "Request validation failed",
    "details": [{ "path": "body.expires_in", "message": "Too small: expected number to be >=300" }]
  }
}

Запрос с "asset": "USDT_TRON" и "amount": "49.9000001" проходит проверку по схеме, но не проходит проверку числа знаков, поэтому details нет:

{
  "error": {
    "code": "validation_failed",
    "message": "amount: amount has more than 6 digits after the decimal point (USDT_TRON has 6 decimals)"
  }
}