Reference

Ошибки

Все наши HTTP-коды и значения error.code в одном месте, плюс справочник failure_code для отказа банка.

Все ошибки — JSON одного формата, с подходящим HTTP-статусом:

{
  "error": {
    "code":    "method_not_supported_by_bank",
    "message": "банк не поддерживает выбранный метод"
  }
}

Что вы можете встретить:

HTTPcodeкогда
400bad_requestневалидное тело или обязательное поле не заполнено
401unauthorized / invalid_tokenнет ключа, ключ просрочен или неверный
401signature_requiredна магазине включена обязательная подпись, заголовок X-Freefin-Signature не пришёл
401invalid_signatureподпись X-Freefin-Signature не сходится с тем, что мы посчитали по телу
403live_not_enabledsk_live, но мерчант ещё не прошёл активацию
403ip_not_allowedIP вне allow-list магазина
403aml_blockedплатёж отклонил наш AML-скоринг
403forbidden_purposedescription или order_id содержит запрещённый контент; аккаунт уходит на проверку
404not_foundобъект не найден или принадлежит другому мерчанту
409not_pendingплатёж уже не в pending (для cancel)
409not_refundableвозврат возможен только на платёж в succeeded
409fully_refundedплатёж уже возвращён полностью
422amount_too_largeсумма возврата больше доступного остатка
422route_not_configuredдля пары (shop, method) не настроен ни один коннектор
422method_not_supported_by_bankбанк-эквайер не умеет выбранный метод
429rate_limitedпревышен лимит мерчанта на public-API; см. Retry-After
500db_error / internalвнутренняя ошибка
502router_errorошибка вызова банка

Коды отказов

В ответе POST /payments и в webhook'е payment.failed приходит поле failure_code. Это наш унифицированный код, не сырой ответ банка. С банком взаимодействуем только мы. Сырой банковский код храним внутри для аудита, наружу не отдаём.

failure_codeкогда
insufficient_fundsна счёте плательщика недостаточно средств
card_declinedкарта отклонена банком (общий кейс без уточнения)
card_expiredсрок действия карты истёк
do_not_honorбанк не подтвердил операцию (CVV-фейл, 3DS-фейл и т.п.)
fraud_blockedзаблокировано anti-fraud (нашим или банка)
limit_exceededпревышен лимит карты, мерчанта или нашего sandbox
aml_blockedотклонено нашим AML-скорингом
customer_cancelledпокупатель сам отменил оплату на банковской странице
timeoutбанк не вернул финальный статус за TTL банковской сессии
bank_unavailableбанк недоступен или ответил 5xx; повторите позже
bank_unknownбанк прислал нестандартный код; смотрите failure_message

Поле failure_message — человеко-читаемое описание для UI. Подходит для прямого показа покупателю на странице ошибки.