API для мерчантов
⌘K Поиск по документации v1
● API v1 · Документация для интеграции

Подключите приём платежей
и выплат к своей системе

REST API LEON для приёма пополнений (Вход), работы с диспутами и получения событий по вебхукам — в реальном времени, тем же курсом и тем же пулом трейдеров, что видит трейдер в своей торговой панели.

Введение

API работает поверх HTTPS и обменивается данными в формате JSON (кроме создания диспута, где чек загружается как multipart/form-data). Базовый адрес для всех запросов из этого раздела документации:

Base URL
{BASE_URL}/api/merchant

{BASE_URL} — домен, на котором развёрнут ваш личный кабинет LEON. Все пути ниже указаны относительно этого адреса.

Заявка «Вход» за три шага

  1. Мерчант создаёт заявку — POST /payin/create — и получает реквизит, на который клиент должен перевести средства.
  2. Клиент переводит деньги; трейдер подтверждает получение в своей панели (или заявка отменяется по истечении времени жизни).
  3. LEON отправляет вебхук payment.success или payment.cancelled на ваш URL — на этом заявка завершена.
POSTquick start
curl -X POST {BASE_URL}/api/merchant/payin/create \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount_rub": 5000,
    "rate": 95.40,
    "payment_methods": ["sbp"],
    "external_id": "order-10231"
  }'
quick start
const res = await fetch("{BASE_URL}/api/merchant/payin/create", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_live_...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    amount_rub: 5000,
    rate: 95.40,
    payment_methods: ["sbp"],
    external_id: "order-10231",
  }),
});

const payin = await res.json();
quick start
import requests

response = requests.post(
    "{BASE_URL}/api/merchant/payin/create",
    headers={"Authorization": "Bearer sk_live_..."},
    json={
        "amount_rub": 5000,
        "rate": 95.40,
        "payment_methods": ["sbp"],
        "external_id": "order-10231",
    },
)

payin = response.json()
💡

Курс. Перед созданием заявки запросите актуальный курс через GET /rate — он парсится из спотового стакана Rapira и обновляется каждые 30 секунд, тем же способом, что и в торговой панели трейдера.

01Аутентификация

Каждый запрос подписывается API-ключом в заголовке Authorization. Ключи выпускаются в личном кабинете мерчанта, в разделе «API-ключи» — сгенерируйте отдельный ключ для каждой интеграции, а не переиспользуйте один и тот же ключ везде.

header
Authorization: Bearer sk_live_7f2c9a1e4b8d6f0a3c5e7b9d1f3a5c7e

Окружения

Ключ несёт префикс окружения — используйте тестовый ключ на стейджинге, чтобы не создавать реальные заявки.

sk_live_…боевые операции sk_test_…песочница, без движения реальных средств

Права доступа

При создании ключа вы выбираете, какие права ему выдать. Запрос к эндпоинту без нужного права вернёт 403.

ПравоДаёт доступ к
readЧтение заявок, диспутов, баланса, курса и логов вебхуков
write_paymentsСоздание и отмена заявок на Вход, открытие и отмена диспутов
write_payoutsВывод средств с баланса
webhooksУправление URL, событиями, секретом и тестовой отправкой вебхуков

IP-белый список

При создании ключа можно ограничить его список IP-адресов, с которых он принимается — запрос с адреса вне списка получит 403. Оставьте список пустым, чтобы разрешить любой адрес.

⚠️

Храните ключ как пароль. Полное значение ключа показывается один раз, в момент создания или перегенерации — LEON хранит только его хеш и не может показать значение повторно. Если ключ скомпрометирован, немедленно отзовите его в кабинете и выпустите новый.

02Ошибки

Все ответы API — включая ошибки — приходят в формате JSON одной и той же формы:

error shape
{
  "status": "error",
  "message": "Недостаточно USDT на балансе"
}
200 OK

Запрос выполнен успешно.

400 Bad Request

Не прошла валидация тела запроса — текст в message объясняет, что именно не так.

401 Unauthorized

Ключ не передан, недействителен или отозван.

403 Forbidden

У ключа нет нужного права, либо запрос пришёл не из IP-белого списка.

404 Not Found

Объект с таким ID не найден либо принадлежит другому мерчанту.

