memo), мониторит
сеть на входящую транзакцию и сообщает об оплате двумя способами: через статусы (которые
вы читаете GET-запросами) и через webhooks, которые платформа сама
шлёт на ваш callback_url.
Все запросы подписываются HMAC — см. Аутентификация. Ответы приходят
в едином конверте: { "ok": true, "data": ... } при успехе и
{ "ok": false, "error": { "code": "...", "message": "..." } } при ошибке (см.
Ошибки). Все суммы — строки, чтобы не терять точность на float.
Во всех примерах ниже базовый URL и идентификатор ключа одни и те же:
https://wallet.your-exchange.com и X-Api-Id: pk_live_a1b2c3d4. Подставьте свои
значения из админ-кабинета.Эндпоинты
| Метод | Путь | Назначение |
|---|---|---|
POST | /v1/public/deposits | создать депозит |
GET | /v1/public/deposits | список (история), с пагинацией и фильтром по статусу |
GET | /v1/public/deposits/{uuid} | получить депозит по его uuid |
GET | /v1/public/deposits/by-order-id/{orderId} | получить депозит по вашему order_id |
GET | /v1/public/deposits/{uuid}/aml | AML-данные (source-of-funds) по uuid |
GET | /v1/public/deposits/by-order-id/{orderId}/aml | AML-данные по вашему order_id |
Адрес или адрес + memo: TON против TRON/EVM
Платформа поддерживает две модели идентификации входящего платежа. От модели зависит, что именно нужно показать вашему клиенту для оплаты.Address-based (TRON, EVM)
На каждый депозит выдаётся уникальный адрес. В ответе
memo равен null. Клиент
переводит средства на data.address — этого достаточно, чтобы платёж был привязан к
нужной заявке.Memo-based (TON)
Используется общий приёмный адрес плюс уникальный
memo (он же comment/tag).
В ответе memo не равен null. Клиент обязан указать и data.address, и data.memo —
без memo платёж невозможно сопоставить с заявкой.Создать депозит
POST /v1/public/deposits
Создаёт новый депозит и возвращает реквизиты для оплаты. Вызывайте этот эндпоинт в момент,
когда клиент на стороне обменника выбрал валюту и готов платить.
Операция идемпотентна по комбинации (site, order_id, asset) и, опционально, по заголовку
X-Idempotency-Key. Подробнее — в разделе Идемпотентность.
Создание новых депозитов требует активной лицензии инстанса. Если лицензия не активирована,
эндпоинт вернёт
403 LICENSE_REQUIRED. Уже идущие депозиты при этом не затрагиваются.Тело запроса
Код актива, например
USDT_TRC20, TRX, USDT_TON. Полный список доступных активов —
GET /v1/public/assets. Максимум 64 символа.Ваш идентификатор заявки (label), 1–255 символов. Опционально — если не передать,
платформа сгенерирует уникальный код вида
NNNN-NNNN-NNNN. По умолчанию (строгий режим)
order_id должен быть уникален в рамках сайта: повтор уже использованного значения
вернёт 409 DUPLICATE_ORDER_ID. Один и тот же order_id на другой валюте также вернёт
409. Для безопасных ретраев используйте X-Idempotency-Key — он проверяется раньше,
чем срабатывает эта ошибка. См. Идемпотентность.Ожидаемая сумма как decimal-строка, например
"100.50". Опционально — если не
передать, берётся минимальная сумма приёма актива (asset.minDepositAmount). Значение
"0" означает «принять любую сумму». Число знаков после запятой не должно превышать
точность актива, иначе вернётся 400 AMOUNT_TOO_MANY_DECIMALS.Опциональная заметка к депозиту (видна только вам в админ-кабинете). Максимум 1024 символа.
memo:
Покажите клиенту
data.address, а если data.memo не равен null (memo-сети) — ещё и
data.memo как обязательное поле. transaction равен null до тех пор, пока в сети не
будет замечена входящая транзакция.Поля ответа
Ответ создания и все GET-эндпоинты (кроме AML) возвращают один и тот же объект депозита:Публичный идентификатор депозита. Используйте его в
GET /v1/public/deposits/{uuid}.Ваш
order_id (label). Если вы его не передавали, здесь будет авто-сгенерированный код.Адрес для оплаты. Для memo-сетей — общий приёмный адрес (используется вместе с
memo).Memo/comment. Не равен
null и обязателен для memo-сетей (TON); null для address-based
сетей (TRON, EVM).Код актива депозита.
Ожидаемая сумма (строка).
"0" означает, что принимается любая сумма.Бизнес-статус депозита. Полный набор и переходы — Статусы депозита.
ISO-8601. До какого момента сеть мониторится на оплату. После этого момента неоплаченный
депозит уходит в
expired.Ссылка на адрес в блок-эксплорере (
null, если для актива не настроен шаблон).On-chain данные входящей транзакции.
null, пока депозит не получил ни одной транзакции.Получить депозит
GET /v1/public/deposits/{uuid} — по uuid из ответа на создание.
GET /v1/public/deposits/by-order-id/{orderId} — по вашему order_id.
Оба эндпоинта возвращают один и тот же объект депозита. Поле transaction заполняется, как
только в сети замечена входящая tx, и обновляется с каждым новым подтверждением. Опрашивайте
эндпоинт периодически либо опирайтесь на webhooks, чтобы не дёргать
API лишний раз.
Это GET-запросы без тела, поэтому подписываемое сообщение —
X-Timestamp + "." + "", то есть просто "1769990500." (timestamp и точка).
См. Аутентификация.Список депозитов
GET /v1/public/deposits?page=1&perPage=20&status=paid
Возвращает историю депозитов вашего сайта в обратном хронологическом порядке. Каждый элемент
имеет ту же форму, что и одиночный депозит.
Параметры запроса
Номер страницы, начиная с 1.
Размер страницы. Минимум 1, максимум 100.
Фильтр по статусу: одно значение (
?status=paid) или несколько через запятую
(?status=paid,paid_over). Допустимые значения — из набора бизнес-статусов депозита
(см. Статусы депозита). Неизвестные значения молча игнорируются.Поля meta
Текущая страница.
Размер страницы.
Всего записей по всем страницам (для пагинации).
AML-данные депозита
GET /v1/public/deposits/{uuid}/aml
GET /v1/public/deposits/by-order-id/{orderId}/aml
Отдельный под-ресурс с результатом AML-скрининга source-of-funds — адреса отправителя
входящей транзакции. Основной объект депозита намеренно не содержит AML-полей; запрашивайте
их явно через эти эндпоинты.
amlStatus равен not_checked, если AML-скрининг выключен в настройках инстанса, либо
транзакция ещё не замечена, либо сеть не поддерживается AML-провайдером. Значение
checkState: "skipped" НЕ означает «чисто» — это означает, что проверка не выполнялась.Поля AML-ответа
UUID депозита (тот же, что в
GET /{uuid}).Ваш
order_id (label).Код актива депозита.
Код сети депозита (например
TRON, TON).Адрес отправителя входящей транзакции — именно он проходит AML-скрин.
null, пока tx не
замечена.Итоговый AML-статус депозита:
not_checked (не проверялся / AML выключен) | passed (чисто)
| flagged (подозрительно, но не блокировка) | hold (заблокирован, ждёт ручного решения)
| rejected (отклонён).Состояние запроса к провайдеру:
pending | success | failed | error | skipped.
null, если проверки не было.Risk-score 0–100 (строка).
null, если проверки не было.Уровень риска:
low | medium | high | severe. Значение severe соответствует
санкциям, терроризму, краденым средствам или эксплуатации — блокировка независимо от score.Решение скрининга:
pass | flag | block.Код AML-провайдера.
Топ-сигнал риска (категория с максимальным весом), например
mixer, sanctions, scam,
darknet.Карта сигналов риска и их весов (0..1).
null, если провайдер их не вернул.Ссылка на полный отчёт провайдера (если есть).
Публичная share-ссылка на отчёт (если есть).
ISO-8601. Когда выполнен AML-скрин.
null, если проверки не было.Ручное действие оператора над заблокированным депозитом:
release (разрешить свип) |
quarantine_now.ISO-8601. Когда применено ручное действие.
Причина ручного действия (комментарий оператора).
Частые ошибки
| Код | HTTP | Когда возникает |
|---|---|---|
VALIDATION_FAILED | 400 | тело запроса не прошло валидацию (например, отсутствует assetCode) |
INVALID_ASSET | 404 | передан неизвестный assetCode (сверьтесь с GET /v1/public/assets) |
AMOUNT_TOO_MANY_DECIMALS | 400 | в expectedAmount больше знаков после запятой, чем поддерживает актив |
INVALID_SIGNATURE | 401 | неверная HMAC-подпись — проверьте формулу сообщения |
TIMESTAMP_SKEW | 401 | X-Timestamp отличается от серверного более чем на 300 секунд |
IP_NOT_WHITELISTED | 403 | IP сервера обменника не в белом списке |
LICENSE_REQUIRED | 403 | инстанс без активной лицензии — создание депозитов недоступно |
DEPOSIT_NOT_FOUND | 404 | депозит не найден или принадлежит другому сайту |
DUPLICATE_ORDER_ID | 409 | order_id уже использован (в том числе на другой валюте) |
IDEMPOTENCY_CONFLICT | 400 | тот же X-Idempotency-Key с другим телом запроса |
Частые вопросы
Когда поле transaction перестаёт быть null?
Когда поле transaction перестаёт быть null?
Как только платформа замечает первую входящую транзакцию на адрес (и memo) депозита.
До этого момента
transaction равен null, а status остаётся check. После детекции
статус переходит в process, а поля транзакции обновляются с каждым подтверждением.Как отличить точную оплату от переплаты или недоплаты?
Как отличить точную оплату от переплаты или недоплаты?
По финальному статусу:
paid — оплачено ровно ожидаемой суммой, paid_over — больше,
wrong_amount — меньше. Если expectedAmount равен "0", принимается любая сумма и
исход всегда paid. Точную фактическую сумму смотрите в transaction.receivedAmount.
Подробнее — в Статусах депозита.Нужно ли опрашивать API или можно полагаться на webhooks?
Нужно ли опрашивать API или можно полагаться на webhooks?
Рекомендуем основным каналом сделать webhooks — платформа сама
уведомит о смене статуса. GET-эндпоинты используйте как резервный механизм (для
реконсиляции и при пропущенных вебхуках), опрашивая их с разумным интервалом.
Что вернётся, если повторить создание с тем же order_id?
Что вернётся, если повторить создание с тем же order_id?
В строгом режиме (по умолчанию) —
409 DUPLICATE_ORDER_ID, второй депозит не создаётся.
Чтобы безопасно повторять запрос при сетевых сбоях, передавайте X-Idempotency-Key: при
совпадении ключа и тела вернётся ранее созданный депозит. См. Идемпотентность.Можно ли получить чужой депозит по uuid?
Можно ли получить чужой депозит по uuid?
Нет. Все запросы скоупятся по вашему сайту. Запрос депозита, принадлежащего другому сайту,
вернёт
404 DEPOSIT_NOT_FOUND — платформа не раскрывает существование чужих UUID.