Ошибки
Формат
{
"error": {
"code": "PAYMENT_NOT_FOUND",
"message": "Payment with id 'pay_xxx' not found",
"details": {}
}
}
Таблица
| HTTP | Code | Когда | Что делать |
|---|---|---|---|
| 400 | VALIDATION_ERROR |
Невалидные параметры запроса. Отдельный случай с HTTP 422 — client_phone в POST /payments не в формате E.164: ожидается «+» и 10–15 цифр после него. Ещё один случай с 422 — значение в объекте payer не прошло правила полей, path вида payer.full_name; форма самого объекта (не объект, нет обязательного поля, лишний ключ) — обычный 400, см. объект payer |
Проверь details, исправь запрос. Для телефона — приведи его к E.164 и повтори запрос |
| 400 | INVALID_JSON |
Тело запроса — не валидный JSON. Проверка тела идёт до авторизации, поэтому код приходит и на невалидных ключах | Пошли корректный JSON с заголовком Content-Type: application/json |
| 400 | MISSING_IDEMPOTENCY_KEY |
Нет заголовка Idempotency-Key на POST |
Добавь UUID |
| 400 | KYC_REQUIRED |
Клиент не прошёл KYC (если для аккаунта настроена KYC-проверка) | Отправь клиента на KYC-верификацию |
| 400 | KYC_PROCESSING |
KYC-верификация ещё обрабатывается | Повтори через несколько минут |
| 400 | KYC_FAILED |
KYC-верификация отклонена | Клиент должен пройти KYC заново |
| 400 | KYC_NOT_REQUIRED |
Вызов KYC-эндпоинта, когда KYC не настроен для аккаунта | KYC не нужен, просто создавай платёж |
| 502 | KYC_PROVIDER_ERROR |
Проверяющая сторона не ответила при создании платежа (не при вызове /kyc/*) |
Временная ошибка. Ретрай через 30–60 сек с тем же Idempotency-Key |
| 403 | PROVIDER_DISABLED |
KYC для твоего аккаунта отключён. Возвращают все /kyc/* — до любых других проверок |
Ретрай не поможет — свяжись с X-Hub. См. Ошибки KYC |
| 403 | QR_PAYMENTS_DISABLED |
Аккаунт настроен только на рекуррентные списания — разовые платежи по QR ему запрещены | Не создавай POST /payments; работай через /subscriptions. Нужен приём разовых — напиши в X-Hub |
| 400 | CARD_NOT_SUPPORTED |
Запрошен payment_method: "card", а приём карт твоему аккаунту не подключён. Платёж не создаётся |
Создавай платёж с payment_method: "sbp". Нужен приём карт — напиши в X-Hub, это настройка аккаунта, флагом в запросе не включается. Подробнее — оплата картой |
| 400 | PAYMENT_ROUTE_UNAVAILABLE |
На POST /payments: для запрошенного способа оплаты у твоего аккаунта нет рабочего маршрута — например, способу оплаты не назначен терминал. Платёж не создаётся. Редкий вариант — тот же код с HTTP 503: маршрут не удалось проверить из-за временного сбоя на нашей стороне |
400 — ретрай не поможет, пока не изменится настройка аккаунта: напиши в X-Hub. 503 — временный сбой: ретрай через 30–60 сек с тем же Idempotency-Key. Подробнее — отказы при создании платежа |
| 422 | PAYMENT_UNAVAILABLE |
На POST /payments: приём по этому способу оплаты для твоего аккаунта сейчас недоступен. Платёж не создаётся. Слово «temporarily» в message значит «до изменения настройки на стороне X-Hub», а не «через минуту» |
Ретрай не поможет — повтор получит тот же ответ. Напиши в X-Hub. Подробнее — отказы при создании платежа |
| 400 | SANDBOX_NOT_SUPPORTED |
Эндпоинт отключён в sandbox для твоего аккаунта (у части конфигураций — /kyc/*) |
Тестируй этот флоу в боевом режиме или свяжись с X-Hub |
| 400 | AMOUNT_BELOW_MINIMUM |
Сумма разового платежа (POST /payments) ниже минимума — 30 ₽, одинаково для всех аккаунтов. Списания по уже выданному мандату подписки порогу не подчиняются |
Увеличь сумму — точное значение минимума приходит в message |
| 400 | AMOUNT_TOO_LOW |
Сумма меньше минимальной для операции (пример: обмен < 1000 ₽) | Увеличь сумму |
| 400 | AMOUNT_TOO_HIGH |
Сумма превышает максимум | Разбей на несколько операций или свяжись с X-Hub |
| 422 | CLIENT_NOT_REGISTERED |
Клиент не прошёл KYC-регистрацию для USDT→RUB | Сначала зарегистрируй клиента через /kyc/register |
| 403 | CLIENT_BLOCKED |
Аккаунт клиента заблокирован | Свяжись с X-Hub |
| 401 | UNAUTHORIZED |
Неверные X-Api-Key / X-Api-Secret |
Проверь ключи |
| 401 | MODE_MISMATCH |
Ключ не-активного режима (test/live) — активен другой режим | Переключи режим в кабинете или используй ключи активного режима |
| 403 | IP_NOT_WHITELISTED |
IP-адрес не в whitelist мерчанта | Добавь IP в настройках или свяжись с X-Hub |
| 404 | PAYMENT_NOT_FOUND |
Платёж не существует / чужой | Проверь ID |
| 404 | NOT_FOUND |
Обмен не существует / чужой; или такого пути в /api/v1 нет |
Проверь ID и путь |
| 410 | WITHDRAWAL_DISCONTINUED |
Запрос к выведенным из эксплуатации эндпоинтам /withdrawals |
Ничего не делать — выплаты происходят автоматически, см. Выплаты |
| 409 | DELIVERY_PROOF_LOCKED |
POST /payments/:id/delivery-proof: хэш по платежу уже подтверждён, заменить его через API нельзя |
Если хэш передан по ошибке, напиши в X-Hub. См. хэш перевода клиенту |
| 409 | DELIVERY_PROOF_CONFLICT |
POST /payments/:id/delivery-proof: хэш изменён параллельным запросом |
Прочитай состояние запросом GET /payments/:id/delivery-proof и повтори запрос |
| 409 | EXCHANGE_IN_PROGRESS |
Обмен уже в обработке | Дождись финального статуса |
| 409 | INVALID_STATUS |
Операция невалидна для текущего статуса (напр. попытка отменить уже завершённый обмен; хэш перевода клиенту по платежу не в статусе paid или settled) |
Проверь статус перед действием |
| 409 | IDEMPOTENCY_TERMINAL |
Повтор запроса с тем же idempotency_key после финального статуса |
Используй новый ключ |
| 502 | RATE_INVALID |
Временная ошибка получения курса для обмена | Ретрай через 30-60 сек |
| 503 | PROVIDER_UNAVAILABLE |
Внешняя платёжная система временно недоступна. Операция могла пройти — мы не увидели ответ | Ретрай с тем же Idempotency-Key через 30-60 сек. Второй платёж не создастся |
| 503 | PROVIDER_NOT_CONFIGURED |
Операция для твоего аккаунта сейчас недоступна на стороне X-Hub. Так же сейчас отвечают списания по подпискам в боевом режиме — см. Подписки | Свяжись с X-Hub. На списаниях по подпискам повтор ответ не изменит |
| 503 | KYC_UNAVAILABLE |
На /kyc/*: аккаунту положен KYC, но проверка сейчас недоступна на нашей стороне. Это не «KYC не нужен» — не пропускай верификацию клиента |
Ретрай через 1–2 мин; если долго — напиши в X-Hub |
| 500 | KYC_PERSIST_FAILED |
На POST /kyc/register: проверяющая сторона клиента приняла, но у нас не сохранилась запись об этом (сбой на нашей стороне уже ПОСЛЕ успешного ответа проверяющей стороны) |
Не повторяй запрос с теми же данными — клиент мог быть создан у проверяющей стороны, повтор для части конфигураций навсегда ломает повторную регистрацию по тому же e-mail/телефону. Напиши в X-Hub с временем запроса и телефоном/e-mail клиента — восстановим вручную |
| 503 | RATE_UNAVAILABLE |
GET /rates: источник курса временно недоступен |
Ретрай через 30-60 сек |
| 404 | EXCHANGE_RATE_NOT_SUPPORTED |
Запрос курса по способу оплаты: курс не отдаётся ни для одного терминала | Не запрашивай курс — повтор ответ не изменит |
| 400 | FEATURE_NOT_ENABLED |
Опция не подключена на твоём аккаунте (например USDT→RUB или KYC; хэш перевода клиенту — по платежу, по которому он не принимается, в том числе в тестовом режиме) | Свяжись с X-Hub для подключения |
| 503 | FEATURE_DISABLED |
Направление временно недоступно у всех мерчантов. Твоя интеграция исправна | Подожди и ретрай. В поддержку — если держится долго |
| 429 | RATE_LIMIT_EXCEEDED |
Превышен лимит. Создание платежа: 120 req/min на ключ или 120 req/min на IP. Остальные вызовы: 60 req/min на ключ или 300 req/min на IP | Жди Retry-After секунд, см. Rate Limiting |
| 500 | INTERNAL_ERROR |
Серверная ошибка | Ретрай через 30 сек, если повторяется — пиши команде |
| 404 | SUBSCRIPTION_NOT_FOUND |
Подписка не существует / чужая / другого режима | Проверь ID |
| 409 | CHARGE_MANDATE_INACTIVE |
Списание по неактивному мандату (подписка не active) |
Дождись активации / возобнови подписку |
| 409 | CAP_EXCEEDED |
Списание превышает cap_amount_rub или cap_window_rub |
Уменьши сумму или измени потолки (PATCH) |
| 409 | INVALID_STATE |
Недопустимый lifecycle-переход подписки (pause/resume/cancel) | Проверь текущий status |
| 501 | RECURRING_NOT_SUPPORTED |
Подписки недоступны для твоего аккаунта: подписка или списание не создаются | Ретрай не поможет — напиши в X-Hub. См. Подписки |
| 502 | PROVIDER_ERROR |
Операция отклонена платёжной системой. На POST /subscriptions — не удалось инициировать привязку мандата; на POST /:id/charges — отказ по списанию, включая отказ банка; на /kyc/* — проверяющая сторона не ответила |
Для привязки и KYC — повтори через 30–60 сек. Для списания это чаще окончательный отказ, см. Ошибки списания |
| 404 | REFUND_NOT_FOUND |
Заявка на возврат не существует / чужая / из другой среды. Приходит на чтение и на отмену | Проверь ID и режим (test/live) |
| 413 | PAYLOAD_TOO_LARGE |
Тело запроса больше лимита (100 КБ). Проверка тела идёт до авторизации | Уменьши тело запроса, например metadata |
| 400 | NOT_REFUNDABLE |
Платёж не в возвратном статусе | Возврат возможен только по оплаченному платежу, см. Возвраты |
| 409 | CANNOT_CANCEL |
Заявку уже взяли в работу или закрыли | Отменить нельзя — деньги могли уйти. Дождись финального статуса |
| 400 | PARTIAL_DISABLED |
Прислана amount_rub, а частичные возвраты выключены |
Не присылай сумму — вернётся весь остаток |
| 400 | PARTIAL_BEFORE_SETTLEMENT |
Частичный возврат до ежедневного расчёта по способу оплаты, где начисление идёт по фактическому поступлению | Вернуть полностью или частично после расчёта |
| 400 | OVER_REMAINING |
Сумма больше остатка по платежу | Остаток смотри в remaining_rub через GET /refunds/:id |
| 400 | INVALID_AMOUNT |
Сумма нулевая или отрицательная | Исправь сумму |
| 409 | LIMIT_PER_PAYMENT |
Больше 10 заявок на один платёж | Разбирайся с уже созданными или пиши команде |
| 400 | SHOP_NOT_FOUND |
Магазина с таким shop_id нет в твоём аккаунте (ответ один и для чужого, и для несуществующего) |
Проверь shop_id в кабинете |
| 403 | SHOP_DISABLED |
Магазин выключен | Включи магазин в кабинете или передай другой |
| 422 | SHOP_MARKUP_NOT_SET |
Магазину ещё не назначена ставка | Напиши в X-Hub |
| 422 | PAYER_DATA_REQUIRED |
На POST /payments: выбранный способ оплаты требует данные плательщика (client_phone / client_email / description / payer), которых нет в запросе. В details.missing_fields — имена недостающих полей; payer в списке значит, что объекта payer в запросе нет вовсе. Платёж не создаётся. Если payer передан, но не прошёл проверку, ответ — VALIDATION_ERROR (400 — форма объекта, 422 — значения полей), а не этот код |
Повтори запрос с тем же Idempotency-Key, добавив недостающие поля: неудачная попытка ключ не расходует. Подробнее — данные плательщика и объект payer |
| 409 | IDEMPOTENCY_KEY_REUSED |
Тот же Idempotency-Key с другими параметрами. Другой shop_id в POST /subscriptions даёт этот ответ всегда. На возвратах (POST /refunds) действует всегда. На POST /payments, POST /exchanges и POST /subscriptions этот ответ пока не включён: повтор с другими параметрами возвращает исходную операцию. О включении объявим отдельно |
Это не ретрай, а ошибка — новая операция требует нового ключа. Используй новый Idempotency-Key для каждой новой операции |
Validation errors
При 400 VALIDATION_ERROR в details — массив проблем:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request body",
"details": [
{"path": "amount_rub", "message": "Must be a decimal string with up to 2 decimal places"},
{"path": "payment_method", "message": "Must be 'sbp' or 'card'"}
]
}
}
Retry-стратегия
| Код | Retry? | Как |
|---|---|---|
| 4xx | нет | Fix запрос, ретрай не поможет. Исключения — 429 ниже и 403 PROVIDER_DISABLED / 403 QR_PAYMENTS_DISABLED (их лечит не ретрай, а обращение в X-Hub) |
| 429 | да | Жди Retry-After / X-RateLimit-Reset |
| 500 | да | Exponential backoff: 1s, 2s, 4s, 8s, max 5 попыток. Исключение — KYC_PERSIST_FAILED: не повторяй с теми же данными, пиши в поддержку |
| 501 | нет | Возможность не подключена — ретрай ничего не изменит |
| 502 | зависит | PROVIDER_ERROR на привязке мандата и на KYC — ретрай (5s, 15s, 60s). PROVIDER_ERROR на списании — это отказ, а не сбой: ретрай даст то же самое |
| 503 | да | PROVIDER_UNAVAILABLE / PROVIDER_NOT_CONFIGURED / FEATURE_DISABLED / RATE_UNAVAILABLE / PAYMENT_ROUTE_UNAVAILABLE — backoff 30–60 сек, обязательно с тем же Idempotency-Key. Исключение — PROVIDER_NOT_CONFIGURED на списаниях по подпискам: повтор ответ не изменит, см. Подписки. KYC_UNAVAILABLE — backoff 1–2 мин, идемпотентность не нужна (/kyc/* без побочных эффектов) |
Tip
Всегда используй Idempotency-Key на ретраях POST — иначе можно создать дубль платежа.