API · Документация

Документация API

Приём депозитов, выводы, инвойсы и подписанные вебхуки в сетях USDT (BEP20/TRC20), BNB и BTC через одно REST API.

Базовый URLhttps://waltix.io/api

Введение

Waltix API позволяет принимать и отправлять криптовалюту программно: создавать адреса и счета для депозитов, инициировать выводы, получать тарифы и обрабатывать подписанные вебхуки. Все эндпоинты работают поверх одного базового URL.

Базовый URL всех запросов:

http
https://waltix.io/api

Подпись обязательна для всех публичных эндпоинтов (GET, POST и др.). Алгоритм описан в разделе «Подпись».

Поддерживаемые сети

USDT в сетях BEP20 и TRC20, BNB (BEP20) и BTC. Полный актуальный список идентификаторов символов возвращает GET /symbol/.

Подпись и ключи

Ключи

КлючГде взятьДля чего
API key ID + secretЛичный кабинет → раздел API keysПодпись запросов к API
callback_keyЛичный кабинет → профильПроверка webhook

API key создаётся один раз: secret показывается только при создании. Для webhook используйте callback_key, а не secret API-ключа.

Заголовки запроса

ЗаголовокОписание
X-API-Key-IDUUID ключа
X-TimestampUnix timestamp, секунды
X-SignatureHMAC-SHA256 hex

Алгоритм подписи

  1. Соберите объект из полей params, body и path:
json
{
  "params": "url_encoded_query_string",
  "body": {},
  "path": "/api/user/balance/"
}
  • params — query string как в URL (search_query=foo, без ?)
  • body — JSON тела запроса; {} если тела нет
  • path — полный путь запроса с префиксом /api/, например /api/user/balance/
  1. Сериализуйте: json.dumps(data, separators=(",", ":"), sort_keys=True)
  2. Вычислите подпись:
text
signature = HMAC-SHA256(key=API_KEY_SECRET, message=timestamp + json_string)

Timestamp должен быть в пределах ±15 секунд от серверного времени. Если allowlist ключа пуст, при первом успешном запросе текущий IP записывается в allowlist, и дальше запросы принимаются только с этих IP.

Пример: GET баланс

bash
# params пустые, body {}
# path = /api/user/balance/
# data = {"body":{},"params":"","path":"/api/user/balance/"}

curl "https://waltix.io/api/user/balance/" \
  -H "X-API-Key-ID: <UUID>" \
  -H "X-Timestamp: 1718659200" \
  -H "X-Signature: <hex>"

Пример: POST адрес

bash
curl "https://waltix.io/api/user/address/" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Key-ID: <UUID>" \
  -H "X-Timestamp: 1718659200" \
  -H "X-Signature: <hex>" \
  -d '{"symbol_id":"USDTBEP20","callback_url":"https://example.com/cb","description":"shop"}'

Python: генерация подписи

python
import hashlib, hmac, json, time

def sign(key: str, timestamp: int, data: dict) -> str:
    s = json.dumps(data, separators=(",", ":"), sort_keys=True)
    return hmac.new(key.encode(), f"{timestamp}{s}".encode(), hashlib.sha256).hexdigest()

data = {"params": "", "body": {"symbol_id": "USDTBEP20"}, "path": "/api/user/address/"}
ts = int(time.time())
signature = sign(API_KEY_SECRET, ts, data)

PHP: генерация подписи

php
$data = ["params" => "", "body" => ["symbol_id" => "USDTBEP20"], "path" => "/api/user/address/"];
ksort($data);
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
$signature = hash_hmac("sha256", time() . $json, $API_KEY_SECRET);

Вебхуки

На ваш callback_url приходит POST. Подпись проверяется ключом callback_key по заголовкам X-Signature и X-Timestamp. Допустимое отклонение timestamp: ±15 секунд.

ЗаголовокОписание
X-SignatureHMAC-SHA256 hex
X-TimestampUnix timestamp

Данные для подписи

json
{
  "params": "",
  "body": { }
}
  • params — query string вашего endpoint
  • body — распарсенное JSON тело POST
  • поле path не используется
  • для подписи используется callback_key

Webhook депозита / вывода

В теле POST передаётся JSON-объект транзакции (поля описаны в соответствующих разделах). Для проверки подписи объект помещается в поле body, поле params оставляют пустым.

Webhook счёта (invoice)

json
{
  "params": "",
  "body": {
    "type": "invoice",
    "id": "5ca38db1-00c5-4aba-91e5-6a57bed60aee",
    "status": "executed"
  }
}

Тело POST совпадает с объектом подписи: на верхнем уровне поля params и body. Для проверки используйте распарсенное тело запроса целиком, без дополнительной обёртки.

Python: проверка webhook

python
# Webhook депозита и вывода / Deposit & withdrawal webhook
body = await request.json()
data = {"params": request.url.query, "body": body}
verify(request.headers["X-Signature"], CALLBACK_KEY, int(request.headers["X-Timestamp"]), data)

