API · Документация
Документация API
Приём депозитов, выводы, инвойсы и подписанные вебхуки в сетях USDT (BEP20/TRC20), BNB и BTC через одно REST API.
https://waltix.io/apiВведение
Waltix API позволяет принимать и отправлять криптовалюту программно: создавать адреса и счета для депозитов, инициировать выводы, получать тарифы и обрабатывать подписанные вебхуки. Все эндпоинты работают поверх одного базового URL.
Базовый URL всех запросов:
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-ID | UUID ключа |
| X-Timestamp | Unix timestamp, секунды |
| X-Signature | HMAC-SHA256 hex |
Алгоритм подписи
- Соберите объект из полей params, body и path:
{
"params": "url_encoded_query_string",
"body": {},
"path": "/api/user/balance/"
}- params — query string как в URL (search_query=foo, без ?)
- body — JSON тела запроса; {} если тела нет
- path — полный путь запроса с префиксом /api/, например /api/user/balance/
- Сериализуйте: json.dumps(data, separators=(",", ":"), sort_keys=True)
- Вычислите подпись:
signature = HMAC-SHA256(key=API_KEY_SECRET, message=timestamp + json_string)Timestamp должен быть в пределах ±15 секунд от серверного времени. Если allowlist ключа пуст, при первом успешном запросе текущий IP записывается в allowlist, и дальше запросы принимаются только с этих IP.
Пример: GET баланс
# 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 адрес
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: генерация подписи
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: генерация подписи
$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-Signature | HMAC-SHA256 hex |
| X-Timestamp | Unix timestamp |
Данные для подписи
{
"params": "",
"body": { }
}- params — query string вашего endpoint
- body — распарсенное JSON тело POST
- поле path не используется
- для подписи используется callback_key
Webhook депозита / вывода
В теле POST передаётся JSON-объект транзакции (поля описаны в соответствующих разделах). Для проверки подписи объект помещается в поле body, поле params оставляют пустым.
Webhook счёта (invoice)
{
"params": "",
"body": {
"type": "invoice",
"id": "5ca38db1-00c5-4aba-91e5-6a57bed60aee",
"status": "executed"
}
}Тело POST совпадает с объектом подписи: на верхнем уровне поля params и body. Для проверки используйте распарсенное тело запроса целиком, без дополнительной обёртки.
Python: проверка webhook
# 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)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.
- Создайте адрес: POST /user/address/ или счёт POST /invoice/.
- Плательщик отправляет перевод on-chain на выданный адрес.
- Сканер фиксирует депозит. Если указан 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_url | string | URL для webhook депозита |
| description | string | Метка адреса |
| external_id | string | Ваш ID |
Виртуальные символы (USDT без сети) не принимаются. Указывайте символ с привязкой к сети.
POST /user/address/ — ответ
| Поле | Описание |
|---|---|
| id | ID адреса |
| value | Адрес кошелька |
| symbol_id | Идентификатор символа |
| callback_url | URL webhook |
| external_id | Ваш ID |
| created_at | Дата создания |
POST /invoice/ — запрос
| Поле | Тип | Описание |
|---|---|---|
| name * | string | Название |
| symbol_id | string | Идентификатор символа для оплаты |
| target_value_fiat | decimal | Сумма в фиате |
| target_currency_fiat | string | Фиат, по умолчанию USD |
| target_value_symbol | decimal | Сумма в крипте |
| deadline_at | datetime | Срок счёта |
| callback_url | string | URL webhook статуса счёта |
| external_id | string | Ваш ID |
| is_payer_fee | bool | Комиссию платит плательщик |
| description | string | Описание |
Нужно указать target_value_fiat или target_value_symbol. В ответе: адрес оплаты в target_wallet.value, текущий status, ссылка на оплату в pay_url.
GET /user/transaction/ — фильтры депозитов
| Параметр | Описание |
|---|---|
| type | deposit |
| symbol_id | Идентификатор символа |
| external_id | Ваш ID |
| search_query | Поиск по символу, hash, адресам |
Webhook депозита — тело
| Поле | Описание |
|---|---|
| type | deposit |
| status | Статус транзакции |
| symbol_id | Идентификатор символа |
| amount | Сумма зачисления на баланс |
| service_fee | Комиссия сервиса |
| net_amount | Сумма on-chain перевода (amount + service_fee) |
| blockchain_data.hash | Tx hash |
| blockchain_data.from_address | Отправитель |
| blockchain_data.to_address | Получатель (ваш адрес) |
| external_id | Ваш ID из адреса |
| invoice | Данные счёта, если депозит по invoice |
| aml_order | AML-проверка: status, data.level, data.risk_score (если включена) |
| callback_order | Статус последней доставки webhook (last_status_code, last_response_data) |
{
"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_code | OTP из email. Не нужен при авторизации API key |
POST /user/balance/withdrawal/ — запрос
| Поле | Тип | Описание |
|---|---|---|
| symbol_id * | string | Идентификатор символа, например USDTTRC20. Список: GET /symbol/ |
| to_address * | string | Адрес получателя |
| amount * | decimal | Сумма получателю (net) |
| external_id | string | Ваш ID |
| callback_url | string | URL webhook |
| comment | string | Комментарий (до 255 символов) |
| extra.memo | string | Memo/tag (если сеть поддерживает) |
| extra.fee_mode | string | Приоритет комиссии сети для 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) |
| status | executed |
| blockchain_data.hash | Tx hash |
| to_address | Адрес получателя |
| memo | Memo, если был |
| external_id | Ваш ID |
| fee_mode | Приоритет комиссии BTC, если был указан |
Статусы вывода
Для выводов status берётся из жизненного цикла вывода. AML-статусы (risky и т.п.) здесь не используются — в отличие от депозитов. Завершённые: executed, cancelled, failed.
| status | Описание |
|---|---|
| compliance_approve_required | Ожидает ручного одобрения |
| created | В очереди |
| aml_order_pending | AML проверка |
| 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_id | Override для пользователя (null — глобальный) |
| tariff_id | Override для тарифа (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-ключ в личном кабинете и начните интеграцию за несколько минут.
Открыть кабинет