Finance OS / API

Errors

Единый обезличенный конверт ошибок (unified error envelope) для B2B API. Один и тот же формат возвращается на любую неуспешную операцию — валидация, аутентификация, недостаток средств, конфликт состояния или недоступность сервиса. Разбирайте ошибки по стабильному строковому полю code, а не по тексту message (текст локализован и может меняться).

Applies to ALL /api/v1/* endpoints
Этот конверт единообразно применяется ко всем merchant-endpoints под /api/v1/* и заменяет (supersedes) любой legacy-формат ошибок (например поля error_code / docs из ранних версий). Если ваш код всё ещё читает старые поля — переключитесь на error.code + error.request_id.

Формат конверта (envelope)

Успех — всегда объект с ключом data. Ошибка — всегда объект с ключом error, внутри которого code, message и request_id. Поле fields добавляется только для invalid_request (детали по каждому невалидному полю).

Responses

{
  "data": {
    "...": "полезная нагрузка операции"
  }
}
{
  "error": {
    "code": "string",
    "message": "string",
    "request_id": "req_...",
    "fields": {
      "field_name": ["сообщение валидации", "..."]
    }
  }
}
Поля конверта ошибки
  • code — стабильный машиночитаемый идентификатор ошибки (см. таблицу ниже). Ветвите логику по нему.
  • message — человекочитаемое, уже обезличенное сообщение. Никогда не раскрывает внутреннюю инфраструктуру. Для отображения пользователю пригодно как есть.
  • request_id — уникальный идентификатор запроса формата req_<random> для обращения в поддержку.
  • fields — присутствует только при invalid_request; объект вида { "имя_поля": ["ошибка", ...] }.

request_id (для поддержки)

Каждый ответ об ошибке содержит уникальный request_id формата req_<random> — префикс req_ плюс 24 случайных символа (например req_a1B2c3D4e5F6g7H8i9J0kLmN). Логируйте его на своей стороне и указывайте при обращении в поддержку: по этому идентификатору во внутреннем канале Finance OS хранится полная техническая детализация инцидента, которая никогда не отдаётся наружу. В merchant-ответ и merchant-лог попадает только обезличенная версия.

Коды ошибок

Полный реестр кодов. Каждый код жёстко привязан к одному HTTP-статусу. В таблице приведён точный текст сообщения по умолчанию (в кавычках) и семантика кода.

Error codes

Name Type Required Description
invalid_request 422 optional «Некорректные данные запроса.» — не прошла валидация тела/параметров (или провайдерская проверка данных). Ответ содержит объект fields с ошибками по каждому полю.
unauthorized 401 optional «Требуется аутентификация. Проверьте ключ API.» — ключ отсутствует, недействителен или отозван. Проверьте заголовок Authorization: Bearer sk_live_… / sk_test_….
forbidden 403 optional «Доступ запрещён.» — ключ аутентифицирован, но у него нет прав на этот ресурс или действие.
not_found 404 optional «Ресурс не найден.» — объект отсутствует. Также возвращается при попытке доступа к ресурсу из другого окружения (sk_test_ к live-ресурсу и наоборот) — намеренно 404, а не 403.
verification_required 403 optional «Требуется завершить верификацию клиента.» — операция недоступна, пока managed-клиент не прошёл верификацию. Сначала завершите верификацию.
insufficient_funds 402 optional «Недостаточно средств для операции.» — на балансе не хватает средств для списания/блокировки под sell или withdraw.
conflict 409 optional «Конфликт состояния операции.» — состояние ресурса несовместимо с запросом (например операция уже в терминальном статусе или конфликт идемпотентности).
rate_limited 429 optional «Слишком много запросов. Повторите позже.» — превышен лимит частоты. Сделайте паузу и повторите с экспоненциальной задержкой (backoff).
service_unavailable 503 optional «Сервис временно недоступен. Попробуйте позже.» — вышестоящий сервис временно недоступен или запрос можно повторить. Retry через некоторое время.
internal_error 500 optional «Внутренняя ошибка. Обратитесь в поддержку с указанным request_id.» — непредвиденная ошибка на стороне Finance OS. Сохраните request_id и обратитесь в поддержку.
Ветвление по code, не по message
message предназначен для показа человеку и может меняться. Программную логику (retry, показ формы, пополнение баланса) стройте по error.code и HTTP-статусу.

Примеры тел ошибок

Реальные тела ответов для типичных ситуаций.

Responses

{
  "error": {
    "code": "unauthorized",
    "message": "Требуется аутентификация. Проверьте ключ API.",
    "request_id": "req_M9n8B7v6C5x4Z3a2S1d0F1gH"
  }
}
{
  "error": {
    "code": "insufficient_funds",
    "message": "Недостаточно средств для операции.",
    "request_id": "req_7Kp2Rt9Wx4Yz1Qb6Nm3Vc8L"
  }
}
{
  "error": {
    "code": "invalid_request",
    "message": "Некорректные данные запроса.",
    "request_id": "req_a1B2c3D4e5F6g7H8i9J0kLmN",
    "fields": {
      "amount_rub": ["The amount rub field must be at least 100."],
      "bank_id": ["The bank id field is required."]
    }
  }
}
{
  "error": {
    "code": "rate_limited",
    "message": "Слишком много запросов. Повторите позже.",
    "request_id": "req_Qw3Er5Ty7Ui9Op1As2Df4Gh6"
  }
}
{
  "error": {
    "code": "service_unavailable",
    "message": "Сервис временно недоступен. Попробуйте позже.",
    "request_id": "req_Zx8Cv6Bn4Mk2Lj0Hg9Fd7Sa5"
  }
}
Sandbox vs live
Окружение определяется префиксом ключа: sk_test_… — sandbox, sk_live_… — live. Отдельного заголовка окружения нет. Обрабатывайте ошибки одинаково в обоих окружениях. См. Sandbox.