# Webhook счёта / Invoice webhook
data = await request.json()
verify(request.headers["X-Signature"], CALLBACK_KEY, int(request.headers["X-Timestamp"]), data)
python
def verify(signature: str, key: str, timestamp: int, data: dict) -> bool:
    if abs(int(time.time()) - timestamp) > 15:
        return False
    expected = sign(key, timestamp, data)
    return hmac.compare_digest(expected, signature)

Доставка вебхуков

При неуспешном ответе вашего сервера webhook повторяется автоматически. Если сервер уже ответил 2xx на первый webhook, повтор при смене статуса на executed не отправляется. При AML или ожидании подтверждений первый webhook может прийти со статусом pending. Актуальный статус запрашивайте через GET /user/transaction/.

Депозиты

Депозит регистрируется после on-chain перевода на адрес, полученный через API. Сканер блокчейна создаёт транзакцию с типом deposit.

  1. Создайте адрес: POST /user/address/ или счёт POST /invoice/.
  2. Плательщик отправляет перевод on-chain на выданный адрес.
  3. Сканер фиксирует депозит. Если указан callback_url, отправляется webhook.

Эндпоинты

  • POST/user/address/
  • GET/user/address/
  • GET/user/address/balance/{symbol_id}/
  • POST/invoice/
  • GET/invoice/
  • GET/invoice/my/{invoice_id}/
  • GET/invoice/{invoice_id}/transactions/
  • GET/symbol/
  • GET/user/transaction/
  • GET/user/transaction/{encoded_id}/

POST /user/address/ — запрос

ПолеТипОписание
symbol_id *stringИдентификатор символа: валюта в конкретной сети, например USDTBEP20, BNBBEP20. Список: GET /symbol/
callback_urlstringURL для webhook депозита
descriptionstringМетка адреса
external_idstringВаш ID

Виртуальные символы (USDT без сети) не принимаются. Указывайте символ с привязкой к сети.

POST /user/address/ — ответ

ПолеОписание
idID адреса
valueАдрес кошелька
symbol_idИдентификатор символа
callback_urlURL webhook
external_idВаш ID
created_atДата создания

POST /invoice/ — запрос

ПолеТипОписание
name *stringНазвание
symbol_idstringИдентификатор символа для оплаты
target_value_fiatdecimalСумма в фиате
target_currency_fiatstringФиат, по умолчанию USD
target_value_symboldecimalСумма в крипте
deadline_atdatetimeСрок счёта
callback_urlstringURL webhook статуса счёта
external_idstringВаш ID
is_payer_feeboolКомиссию платит плательщик
descriptionstringОписание

Нужно указать target_value_fiat или target_value_symbol. В ответе: адрес оплаты в target_wallet.value, текущий status, ссылка на оплату в pay_url.

GET /user/transaction/ — фильтры депозитов

ПараметрОписание
typedeposit
symbol_idИдентификатор символа
external_idВаш ID
search_queryПоиск по символу, hash, адресам

Webhook депозита — тело

ПолеОписание
typedeposit
statusСтатус транзакции
symbol_idИдентификатор символа
amountСумма зачисления на баланс
service_feeКомиссия сервиса
net_amountСумма on-chain перевода (amount + service_fee)
blockchain_data.hashTx hash
blockchain_data.from_addressОтправитель
blockchain_data.to_addressПолучатель (ваш адрес)
external_idВаш ID из адреса
invoiceДанные счёта, если депозит по invoice
aml_orderAML-проверка: status, data.level, data.risk_score (если включена)
callback_orderСтатус последней доставки webhook (last_status_code, last_response_data)
json
{
  "user_id": 1,
  "type": "deposit",
  "created_at": "2025-11-20T16:08:10.180830+00:00",
  "symbol_id": "USDTBEP20",
  "status": "executed",
  "amount": "4.696700000000000000",
  "service_fee": "0.803300000000000000",
  "net_amount": "5.500000000000000000",
  "blockchain_data": {
    "hash": "0xabc...",
    "from_address": "0x123",
    "to_address": "0x456"
  },
  "external_id": null,
  "callback_url": "https://example.com/cb"
}

Статусы депозита (on-chain / счёт)

statusОписание
pendingОжидание AML или подтверждений сети
executedЗачислено на баланс
dirty_lockАдрес помечен dirty, депозит заблокирован
cancelledОтменён

При неуспешной AML-проверке status транзакции становится risky. Поля AML: aml_order.status (created, pending_check, completed, risky, failed, manual_completed), aml_order.data.level (undefined, none, low, medium, high, severe), aml_order.data.risk_score (0–100).

Статусы счёта

statusОписание
activeОжидает оплаты
executedОплачен
expiredИстёк срок
cancelledОтменён

Депозиты ниже min_deposit_amount игнорируются.

Выводы

Эндпоинты

  • POST/user/balance/withdrawal/
  • GET/user/transaction/?type=withdrawal
  • GET/user/transaction/{encoded_id}/
  • GET/symbol/