415 Unsupported Media Type

Тело запроса должно быть application/json (кроме создания диспута — там multipart/form-data).

500 Internal Server Error

Внутренняя ошибка сервиса. Повторите запрос позже; если повторяется — напишите в поддержку.

03Формат данных

Единые соглашения, которые действуют во всех эндпоинтах и вебхуках ниже.

ЧтоФормат
Дата и времяYYYY-MM-DD HH:MM:SS, всегда UTC. Без суффикса Z — прибавляйте смещение на своей стороне, если нужен другой часовой пояс.
Сумма в рубляхЧисло с плавающей точкой, напр. 5000 или 4999.5.
Сумма в USDTЧисло, округлённое до 2 знаков после запятой, напр. 52.41.
Списки (GET .../list)Всегда форма { "data": [...], "total", "page", "per_page" }. page — с 1; per_page — от 1 до 100, по умолчанию 20.
ИдентификаторыЦелые числа, возрастающие, без переиспользования.
external_idПроизвольная строка на вашей стороне. Возвращается как есть в ответах и вебхуках, и служит ключом идемпотентности при создании заявки — см. раздел ниже.

Идемпотентность

POST /payin/create идемпотентен по external_id. Если ваш запрос не долетел до вас (таймаут, обрыв сети, краш до чтения ответа) — просто повторите его с тем же external_id: вместо второй заявки вы получите тот же самый объект, который был создан первым запросом, с его актуальным текущим статусом.

  • Идемпотентность работает только если вы передали external_id — без него каждый запрос создаёт новую заявку.
  • Повтор с той же суммой — возвращается существующая заявка, 200, баланс/лимит трейдера не трогается повторно.
  • Повтор с другой суммой под тем же external_id — расценивается как ошибка использования ключа, а не как новая заявка: 400.
💡

Используйте собственный ID заказа как external_id и ретраите запрос при любом сетевом сбое или таймауте на вашей стороне — так вы никогда не создадите вторую заявку и не заморозите баланс трейдера дважды за один и тот же заказ.

04Курс USDT/RUB

Возвращает средний курс между лучшим bid и ask в спотовом стакане Rapira (пара USDT/RUB). Значение кешируется на 30 секунд — ровно так же курс обновляется в шапке торговой панели трейдера.

GET/rateread

Текущий курс

Используйте перед созданием заявки, чтобы предложить клиенту актуальную сумму в USDT.

GET/rate
curl {BASE_URL}/api/merchant/rate \
  -H "Authorization: Bearer sk_live_..."
200
{ "rate": 95.42 }

05Вход (PayIn)

Заявка на приём средств от клиента. При создании система подбирает активного трейдера, у которого есть реквизит под нужный способ перевода, банк и лимиты — заявка возвращает реквизит, на который клиент должен отправить деньги.

Статусы заявки

pending

Ожидает подтверждения трейдером.

success

Трейдер подтвердил получение — средства зачислены на баланс мерчанта.

cancelled

Отменена мерчантом либо истекло время жизни без подтверждения.

dispute

По отменённой заявке открыт диспут.

Время жизни заявки — 15 минут. Если трейдер не подтвердит получение до истечения expires_at, заявка автоматически отменяется и приходит вебхук payment.cancelled.

POST/payin/createwrite_payments

Создать заявку

Тело запроса — JSON.

ПараметрТипОписание
amount_rub обязательноnumberСумма пополнения в рублях.
rate обязательноnumberКурс USDT/RUB, по которому зафиксировать сумму в USDT (см. GET /rate).
payment_methods опциональноstring[]Допустимые способы перевода: c2c, sbp, mobile_commerce. Пустой список или отсутствие поля — подходит трейдер с любым способом.
bank опциональноstringПредпочитаемый банк: any, sberbank, tinkoff, vtb, alfabank, raiffeisen. По умолчанию any.
external_id опциональноstringВаш собственный ID заказа — вернётся как есть во всех вебхуках по этой заявке.
Возможные ошибки
400«Некорректная сумма» / «Некорректный курс» / «Некорректный способ перевода» — не прошла валидация тела запроса.
400«Подходящий трейдер не найден. Попробуйте изменить способ перевода или банк.» — нет активного трейдера с нужным способом, банком и свободным лимитом. Заявка не создаётся.
400«external_id уже использован для заявки с другой суммой» — повтор ключа идемпотентности с другими параметрами.
POST/payin/create
curl -X POST {BASE_URL}/api/merchant/payin/create \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount_rub": 5000,
    "rate": 95.40,
    "payment_methods": ["sbp"],
    "bank": "any",
    "external_id": "order-10231"
  }'
