[
  {
    "code": "authentication_failed",
    "http": [
      401
    ],
    "scope": "Все подписанные операции",
    "meaning": "Сервер не подтвердил подлинность запроса: заголовки, ключ, подпись, время или nonce не прошли проверку. Точная причина намеренно не раскрывается.",
    "action": "Проверить выданный ключ, часы, UUID v4 и подпись реально отправленных байтов. После потери ответа POST сначала выполнить lookup.",
    "retry": "Только после исправления; новые timestamp, nonce и signature. Не повторять старые заголовки.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2",
      "getPayinV2",
      "listBanksV2",
      "createPayoutV2",
      "lookupPayoutRequestV2",
      "getPayoutV2",
      "getShopBalanceV2"
    ],
    "operation_http": {
      "createPayinV2": [
        401
      ],
      "lookupPayinRequestV2": [
        401
      ],
      "getPayinV2": [
        401
      ],
      "listBanksV2": [
        401
      ],
      "createPayoutV2": [
        401
      ],
      "lookupPayoutRequestV2": [
        401
      ],
      "getPayoutV2": [
        401
      ],
      "getShopBalanceV2": [
        401
      ]
    }
  },
  {
    "code": "ip_not_allowed",
    "http": [
      403
    ],
    "scope": "Все подписанные операции",
    "meaning": "Исходящий IP вашего backend не входит в разрешённый список магазина.",
    "action": "Согласовать фактический адрес с учётом NAT/proxy. Не менять IP для обхода ограничений.",
    "retry": "После исправления allowlist; для неизвестного POST сначала lookup.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2",
      "getPayinV2",
      "listBanksV2",
      "createPayoutV2",
      "lookupPayoutRequestV2",
      "getPayoutV2",
      "getShopBalanceV2"
    ],
    "operation_http": {
      "createPayinV2": [
        403
      ],
      "lookupPayinRequestV2": [
        403
      ],
      "getPayinV2": [
        403
      ],
      "listBanksV2": [
        403
      ],
      "createPayoutV2": [
        403
      ],
      "lookupPayoutRequestV2": [
        403
      ],
      "getPayoutV2": [
        403
      ],
      "getShopBalanceV2": [
        403
      ]
    }
  },
  {
    "code": "shop_disabled",
    "http": [
      403,
      422,
      200
    ],
    "scope": "Создание приёма/выплаты; lookup приёма",
    "meaning": "Магазин или его группа недоступны для создания. HTTP 403 — отказ доступа; HTTP 422 — приём отклонён после резервирования номера; HTTP 200 — причина failed в lookup.",
    "action": "Уточнить активацию у менеджера. Сохранённые операции читать действующим ключом. При 422 номер уже занят.",
    "retry": "Не автоматически. После активации проверить прежний результат; занятый номер не переиспользовать.",
    "operations": [
      "createPayinV2",
      "createPayoutV2",
      "lookupPayinRequestV2"
    ],
    "operation_http": {
      "createPayinV2": [
        403,
        422
      ],
      "createPayoutV2": [
        403
      ],
      "lookupPayinRequestV2": [
        200
      ]
    }
  },
  {
    "code": "invalid_request",
    "http": [
      400
    ],
    "scope": "Приём и банки",
    "meaning": "Неверный JSON, поля, query или идентификатор: неизвестные/повторные параметры, недопустимый IP/URL либо параметры справочника.",
    "action": "Сравнить запрос со схемой конкретной операции. У GET по ID и POST приёма query не допускается; lookup требует один merchant_order_id.",
    "retry": "После исправления запроса. Если ранее был неизвестный результат POST — сначала lookup.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2",
      "getPayinV2",
      "listBanksV2"
    ],
    "operation_http": {
      "createPayinV2": [
        400
      ],
      "lookupPayinRequestV2": [
        400
      ],
      "getPayinV2": [
        400
      ],
      "listBanksV2": [
        400
      ]
    }
  },
  {
    "code": "invalid_amount",
    "http": [
      400
    ],
    "scope": "Создание приёма",
    "meaning": "Сумма не соответствует разрешённому формату или границам.",
    "action": "Передать положительную точную decimal-строку согласно схеме; не JSON-число. Не округлять деньги через float.",
    "retry": "После исправления; неизвестный предыдущий POST сначала проверить lookup.",
    "operations": [
      "createPayinV2"
    ],
    "operation_http": {
      "createPayinV2": [
        400
      ]
    }
  },
  {
    "code": "invalid_payout_request",
    "http": [
      400
    ],
    "scope": "Выплаты и баланс",
    "meaning": "Некорректные поля, сумма, реквизиты, bank_id, UUID или query. При выплате bank_id должен указывать на активный канонический банк.",
    "action": "Проверить схему выплаты и тип реквизитов, получить bank_id из справочника. У баланса query запрещён. Ошибка может возникнуть и после занятия номера выплаты.",
    "retry": "После исправления сначала lookup по прежнему номеру; если номер занят, не переиспользовать.",
    "operations": [
      "createPayoutV2",
      "lookupPayoutRequestV2",
      "getPayoutV2",
      "getShopBalanceV2"
    ],
    "operation_http": {
      "createPayoutV2": [
        400
      ],
      "lookupPayoutRequestV2": [
        400
      ],
      "getPayoutV2": [
        400
      ],
      "getShopBalanceV2": [
        400
      ]
    }
  },
  {
    "code": "method_not_allowed",
    "http": [
      405
    ],
    "scope": "Маршрутизация /api/v2",
    "meaning": "HTTP-метод не поддерживается по указанному пути.",
    "action": "Использовать метод и путь из OpenAPI; заново подписать исправленный запрос.",
    "retry": "После исправления. Если это повтор после timeout, сначала выяснить исход первой операции.",
    "operations": [],
    "operation_http": {}
  },
  {
    "code": "payin_not_found",
    "http": [
      404
    ],
    "scope": "Получение/lookup приёма; неизвестный маршрут /api/v2",
    "meaning": "Приём или запрос с таким номером не найден в данном магазине; этот код также используется для неизвестного пути v2.",
    "action": "Проверить путь, магазин и идентификатор. Пока Payin не сформирован, искать по merchant_order_id. После потерянного ответа повторить чтение и при неопределённости обратиться в поддержку.",
    "retry": "Повтор чтения допустим с новой подписью. Один 404 не разрешает повтор POST или создание нового номера.",
    "operations": [
      "lookupPayinRequestV2",
      "getPayinV2"
    ],
    "operation_http": {
      "lookupPayinRequestV2": [
        404
      ],
      "getPayinV2": [
        404
      ]
    }
  },
  {
    "code": "payout_not_found",
    "http": [
      404
    ],
    "scope": "Получение/lookup выплаты; чтение баланса",
    "meaning": "Объект не найден или не принадлежит магазину ключа. При балансе не найдена строка учёта магазина; это не нулевой баланс.",
    "action": "Проверить магазин, UUID/merchant_order_id; при балансе обратиться в поддержку. После потерянного POST выяснить исход по прежнему номеру.",
    "retry": "Повтор GET допустим. Один 404 после timeout не доказывает, что можно создать перевод снова.",
    "operations": [
      "createPayoutV2",
      "lookupPayoutRequestV2",
      "getPayoutV2",
      "getShopBalanceV2"
    ],
    "operation_http": {
      "createPayoutV2": [
        404
      ],
      "lookupPayoutRequestV2": [
        404
      ],
      "getPayoutV2": [
        404
      ],
      "getShopBalanceV2": [
        404
      ]
    }
  },
  {
    "code": "duplicate_merchant_order_id",
    "http": [
      409
    ],
    "scope": "Создание приёма и выплаты",
    "meaning": "Номер бизнес-запроса уже занят в данном магазине, в том числе после отказа. Повтор POST не возвращает старый успешный ответ.",
    "action": "Читать /payins/result или /payouts/result по исходному номеру. Не заменять номер автоматически.",
    "retry": "Повторять lookup, не POST. Новый перевод — только отдельное бизнес-решение после выяснения исхода.",
    "operations": [
      "createPayinV2",
      "createPayoutV2"
    ],
    "operation_http": {
      "createPayinV2": [
        409
      ],
      "createPayoutV2": [
        409
      ]
    }
  },
  {
    "code": "payout_action_unavailable",
    "http": [
      409
    ],
    "scope": "Создание выплаты: конфликт согласованности",
    "meaning": "При записи обнаружен конфликт идентичности/состояния выплаты. Общая классификация ошибок БД может вернуть этот код публичному созданию.",
    "action": "Проверить lookup по исходному номеру и передать request_id в поддержку. Это не маршрут изменения выплаты мерчантом.",
    "retry": "Не повторять POST автоматически; сначала сверка.",
    "operations": [
      "createPayoutV2"
    ],
    "operation_http": {
      "createPayoutV2": [
        409
      ]
    }
  },
  {
    "code": "payout_configuration_disabled",
    "http": [
      403,
      200
    ],
    "scope": "Создание и lookup выплаты",
    "meaning": "Нет активных отдельных условий выплаты для метода/валюты либо магазин/группа отключены. В lookup HTTP 200 это причина rejected.",
    "action": "Согласовать и активировать условия выплат. Условия приёма не заменяют условия выплат. Номер может быть уже занят.",
    "retry": "После исправления проверить lookup; отвергнутый занятый номер остаётся занят.",
    "operations": [
      "createPayoutV2",
      "lookupPayoutRequestV2"
    ],
    "operation_http": {
      "createPayoutV2": [
        403
      ],
      "lookupPayoutRequestV2": [
        200
      ]
    }
  },
  {
    "code": "insufficient_funds",
    "http": [
      422,
      200
    ],
    "scope": "Создание и lookup выплаты",
    "meaning": "Доступного USDT недостаточно для резерва основной стоимости и комиссии. В lookup HTTP 200 это причина rejected.",
    "action": "Прочитать баланс, учесть reserved и полную стоимость по условиям выплат. Согласовать пополнение доступного остатка; прежний номер уже занят.",
    "retry": "Не повторять прежний POST после пополнения. Новый запрос только как новое подтверждённое бизнес-действие.",
    "operations": [
      "createPayoutV2",
      "lookupPayoutRequestV2"
    ],
    "operation_http": {
      "createPayoutV2": [
        422
      ],
      "lookupPayoutRequestV2": [
        200
      ]
    }
  },
  {
    "code": "webhook_required",
    "http": [
      422,
      200
    ],
    "scope": "Создание и lookup приёма",
    "meaning": "До формирования не найден webhook_url ни в запросе, ни в настройках магазина. Номер уже зарезервирован.",
    "action": "Настроить публичный HTTPS endpoint для будущих запросов. Проверить failed через lookup. Добавление URL не возобновит этот запрос.",
    "retry": "Этот POST не повторять; новый номер только для осознанно нового запроса после проверки исхода.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2"
    ],
    "operation_http": {
      "createPayinV2": [
        422
      ],
      "lookupPayinRequestV2": [
        200
      ]
    }
  },
  {
    "code": "traffic_type_not_allowed",
    "http": [
      422,
      200
    ],
    "scope": "Создание и lookup приёма",
    "meaning": "Тип трафика не разрешён условиями магазина. Номер сохранён.",
    "action": "Согласовать тип трафика и настройки; не подменять классификацию ради обхода ограничения.",
    "retry": "Не повторять сохранённый запрос. После согласования возможен отдельный новый бизнес-запрос.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2"
    ],
    "operation_http": {
      "createPayinV2": [
        422
      ],
      "lookupPayinRequestV2": [
        200
      ]
    }
  },
  {
    "code": "payer_restricted",
    "http": [
      422,
      200
    ],
    "scope": "Создание и lookup приёма",
    "meaning": "Для плательщика действует ограничение. Номер запроса сохранён.",
    "action": "Уточнить причину и порядок разблокировки у менеджера; не менять ID плательщика для обхода.",
    "retry": "Автоматический повтор запрещён; сначала решение по ограничению и сверка результата.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2"
    ],
    "operation_http": {
      "createPayinV2": [
        422
      ],
      "lookupPayinRequestV2": [
        200
      ]
    }
  },
  {
    "code": "unsupported_payment_configuration",
    "http": [
      422,
      200
    ],
    "scope": "Создание и lookup приёма",
    "meaning": "Сочетание метода, валюты и режима не поддерживается действующими условиями магазина.",
    "action": "Сверить матрицу и согласованные настройки; наличие значения в enum не гарантирует доступность.",
    "retry": "После согласования — отдельный новый запрос; прежний зарезервированный номер не повторять.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2"
    ],
    "operation_http": {
      "createPayinV2": [
        422
      ],
      "lookupPayinRequestV2": [
        200
      ]
    }
  },
  {
    "code": "no_requisite",
    "http": [
      422,
      200
    ],
    "scope": "Создание и lookup приёма",
    "meaning": "Каскад не выдал реквизиты. Сохранённый запрос не стал сформированным Payin и не означает оплату.",
    "action": "Проверить failed через lookup, показать пользователю отсутствие реквизитов и возможность обратиться в поддержку.",
    "retry": "Не повторять POST автоматически; новая попытка только как отдельное согласованное бизнес-действие.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2"
    ],
    "operation_http": {
      "createPayinV2": [
        422
      ],
      "lookupPayinRequestV2": [
        200
      ]
    }
  },
  {
    "code": "payment_processing_failed",
    "http": [
      422,
      200
    ],
    "scope": "Создание и lookup приёма",
    "meaning": "Формирование не завершилось; внутренняя причина скрыта за общим публичным кодом.",
    "action": "Получить lookup по исходному номеру, сохранить request_id и обратиться в поддержку. Не угадывать причину по тексту message.",
    "retry": "Повтор чтения допустим; POST с занятым номером не повторять.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2"
    ],
    "operation_http": {
      "createPayinV2": [
        422
      ],
      "lookupPayinRequestV2": [
        200
      ]
    }
  },
  {
    "code": "payment_requires_reconciliation",
    "http": [
      503
    ],
    "scope": "Создание приёма",
    "meaning": "Исход формирования требует сверки; отсутствие Payin в ответе не является доказательством отсутствия операции.",
    "action": "Прочитать lookup; при review_required дождаться сверки поддержки по исходному номеру.",
    "retry": "Не повторять POST и не создавать автоматически новый номер; разрешён polling.",
    "operations": [
      "createPayinV2"
    ],
    "operation_http": {
      "createPayinV2": [
        503
      ]
    }
  },
  {
    "code": "payment_processing_timeout",
    "http": [
      504
    ],
    "scope": "Создание приёма",
    "meaning": "Истекло ожидание HTTP-ответа; долговечная обработка может продолжаться.",
    "action": "Выполнить lookup по исходному merchant_order_id с новой подписью. Для processing продолжать чтение с задержкой.",
    "retry": "Только чтение до известного результата; автоматический retry POST выключить.",
    "operations": [
      "createPayinV2"
    ],
    "operation_http": {
      "createPayinV2": [
        504
      ]
    }
  },
  {
    "code": "internal_error",
    "http": [
      503
    ],
    "scope": "Все подписанные операции",
    "meaning": "Результат временно недоступен: хранилище, аудит, ключи или обработчик не позволили завершить ответ. Это не финальный денежный статус.",
    "action": "Для POST сначала lookup по сохранённому номеру. Для GET повторить чтение с задержкой; при сохранении ошибки передать request_id поддержке.",
    "retry": "GET — с ограниченным backoff и новой подписью. POST — без автоматического повтора при неизвестном исходе.",
    "operations": [
      "createPayinV2",
      "lookupPayinRequestV2",
      "getPayinV2",
      "listBanksV2",
      "createPayoutV2",
      "lookupPayoutRequestV2",
      "getPayoutV2",
      "getShopBalanceV2"
    ],
    "operation_http": {
      "createPayinV2": [
        503
      ],
      "lookupPayinRequestV2": [
        503
      ],
      "getPayinV2": [
        503
      ],
      "listBanksV2": [
        503
      ],
      "createPayoutV2": [
        503
      ],
      "lookupPayoutRequestV2": [
        503
      ],
      "getPayoutV2": [
        503
      ],
      "getShopBalanceV2": [
        503
      ]
    }
  },
  {
    "code": "creation_requires_review",
    "http": [
      200
    ],
    "scope": "Только error_code в lookup выплаты",
    "meaning": "Создание выплаты завершилось отклонённым запросом, требующим проверки причины; публичный обработчик не раскрывает внутреннюю ошибку.",
    "action": "Проверить status и payout в lookup, передать номер и request_id поддержке. Номер зарезервирован, даже когда payout равен null.",
    "retry": "Повторять только чтение. Не превращать rejected в автоматическое повторное создание.",
    "operations": [
      "lookupPayoutRequestV2"
    ],
    "operation_http": {
      "lookupPayoutRequestV2": [
        200
      ]
    }
  }
]
