Коротко: как читать коды ошибок платёжного API
Коды ошибок обычно делятся на три группы: ошибка в запросе от вашего сервера, отказ на стороне провайдера или банка и временный сбой инфраструктуры. Каждая группа требует разной реакции — от немедленного лога и остановки интеграции до автоматического повтора запроса через несколько секунд.
Почему нельзя показывать сырой код ошибки покупателю
Технический код вроде invalid_signature или provider_timeout ничего не говорит человеку на странице оплаты — он просто уйдёт, решив, что сервис не работает. Ошибку нужно переводить в понятный текст на вашей стороне: «повторите попытку через минуту» или «выберите другой способ оплаты» — а исходный код оставлять в логах для разбора.
Три группы ошибок и что с ними делать
- Ошибки запроса. Неверная подпись, отсутствующее обязательное поле, некорректная сумма. Это ваша ошибка интеграции — исправляется на стороне кода, а не повтором запроса.
- Отказ провайдера или банка. Недостаточно средств, превышен лимит, банк заблокировал операцию. Повторять тот же запрос бессмысленно — нужно показать причину покупателю и предложить другой способ оплаты.
- Временный сбой. Таймаут, недоступность провайдера, сетевая ошибка. Здесь уместен автоматический повтор с задержкой — но с ограничением по числу попыток, чтобы не заспамить провайдера одним и тем же запросом.
Как коды ошибок связаны с идемпотентностью
Повторный запрос после таймаута — частый источник дублей: сервер отправил платёж, ответ не дошёл, вы повторяете запрос, а на стороне провайдера уже создано две операции. Идемпотентный ключ на каждый запрос решает эту проблему — повтор с тем же ключом возвращает результат первой попытки, а не создаёт вторую.
Мониторинг кодов ошибок как метрика
Отдельная польза от структурированных кодов — возможность считать их долю от общего числа запросов и настраивать алерт на резкий рост конкретной категории. Всплеск ошибок подписи почти всегда означает баг в свежем деплое на вашей стороне, а всплеск таймаутов провайдера — проблему уже не у вас, а на стороне инфраструктуры. Без разбивки по кодам оба случая выглядят одинаково — просто «выросло число ошибок оплаты», и разбираться приходится вслепую.
Частые ошибки обработки
- Одна и та же реакция на все коды. Ошибка подписи и таймаут провайдера требуют разных действий — нельзя просто показывать общий текст «что-то пошло не так» на оба случая.
- Бесконечные повторы без ограничения. Автоматический ретрай без лимита попыток и задержки может создать нагрузку на провайдера и заблокировать вашу интеграцию за спам-паттерн.
- Нет логирования исходного кода ошибки. Если сохраняется только «оплата не прошла», через месяц невозможно понять, сколько ошибок было техническими, а сколько — отказами банка.
- Игнорирование кода в пользу общего HTTP-статуса. 400 или 500 сам по себе не объясняет причину — смысл несёт код ошибки в теле ответа.
Как это устроено в RollyPay
API возвращает структурированный код ошибки и человекочитаемое описание в одном ответе — можно логировать код для разбора и сразу показывать покупателю понятный текст, не переводя техническую формулировку вручную. Идемпотентный ключ поддерживается на создание платежа, поэтому повтор запроса после таймаута безопасен и не создаёт задвоенный платёж. Документация перечисляет коды по категориям, чтобы при интеграции можно было сразу заложить нужную реакцию на каждую группу, а не дорабатывать обработку ошибок постфактум.
Пример: интеграция без разбора кодов ошибок
Команда подключила API и обрабатывала любую неудачу одинаково: показывала покупателю текст «оплата не прошла, попробуйте позже» и логировала только факт ошибки без кода. Через месяц в поддержку начали поступать жалобы на платежи, которые «зависли» — на деле это были обычные таймауты провайдера, которые сервер даже не пытался повторить. Разбор логов занял два дня именно потому, что в них не было исходного кода ошибки — только общая пометка «ошибка оплаты».
После разделения ошибок на три группы и добавления повтора с идемпотентным ключом для временных сбоев доля обращений в поддержку по теме «платёж завис» заметно снизилась — большая часть таких случаев стала решаться автоматическим повтором ещё до того, как покупатель успевал написать в чат.
Что проверить в обработке ошибок
- Каждая группа ошибок — запрос, отказ, сбой — обрабатывается своей логикой, а не одним общим catch.
- Исходный код ошибки сохраняется в логах, а не только факт неудачи.
- Повтор запроса идёт с идемпотентным ключом и ограничением по числу попыток.
- Текст на странице оплаты понятен покупателю без знания внутренних кодов API.