Надёжность
Коды ошибок
Успешные ответы приходят с кодами 2xx. Ошибка — это HTTP-код 4xx или 5xx и объект error с машиночитаемым кодом и понятным сообщением.
{
"error": {
"type": "invalid_request_error",
"code": "validation_failed",
"message": "Проверьте параметры запроса",
"param": "amount",
"fields": {
"amount": "Минимальная сумма — 10 ₽"
},
"request_id": "req_8b2f6d1c0a"
}
}Формат ошибки
code— машиночитаемый код, по нему стоит ветвить логику.message— описание на русском, его можно показать в логах или администратору.paramиfields— для ошибок валидации: какое поле и что с ним не так.request_id— идентификатор запроса, тот же, что в заголовкеX-Request-Id. Приложите его, если пишете в поддержку.type— группа ошибки.
Повторять запрос имеет смысл при кодах 429, 500 и 503, а также при сетевых ошибках — с тем же ключом идемпотентности.
const res = await fetch(url, init);
const body = await res.json();
if (!res.ok) {
const { code, message, fields, request_id } = body.error;
switch (code) {
case 'validation_failed':
return showFieldErrors(fields);
case 'payment_declined':
case 'insufficient_funds':
case 'card_expired':
return askForAnotherMethod(message);
case 'rate_limited':
return retryAfter(Number(res.headers.get('Retry-After')) || 1);
default:
logger.error({ code, request_id }, message);
throw new Error(message);
}
}Коды
| Код | HTTP | Что случилось и что делать |
|---|---|---|
authentication_failed | 401 | Ключ не передан, неверен или отозван. Проверьте заголовок Authorization и режим ключа. Отозванный ключ замените новым в кабинете. |
permission_denied | 403 | Действие недоступно для этого ключа или мерчанта. Например, боевой режим ещё не включён. Уточните у менеджера. |
not_found | 404 | Объект не найден. Проверьте идентификатор и режим: тестовые объекты не видны по боевому ключу и наоборот. |
invalid_request | 400 | Некорректный запрос. Невалидный JSON, неизвестный параметр или недопустимое сочетание полей. Подробности — в message и param. |
validation_failed | 422 | Параметры не прошли проверку. Ошибки по полям — в объекте fields. Исправьте значения и повторите. |
idempotency_conflict | 409 | Ключ идемпотентности уже использован с другим телом. Для нового запроса сгенерируйте новый Idempotency-Key. |
rate_limited | 429 | Превышен лимит запросов. Подождите столько секунд, сколько указано в Retry-After, и повторите. |
payment_declined | 402 | Банк отклонил операцию. Предложите покупателю другую карту или другой способ оплаты. |
insufficient_funds | 402 | Недостаточно средств. Сообщите покупателю; повторное списание по подписке запланируйте позже. |
card_expired | 402 | Срок действия карты истёк. Попросите покупателя обновить карту. |
method_unavailable | 400 | Метод оплаты недоступен. Метод не подключён для вашего магазина или временно отключён — см. статус сервиса. |
network_unavailable | 400 | Сеть USDT не поддерживается или не совпадает. Передайте crypto_network из списка trc20, ton, bep20, erc20, sol. Если сеть зафиксирована в платеже или ссылке, другую выбрать нельзя. |
amount_too_small | 400 | Сумма меньше минимальной. Минимальная сумма платежа — 10 ₽ (1000 копеек). |
amount_too_large | 400 | Сумма больше максимальной. Максимальная сумма платежа — 600 000 ₽ (60 000 000 копеек). |
partner_not_configured | 503 | Боевой приём ещё не активирован. Боевые платежи станут доступны после завершения подключения. Тестовые ключи работают. |
internal_error | 500 | Внутренняя ошибка. Повторите запрос с тем же Idempotency-Key. Если ошибка не уходит — напишите менеджеру и приложите request_id. |
{
"error": {
"type": "api_error",
"code": "partner_not_configured",
"message": "Боевой приём платежей ещё не активирован для этого магазина",
"request_id": "req_31c9e07d5f"
}
}