200
{
  "id": 764,
  "status": "pending",
  "trader_name": "Trader #1",
  "client_bank": "СБП · +7 916 987-65-43",
  "rate": 95.4,
  "amount_usdt": 52.41,
  "expires_at": "2026-08-03 14:54:31"
}
GET/payin/listread

Список заявок

ПараметрТипОписание
statusesstringСписок статусов через запятую, напр. pending,success.
date_from / date_tostringДиапазон дат создания, YYYY-MM-DD.
amount_from / amount_tonumberДиапазон суммы в рублях.
pageintНомер страницы, по умолчанию 1.
per_pageintРазмер страницы, 1–100, по умолчанию 20.
GET/payin/list
curl "{BASE_URL}/api/merchant/payin/list?statuses=pending,success&per_page=20" \
  -H "Authorization: Bearer sk_live_..."
200
{
  "data": [
    {
      "id": 764,
      "date": "2026-08-03 14:39:31",
      "amount_rub": 5000,
      "rate": 95.4,
      "amount_usdt": 52.41,
      "status": "success",
      "client_bank": "СБП · +7 916 987-65-43",
      "external_id": "order-10231",
      "expires_at": "2026-08-03 14:54:31",
      "payment_methods": ["sbp"],
      "bank": "any"
    }
  ],
  "total": 1,
  "page": 1,
  "per_page": 20
}
GET/payin/{id}read

Заявка по ID

Полная карточка заявки, включая историю смены статусов.

GET/payin/764
curl {BASE_URL}/api/merchant/payin/764 \
  -H "Authorization: Bearer sk_live_..."
200
{
  "id": 764,
  "amount_rub": 5000,
  "rate": 95.4,
  "amount_usdt": 52.41,
  "status": "success",
  "client_bank": "СБП · +7 916 987-65-43",
  "external_id": "order-10231",
  "trader_id": 1,
  "trader_name": "Trader #1",
  "created_at": "2026-08-03 14:39:31",
  "updated_at": "2026-08-03 14:41:02",
  "expires_at": "2026-08-03 14:54:31",
  "payment_methods": ["sbp"],
  "bank": "any",
  "history": [
    { "time": "2026-08-03 14:39:31", "status": "pending" },
    { "time": "2026-08-03 14:41:02", "status": "success" }
  ]
}
POST/payin/{id}/cancelwrite_payments

Отменить заявку

Доступно только для заявок в статусе pending. Тела запроса не требует.

Возможные ошибки
404«Заявка не найдена» — нет заявки с таким ID у вашего аккаунта.
400«Отмена недоступна для текущего статуса заявки» — заявка уже success, cancelled или по ней открыт диспут.
POST/payin/764/cancel
curl -X POST {BASE_URL}/api/merchant/payin/764/cancel \
  -H "Authorization: Bearer sk_live_..."
200
{ "status": "cancelled" }

06Диспуты

Если заявка на Вход была отменена, а клиент утверждает, что перевод всё же ушёл — откройте диспут и приложите чек. Открыть диспут можно только по заявке в статусе cancelled, и только один активный диспут на заявку одновременно.

Статусы диспута

open / pending_trader

Ожидает решения трейдера.

resolved_merchant

Решён в пользу мерчанта — заявка переходит в success, средства зачислены.

resolved_psp

Решён в пользу трейдера — заявка остаётся cancelled.

cancelled_merchant

Диспут отозван мерчантом.

POST/disputes/createwrite_payments

Открыть диспут

Тело запроса — multipart/form-data (нужен для прикладываемого чека).