Отдельного GET /withdrawal/{id} нет — используйте transaction API.

POST /user/balance/withdrawal/ — query

ПараметрОписание
totp_codeOTP из email. Не нужен при авторизации API key

POST /user/balance/withdrawal/ — запрос

ПолеТипОписание
symbol_id *stringИдентификатор символа, например USDTTRC20. Список: GET /symbol/
to_address *stringАдрес получателя
amount *decimalСумма получателю (net)
external_idstringВаш ID
callback_urlstringURL webhook
commentstringКомментарий (до 255 символов)
extra.memostringMemo/tag (если сеть поддерживает)
extra.fee_modestringПриоритет комиссии сети для BTC (см. ниже)

Комиссия списывается сверх amount: с баланса уходит amount + service_fee. При авторизации через API key применяются тарифы withdrawal_via_api_* (см. GET /setting/fees/). Rate limit: 5 запросов в секунду.

Приоритет комиссии BTC (extra.fee_mode)

fee_modeОписание
fastestFeeМаксимальный приоритет, быстрее всего
economyFeeЭкономный режим
minimumFeeМинимальный приоритет (значение по умолчанию)

Если fee_mode не передан или значение неизвестно, используется серверный дефолт (economyFee). Markup по режимам можно посмотреть в GET /blockchain/ → settings.service_fee_markup_by_fee_mode для сети BTC. Для сетей кроме BTC поле игнорируется.

Ошибки

detailПричина
Insufficient balanceНедостаточно средств
Invalid addressНеверный адрес
Minimum withdrawal amount is …Ниже минимума
TOTP code is requiredНужен totp_code без API key
MEMO doesn't supported on this chain!Memo не поддерживается

Webhook вывода — тело

Отправляется один раз при переходе вывода в статус executed. JSON-объект транзакции с type: withdrawal.

ПолеОписание
amountСумма транзакции (получатель + комиссия)
service_feeКомиссия
net_amountСумма получателю (amount - service_fee)
statusexecuted
blockchain_data.hashTx hash
to_addressАдрес получателя
memoMemo, если был
external_idВаш ID
fee_modeПриоритет комиссии BTC, если был указан

Статусы вывода

Для выводов status берётся из жизненного цикла вывода. AML-статусы (risky и т.п.) здесь не используются — в отличие от депозитов. Завершённые: executed, cancelled, failed.

statusОписание
compliance_approve_requiredОжидает ручного одобрения
createdВ очереди
aml_order_pendingAML проверка
prepare_pendingПодготовка транзакции
ready_to_transferГотов к отправке
transfer_lockОтправка в сеть
pendingОжидание подтверждений
swap_lockОжидание autoswap
executedВыполнен
cancelledОтменён
failedОшибка

Ограничения

ПараметрОписание
min_withdrawal_amountМинимум по символу и тарифу
withdrawal_fee_amountФиксированная комиссия (UI / без API key)
withdrawal_fee_percentageПроцент комиссии (UI / без API key)
withdrawal_via_api_fee_amountФиксированная комиссия при запросах через API key
withdrawal_via_api_fee_percentageПроцент комиссии при запросах через API key
totp_codeОбязателен без API key (email OTP, 10 мин)

Повтор запроса с тем же external_id не является идемпотентным.

Тарифы и комиссии

Эндпоинты

  • GET/setting/fees/
  • GET/setting/fees/my/

GET /setting/fees/ доступен без сессии, с API key. Query-параметры user_id и tariff_id — для админского просмотра конкретных override (обычно не нужны интегратору).

Поля ответа FeesSettingsDTO

ПолеОписание
symbol_idИдентификатор символа
user_idOverride для пользователя (null — глобальный)
tariff_idOverride для тарифа (null — глобальный)
min_deposit_amountМинимальная сумма депозита
min_withdrawal_amountМинимальная сумма вывода
deposit_fee_amountФикс. комиссия депозита (UI)
deposit_fee_percentage% комиссии депозита (UI)
withdrawal_fee_amountФикс. комиссия вывода (UI)
withdrawal_fee_percentage% комиссии вывода (UI)
deposit_via_api_fee_amountФикс. комиссия депозита через API key
deposit_via_api_fee_percentage% комиссии депозита через API key
withdrawal_via_api_fee_amountФикс. комиссия вывода через API key
withdrawal_via_api_fee_percentage% комиссии вывода через API key
swap_fee_amountФикс. комиссия swap
swap_fee_percentage% комиссии swap
swap_from_min_amountМин. сумма «от» для swap
swap_to_min_amountМин. сумма «к» для swap

Приоритет применения: пользовательский override → тариф → глобальные настройки. Для интеграции через API key используйте поля *_via_api_*. Для операций из личного кабинета — deposit_fee_* / withdrawal_fee_*.

Нужна помощь?

Создайте API-ключ в личном кабинете и начните интеграцию за несколько минут.

Открыть кабинет