ПолеТипОписание
transaction_id обязательноintID отменённой заявки на Вход.
reason обязательноstringПричина диспута — покажется трейдеру.
duration_minutes опциональноintСрок на решение, 15–360 минут. По умолчанию 30.
file опциональноfileЧек об оплате — PDF, JPG или PNG, до 5 МБ.
Возможные ошибки
400«Не указана сделка» / «Укажите причину диспута» — не заполнены обязательные поля.
400«Диспут можно открыть только по сделке в статусе «Отменён»» — заявка ещё не отменена.
400«По этой сделке уже открыт диспут» — активный диспут по заявке уже существует.
400«Недостаточно средств на рабочем и страховом балансе трейдера» — сумму диспута не удалось заморозить у трейдера.
400«Недопустимый формат файла» / «Файл превышает 5 МБ» — проблема с приложенным чеком.
POST/disputes/create
curl -X POST {BASE_URL}/api/merchant/disputes/create \
  -H "Authorization: Bearer sk_live_..." \
  -F "transaction_id=764" \
  -F "reason=Клиент прислал чек об успешном переводе" \
  -F "file=@receipt.pdf"
200
{
  "id": 42,
  "status": "pending_trader",
  "expires_at": "2026-08-03 15:24:31"
}
GET/disputes/listread

Список диспутов

Фильтры: statuses, date_from, date_to, search, page, per_page.

200
{
  "data": [
    {
      "id": 42,
      "transaction_id": 764,
      "amount_rub": 5000,
      "amount_usdt": 52.41,
      "status": "resolved_merchant",
      "reason": "Клиент прислал чек…",
      "created_at": "2026-08-03 14:54:31",
      "expires_at": "2026-08-03 15:24:31",
      "is_overdue": false
    }
  ],
  "total": 1, "page": 1, "per_page": 20
}
GET/disputes/{id}read

Диспут по ID

То же самое плюс has_receipt — есть ли приложенный чек.

200
{
  "id": 42,
  "transaction_id": 764,
  "amount_rub": 5000,
  "amount_usdt": 52.41,
  "status": "resolved_merchant",
  "reason": "Клиент прислал чек…",
  "has_receipt": true,
  "created_at": "2026-08-03 14:54:31",
  "expires_at": "2026-08-03 15:24:31",
  "is_overdue": false
}
GET/disputes/for-transaction/{transaction_id}read

Есть ли диспут по заявке

Проверьте перед открытием диспута, чтобы не наткнуться на ошибку «уже открыт» — вернёт dispute_id: null, если активного диспута нет.

GET/disputes/for-transaction/764
curl {BASE_URL}/api/merchant/disputes/for-transaction/764 \
  -H "Authorization: Bearer sk_live_..."
200
{ "dispute_id": 42, "status": "pending_trader" }
POST/disputes/{id}/cancelwrite_payments

Отменить диспут

Доступно, пока диспут активен (open или pending_trader). Заявка остаётся cancelled.

Возможные ошибки
404«Диспут не найден».
400«Отмена доступна только для открытого диспута» — диспут уже решён.
200
{ "status": "cancelled_merchant" }
GET/disputes/{id}/receiptread

Скачать приложенный чек

Возвращает бинарный файл, который вы сами загрузили при открытии диспута. 404, если чек не прикладывался.

GET/disputes/42/receipt
curl {BASE_URL}/api/merchant/disputes/42/receipt \
  -H "Authorization: Bearer sk_live_..." \
  -o receipt.pdf

07Баланс

Баланс мерчанта хранится в USDT. Пополняется автоматически при успешных заявках на Вход.

GET/balanceread

Текущий баланс

reserved — сумма, удерживаемая по графику резервирования и пока недоступная к выводу.

200
{
  "balance": 1284.56,
  "reserved": 120.00,
  "available": 1164.56
}
POST/balance/withdrawwrite_payouts

Вывести средства

ПараметрТипОписание
amount обязательноnumberСумма в USDT, минимум 10.
network обязательноstringtrc20 или erc20.
address обязательноstringАдрес кошелька в выбранной сети.
Возможные ошибки
400«Некорректная сумма» / «Минимальная сумма вывода — 10 USDT».
400«Недостаточно средств на балансе» — сумма превышает доступный остаток (available).
400«Некорректная сеть» / «Укажите адрес кошелька» / «Некорректный адрес TRC20» / «Некорректный адрес ERC20».
POST/balance/withdraw
curl -X POST {BASE_URL}/api/merchant/balance/withdraw \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 250,
    "network": "trc20",
    "address": "TXy2Ss9K...pQ7m"
  }'
200
{ "id": 88, "status": "pending" }
GET/balance/historyread

История движений

Фильтры: type (deposit / withdraw / adjustment), date_from, date_to, page, per_page.

200
{
  "data": [
    {
      "id": 88,
      "type": "withdraw",
      "amount": 250,
      "status": "success",
      "tx_hash": "0x91a…",
      "network": "trc20",
      "address": "TXy2Ss9K...pQ7m",
      "created_at": "2026-08-03 10:02:00",
      "updated_at": "2026-08-03 10:14:20"
    }
  ],
  "total": 1, "page": 1, "per_page": 20
}

08Вебхуки

LEON отправляет POST-запрос на ваш URL при каждом событии, на которое вы подписаны. Настройте URL и события в личном кабинете (раздел «Вебхуки») либо через API ниже.

События

СобытиеКогда отправляется
payment.successЗаявка на Вход подтверждена трейдером или решена в пользу мерчанта по диспуту.
payment.cancelledЗаявка на Вход отменена мерчантом или истекла по времени.
dispute.openedОткрыт диспут по отменённой заявке на Вход.
dispute.resolvedДиспут решён — в пользу мерчанта, трейдера, или отозван.
💡

Когда диспут решается в пользу мерчанта, помимо dispute.resolved дополнительно придёт payment.success по той же заявке — так что если вы слушаете только платёжные события (без диспутов), вы всё равно узнаете об успехе.

Тело запроса

Каждое событие оборачивается общими полями event и sent_at:

payment.success
{
  "event": "payment.success",
  "sent_at": "2026-08-03 14:41:02",
  "transaction_id": 764,
  "external_id": "order-10231",
  "amount_rub": 5000,
  "amount_usdt": 52.41,
  "status": "success"
}
dispute.resolved
{
  "event": "dispute.resolved",
  "sent_at": "2026-08-03 15:10:44",
  "dispute_id": 42,
  "transaction_id": 764,
  "resolution": "resolved_merchant",
  "amount_usdt": 52.41
}

Проверка подписи

Каждый запрос подписывается HMAC-SHA256 по вашему секрету вебхука и точному телу запроса, подпись передаётся в заголовке X-Leon-Signature. Секрет доступен в личном кабинете (раздел «Вебхуки») либо через GET /webhook-secret — сверяйте подпись перед тем, как доверять содержимому запроса.

header
X-Leon-Signature: 3f9a1c...e07b2d
verify signature
const crypto = require("crypto");

function isValidSignature(rawBody, signatureHeader, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody) // необработанное тело запроса, без JSON.parse
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader),
  );
}
verify signature
import hmac
import hashlib

def is_valid_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)
⚠️

Считайте HMAC от сырых байт тела запроса, полученных до какого-либо парсинга — если сначала распарсить JSON и затем сериализовать обратно, порядок ключей или пробелы могут отличаться, и подпись не совпадёт.

Ретраи и таймауты

Ваш эндпоинт должен ответить в течение 5 секунд. Доставка — «по возможности»: если вебхук выключен или не подписан на событие — заявка или диспут всё равно обрабатываются штатно, событие просто не отправляется. Если вебхук включён, но ваш эндпоинт ответил с кодом вне диапазона 200–299 (или не ответил вовремя) — попытка считается неудачной и повторяется автоматически:

ПопыткаКогда
1сразу
2через 30 секунд после первой
3через 2 минуты после второй
4через 10 минут после третьей

Как только любая попытка получает ответ 200–299 — цепочка останавливается. После 4-й неудачной попытки LEON прекращает попытки по этому событию. Каждая попытка — отдельная строка в истории доставок, с номером в поле attempt — так вы отличите повтор одного и того же события от двух разных событий. Если все 4 попытки провалились (эндпоинт был недоступен дольше ~12 минут) — сверяйте состояние вручную через GET-эндпоинты по id из последнего известного события.

GET/webhook-settingswebhooks

Настройки вебхука

POST на тот же адрес обновляет настройки: url, events[], status (active / disabled).

200
{
  "url": "https://shop.example.com/leon/webhook",
  "events": ["payment.success", "payment.cancelled"],
  "status": "active"
}
GET/webhook-logswebhooks

Логи доставки

Последние попытки отправки — код ответа и время выполнения. Хранятся последние 50 записей.

200
{
  "data": [
    {
      "id": 1205,
      "url": "https://shop.example.com/leon/webhook",
      "event": "payment.success",
      "attempt": 2,
      "response_code": 200,
      "response_time_ms": 211,
      "created_at": "2026-08-03 14:41:32"
    },
    {
      "id": 1204,
      "url": "https://shop.example.com/leon/webhook",
      "event": "payment.success",
      "attempt": 1,
      "response_code": 503,
      "response_time_ms": 184,
      "created_at": "2026-08-03 14:41:02"
    }
  ],
  "total": 2, "page": 1, "per_page": 20
}
POST/webhook-testwebhooks

Тестовая отправка

Отправляет пробный подписанный запрос на указанный URL, не создавая никаких реальных заявок — удобно проверить обработчик перед подключением.

POST/webhook-test
curl -X POST {BASE_URL}/api/merchant/webhook-test \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://shop.example.com/leon/webhook",
    "event": "payment.success"
  }'

09Справочник

Сводные таблицы для быстрого поиска — без пересказа деталей из разделов выше.

Жизненный цикл заявок

PayIn
pending
  ├─ трейдер подтвердил ───────────▶ success
  └─ отменена / истекло время ─────▶ cancelled
                                        └─ открыт диспут ─▶ см. Dispute ниже
Dispute
open / pending_trader
  ├─ решён в пользу мерчанта ───▶ resolved_merchant   (заявка PayIn → success)
  ├─ решён в пользу трейдера ───▶ resolved_psp        (заявка остаётся cancelled)
  └─ отозван мерчантом ─────────▶ cancelled_merchant  (заявка остаётся cancelled)

Лимиты

ПараметрЗначение
Время жизни заявки (PayIn)15 минут от создания до автоматической отмены
Срок на решение диспута15–360 минут, по умолчанию 30
Чек к диспуту1 файл, PDF / JPG / PNG, до 5 МБ
Минимальный вывод с баланса10 USDT
Размер страницы (per_page)1–100, по умолчанию 20
Хранение логов вебхуковпоследние 50 попыток
Таймаут ответа на вебхук5 секунд
Повторные попытки вебхукадо 4 попыток всего: сразу, +30с, +2мин, +10мин
Обновление курсакеш на 30 секунд
⚠️

Если все 4 попытки доставки вебхука провалились — LEON прекращает пытаться по этому событию. Ориентируйтесь на лог доставок и на опрос состояния через GET-эндпоинты, если подозреваете пропуск события.

Карта эндпоинтов

МетодПутьПравоОписание
GET/ratereadТекущий курс USDT/RUB
POST/payin/createwrite_paymentsСоздать заявку на Вход
GET/payin/listreadСписок заявок на Вход
GET/payin/{id}readЗаявка на Вход по ID
POST/payin/{id}/cancelwrite_paymentsОтменить заявку на Вход
POST/disputes/createwrite_paymentsОткрыть диспут
GET/disputes/listreadСписок диспутов
GET/disputes/statisticsreadСчётчики открытых / просроченных / решённых диспутов
GET/disputes/{id}readДиспут по ID
GET/disputes/for-transaction/{id}readАктивный диспут по заявке, если есть
POST/disputes/{id}/cancelwrite_paymentsОтменить диспут
GET/disputes/{id}/receiptreadСкачать приложенный чек
GET/balancereadБаланс, резерв, доступно к выводу
POST/balance/withdrawwrite_payoutsВывести USDT на внешний адрес
GET/balance/historyreadИстория движений по балансу
GET/balance/history/{id}readОперация по балансу по ID
GET/webhook-settingswebhooksТекущие настройки вебхука
POST/webhook-settingswebhooksОбновить URL / события / статус
GET/webhook-secretwebhooksМаскированный секрет подписи
POST/webhook-secret/regeneratewebhooksПеревыпустить секрет — прежний перестаёт действовать немедленно
GET/webhook-logswebhooksЛог последних доставок
POST/webhook-testwebhooksОтправить тестовое событие