Customer Wallets
Крипто-кошельки ваших клиентов: вы выдаёте клиенту адрес пополнения в нужной сети, платформа принимает депозит и ведёт остаток, а вы распоряжаетесь им через API - выводите на внешний адрес, списываете в свою пользу и выплачиваете обратно. Кастоди, подтверждения сети и комплаенс остаются на нашей стороне; вы работаете только с этим набором эндпоинтов.
Модель данных
У клиента один кошелёк на монету и по одному адресу на сеть. Монета описывается парой asset + network (например USDT в сети TRON). В балансах и в мастер-счёте та же монета фигурирует как currency: для токенов это составной код {ASSET}_{NETWORK} (USDT_TRON), для нативных монет - просто BTC, LTC.
Имена сетей
network
string
optional
TRON, ETHEREUM, BSC, POLYGON, BASE, BITCOIN, LITECOIN. Точный список доступных вам монет и сетей - в GET /api/v1/merchant/service-pricing.asset
string
optional
USDT, USDC, BTC, LTC.currency
string
optional
USDT_TRON, USDC_BSC, BTC. Токен всегда несёт сеть в коде - один и тот же тикер в разных сетях это разные строки баланса.| Name | Type | Required | Description |
|---|---|---|---|
network
|
string
|
optional |
Верхний регистр: TRON, ETHEREUM, BSC, POLYGON, BASE, BITCOIN, LITECOIN. Точный список доступных вам монет и сетей - в GET /api/v1/merchant/service-pricing.
|
asset
|
string
|
optional |
Тикер монеты в верхнем регистре: USDT, USDC, BTC, LTC.
|
currency
|
string
|
optional |
Код строки баланса: USDT_TRON, USDC_BSC, BTC. Токен всегда несёт сеть в коде - один и тот же тикер в разных сетях это разные строки баланса.
|
"150.000000000000000000", "5", "0". Число знаков после точки у разных полей разное и на смысл не влияет - разбирайте значение как decimal и сравнивайте по значению, а не по тексту. Числа с плавающей точкой в денежной арифметике использовать нельзя. В запросах сумма принимается только плоской десятичной строкой: без знака и экспоненты, до 18 знаков после точки. Значения вида "1e3", "+10", "10." отклоняются кодом 422 invalid_request, а не приводятся молча к числу.
Адреса пополнения
/api/v1/customers/{uuid}/wallet/addresses
Выдать адрес клиенту в указанной сети
Body
chain
string
required
TRON, ETHEREUM, BSC, POLYGON, BASE, BITCOIN, LITECOIN. Регистр не важен, приводится к верхнему.| Name | Type | Required | Description |
|---|---|---|---|
chain
|
string
|
required |
Сеть: TRON, ETHEREUM, BSC, POLYGON, BASE, BITCOIN, LITECOIN. Регистр не важен, приводится к верхнему.
|
Responses
{
"data": {
"network": "TRON",
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"sandbox": null
}
}
{
"error": {
"code": "wallets_disabled",
"message": "Крипто-кошельки клиентов сейчас недоступны.",
"request_id": "req_Zx8Cv6Bn4Mk2Lj0Hg9Fd7Sa5"
}
}
{
"error": {
"code": "coin_not_allowed",
"message": "Эта монета недоступна для вашей учётной записи.",
"request_id": "req_7Kp2Rt9Wx4Yz1Qb6Nm3Vc8L"
}
}
Поле sandbox равно true только у синтетических адресов песочницы; в боевом окружении оно null.
/api/v1/customers/{uuid}/wallet/addresses
Все выданные адреса клиента
{ network, address, sandbox }, отсортированный по сети. Параметров нет.Депозиты
Депозит зачисляется сразу после появления транзакции в сети, не дожидаясь подтверждений: баланс клиента растёт мгновенно, а строка журнала при этом остаётся в статусе pending и переходит в confirmed, когда сеть наберёт нужное число подтверждений. По каждому событию уходит вебхук: customer.deposit.detected в момент зачисления и customer.deposit.confirmed после подтверждения.
Правила приёма
Рекомендованный минимум
optional
min_deposit из GET /api/v1/merchant/service-pricing. Поступления меньше минимума тоже зачисляются, но экономического смысла в них мало: комиссия последующего вывода фиксированная и от суммы не зависит - показывайте минимум клиенту в интерфейсе пополнения.Зачисление бесплатно
optional
Только свои монеты
optional
BTC, LTC). Нативная монета сети TRON и EVM-сетей на адрес клиента не зачисляется - это служебные средства сети.Один адрес - одна сеть
optional
network, в которой он выдан.Комплаенс-проверка
optional
aml_status равно pending; вывод по такому клиенту временно отклоняется кодом aml_screening_in_progress.Заморозка
optional
locked, приходит вебхук customer.deposit.frozen, решение принимает комплаенс-офицер платформы. Снятие заморозки - вебхук customer.deposit.released.| Name | Type | Required | Description |
|---|---|---|---|
Рекомендованный минимум
|
optional |
Справочное значение min_deposit из GET /api/v1/merchant/service-pricing. Поступления меньше минимума тоже зачисляются, но экономического смысла в них мало: комиссия последующего вывода фиксированная и от суммы не зависит - показывайте минимум клиенту в интерфейсе пополнения.
|
|
Зачисление бесплатно
|
optional | За пополнение не берут ничего ни платформа, ни вы: клиенту зачисляется ровно та сумма, которая пришла на адрес. Надбавки на пополнение в контуре нет - зарабатываете вы на выводе. | |
Только свои монеты
|
optional |
Зачисляются токены из поддерживаемого списка и нативные монеты UTXO-сетей (BTC, LTC). Нативная монета сети TRON и EVM-сетей на адрес клиента не зачисляется - это служебные средства сети.
|
|
Один адрес - одна сеть
|
optional |
Отправка в другой сети на тот же адрес не будет распознана. Адрес всегда используйте вместе с network, в которой он выдан.
|
|
Комплаенс-проверка
|
optional |
Каждое поступление проходит автоматический скрининг отправителя. Пока вердикта нет, поле aml_status равно pending; вывод по такому клиенту временно отклоняется кодом aml_screening_in_progress.
|
|
Заморозка
|
optional |
При высоком риске сумма поступления переводится в locked, приходит вебхук customer.deposit.frozen, решение принимает комплаенс-офицер платформы. Снятие заморозки - вебхук customer.deposit.released.
|
Балансы клиента
/api/v1/customers/{uuid}/wallet
Крипто-балансы по всем доступным монетам
Responses
{
"data": [
{
"asset": "USDT",
"symbol": "USDT",
"network": "TRON",
"currency": "USDT_TRON",
"available": "150.0000000000",
"locked": "0.0000000000"
},
{
"asset": "USDT",
"symbol": "USDT",
"network": "BSC",
"currency": "USDT_BSC",
"available": "0",
"locked": "0"
}
],
"meta": {
"customer_status": "active"
}
}
available - остаток, которым можно распоряжаться прямо сейчас. locked - сумма, временно недоступная: замороженное комплаенсом поступление либо средства под уже принятой заявкой на вывод. Общий остаток клиента - сумма обоих полей.
Журнал движений
/api/v1/customers/{uuid}/wallet/transactions
Крипто-движения клиента (постраничная выборка)
Query parameters
coin
string
optional
USDT.direction
enum
optional
in - поступления и выплаты вам в пользу клиента; out - выводы и списания с клиента.status
enum
optional
pending, confirmed, failed.per_page
integer
optional
25page
integer
optional
1| Name | Type | Required | Description |
|---|---|---|---|
coin
|
string
|
optional |
Фильтр по тикеру монеты, например USDT.
|
direction
|
enum
|
optional |
in - поступления и выплаты вам в пользу клиента; out - выводы и списания с клиента.
|
status
|
enum
|
optional |
pending, confirmed, failed.
|
per_page
|
integer
|
optional |
Размер страницы, 1..100.
Default:
25 |
page
|
integer
|
optional |
Номер страницы.
Default:
1 |
Объект транзакции
Поля
id
string
optional
network
string
optional
asset
string
optional
direction
enum
optional
in или out - с точки зрения клиента.amount
string
optional
address
string|null
optional
internal:merchant:….counterparty
string|null
optional
tx_hash
string|null
optional
null, если операция внутренняя или отправка ещё не состоялась.status
enum
optional
pending, confirmed, failed - и ничего больше. Ветвите логику по нему.state
enum
optional
confirmations
integer
optional
aml_status
enum
optional
pending - проверка идёт; clear - вопросов нет; flagged - есть риск (обычно вместе с заморозкой); skipped - проверка неприменима (внутренние расчёты).frozen
bool
optional
fee.platform
string
optional
0.fee.merchant
string
optional
0: зачисление бесплатно.confirmed_at
datetime|null
optional
null.created_at
datetime
optional
| Name | Type | Required | Description |
|---|---|---|---|
id
|
string
|
optional | Идентификатор строки журнала (UUID). Он же используется как курсор в единой истории клиента. |
network
|
string
|
optional | Сеть операции. |
asset
|
string
|
optional | Тикер монеты. |
direction
|
enum
|
optional |
in или out - с точки зрения клиента.
|
amount
|
string
|
optional | Сумма операции без комиссий. |
address
|
string|null
|
optional |
Адрес зачисления (у поступления) или адрес получателя (у вывода). У внутренних расчётов - служебное значение вида internal:merchant:….
|
counterparty
|
string|null
|
optional | Адрес отправителя у поступления, адрес назначения у вывода либо человекочитаемая подпись у внутренних расчётов. |
tx_hash
|
string|null
|
optional |
Хеш транзакции в сети. null, если операция внутренняя или отправка ещё не состоялась.
|
status
|
enum
|
optional |
Стабильный словарь: pending, confirmed, failed - и ничего больше. Ветвите логику по нему.
|
state
|
enum
|
optional | Только у заявок на вывод: стадия обработки (см. ниже). У поступлений и внутренних расчётов поля нет вовсе. |
confirmations
|
integer
|
optional | Число подтверждений сети на момент ответа. |
aml_status
|
enum
|
optional |
pending - проверка идёт; clear - вопросов нет; flagged - есть риск (обычно вместе с заморозкой); skipped - проверка неприменима (внутренние расчёты).
|
frozen
|
bool
|
optional | Сумма по этой строке сейчас заморожена. |
fee.platform
|
string
|
optional |
Комиссия платформы, удержанная сверх суммы. У поступлений - 0.
|
fee.merchant
|
string
|
optional |
Ваша надбавка, удержанная сверх суммы, - она зачисляется на ваш мастер-счёт. У поступлений - 0: зачисление бесплатно.
|
confirmed_at
|
datetime|null
|
optional |
Момент подтверждения (ISO 8601) или null.
|
created_at
|
datetime
|
optional | Момент создания строки (ISO 8601). |
Responses
{
"data": [
{
"id": "7c1f2b90-4a3e-4a1f-9c62-8b0f4a7d2e11",
"network": "TRON",
"asset": "USDT",
"direction": "in",
"amount": "150.000000000000000000",
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"counterparty": "TWd4WrZ9wn84f5x1hZhL4DHvk738ns5jwb",
"tx_hash": "3f0c1b7a94e2d5c86a1f0b2d4e7c9a51b3d6f8e0a2c4b6d8f0e1a3c5b7d9f2e4",
"status": "confirmed",
"confirmations": 21,
"aml_status": "clear",
"frozen": false,
"fee": { "platform": "0.000000000000000000", "merchant": "0.000000000000000000" },
"confirmed_at": "2026-08-17T12:11:40+00:00",
"created_at": "2026-08-17T12:04:11+00:00"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total": 1,
"last_page": 1
}
}
status отвечает на вопрос «деньги дошли?» и никогда не выходит за три значения. state появляется только у заявок на вывод и отвечает на вопрос «на каком шаге заявка сейчас». Не подменяйте одно другим: интеграция, читающая стадию из status, увидит только pending.
Принудительная сверка
/api/v1/customers/{uuid}/wallet/sync
Перечитать поступления по адресам клиента
Body
chain
string
optional
| Name | Type | Required | Description |
|---|---|---|---|
chain
|
string
|
optional | Ограничить сверку одной сетью. Без параметра проверяются все адреса клиента. |
Responses
{
"data": {
"network": "TRON",
"new_deposits": 1,
"synced_at": "2026-08-17T12:20:03+00:00"
}
}
new_deposits - сколько поступлений зачислено именно этим вызовом. Ноль означает, что новых денег на адресах нет; это нормальный ответ, а не ошибка. Сверка покрывает TRON и UTXO-сети; в EVM-сетях поступления приходят по подписке и в отдельной сверке не нуждаются.
Вывод на внешний адрес
Вывод - двухшаговый сценарий: сначала предпросмотр quote (сколько спишется, что пройдёт по лимитам), затем создание заявки. Заявка обрабатывается асинхронно: ответ приходит сразу, деньги уходят в сеть фоном, а вы следите за стадией по вебхукам либо опросом статуса.
Предпросмотр
/api/v1/customers/{uuid}/wallet/withdraw/quote
Расчёт вывода без движения денег
"+10", "10." отклоняются кодом 422.'],
]" />
Responses
{
"data": {
"asset": "USDT",
"network": "TRON",
"amount": "100",
"fee_platform": "5",
"fee_merchant": "1.0000000000",
"total_debit": "106.0000000000",
"receives": "100",
"balance": "150.0000000000",
"daily_limit": "30000",
"daily_used": "0.0000000000",
"daily_left": "30000.0000000000",
"max_per_tx": "10000",
"min_withdraw": "10.000000000000000000",
"network_fee_from_amount": false,
"aml_precheck": false,
"allowed": true,
"reason": null
}
}
{
"data": {
"asset": "USDT",
"network": "TRON",
"amount": "50000",
"fee_platform": "5",
"fee_merchant": "1.0000000000",
"total_debit": "50006.0000000000",
"receives": "50000",
"balance": "150.0000000000",
"daily_limit": "30000",
"daily_used": "0.0000000000",
"daily_left": "30000.0000000000",
"max_per_tx": "10000",
"min_withdraw": "10.000000000000000000",
"network_fee_from_amount": false,
"aml_precheck": false,
"allowed": false,
"reason": {
"code": "withdraw_limit_exceeded",
"gate": "max_per_tx",
"error": "Сумма больше лимита на одну операцию (10000 USDT)."
}
}
}
Комиссии, лимиты и минимумы в примерах - иллюстративные: действующие значения вашей учётной записи всегда берите из витрины GET /api/v1/merchant/service-pricing либо из самого расчёта.
fee_merchant - ваша надбавка на вывод: фиксированная сумма в единицах выводимой монеты, заданная отдельно для каждой пары монета+сеть. Работа платформы и сети на выводе 10 и 10 000 USDT одинакова, поэтому процент давал бы стократную разницу в цене за одну и ту же операцию. Верхнюю границу надбавки по каждой монете устанавливает платформа; по монетам, где она равна нулю, надбавка недоступна. Действующие значения - в витрине GET /api/v1/merchant/service-pricing, блок withdraw.markup. На пополнение надбавки нет вовсе: зачисление бесплатно, клиенту приходит ровно то, что пришло на адрес.
Поля расчёта
amount
string
optional
fee_platform
string
optional
fee_merchant
string
optional
total_debit
string
optional
amount + fee_platform + fee_merchant.receives
string
optional
balance
string
optional
daily_limit
string
optional
daily_used
string
optional
daily_left
string
optional
max_per_tx
string
optional
min_withdraw
string
optional
network_fee_from_amount
bool
optional
BITCOIN, LITECOIN) - true: сеть удержит свою плату из отправляемой суммы, и получатель получит немного меньше amount. Для токенов - false.aml_precheck
bool
optional
false: предпросмотр не выполняет комплаенс-проверку адреса назначения. Она делается в момент создания заявки.allowed
bool
optional
reason
object|null
optional
allowed: false - причина отказа: code (тот же, что вернёт боевой вызов), gate (какая проверка не пройдена) и error (текст для человека).| Name | Type | Required | Description |
|---|---|---|---|
amount
|
string
|
optional | Сумма, которую вы запросили. |
fee_platform
|
string
|
optional | Фиксированная комиссия платформы за операцию в этой сети. Сетевые издержки покрывает платформа - отдельной платы за них нет. |
fee_merchant
|
string
|
optional | Ваша надбавка - фиксированная сумма, заданная вами для этой пары монета+сеть, в единицах выводимой монеты. От суммы вывода не зависит. Удерживается с клиента и зачисляется на ваш мастер-счёт. |
total_debit
|
string
|
optional |
Сколько всего спишется с клиента: amount + fee_platform + fee_merchant.
|
receives
|
string
|
optional | Сколько получит адрес назначения. |
balance
|
string
|
optional | Доступный остаток клиента по этой монете на момент расчёта. |
daily_limit
|
string
|
optional | Суточный лимит вывода на одного клиента, в эквиваленте USDT. Окно скользящее: считаются операции за последние 24 часа, полночь лимит не обнуляет. |
daily_used
|
string
|
optional | Сколько клиент вывел за последние 24 часа, в эквиваленте USDT. |
daily_left
|
string
|
optional | Остаток суточного лимита. Освобождается по мере того, как операции выходят за окно в 24 часа. |
max_per_tx
|
string
|
optional | Лимит на одну операцию, в эквиваленте USDT. |
min_withdraw
|
string
|
optional | Минимальная сумма вывода для этой монеты. |
network_fee_from_amount
|
bool
|
optional |
Для UTXO-сетей (BITCOIN, LITECOIN) - true: сеть удержит свою плату из отправляемой суммы, и получатель получит немного меньше amount. Для токенов - false.
|
aml_precheck
|
bool
|
optional |
Всегда false: предпросмотр не выполняет комплаенс-проверку адреса назначения. Она делается в момент создания заявки.
|
allowed
|
bool
|
optional | Пройдут ли проверки при создании заявки прямо сейчас. |
reason
|
object|null
|
optional |
При allowed: false - причина отказа: code (тот же, что вернёт боевой вызов), gate (какая проверка не пройдена) и error (текст для человека).
|
Создание заявки
/api/v1/customers/{uuid}/wallet/withdraw
Вывести средства клиента на внешний адрес
Idempotency-Key обязателен. Лимит - 6 запросов в минуту.Заголовки
Idempotency-Key
string
required
200 и полем duplicate: true, второй раз деньги не спишутся. Тот же ключ с другими параметрами - 409 conflict и ни копейки движения.| Name | Type | Required | Description |
|---|---|---|---|
Idempotency-Key
|
string
|
required |
Ваш уникальный ключ операции. Повтор с тем же ключом и теми же параметрами вернёт ту же заявку с кодом 200 и полем duplicate: true, второй раз деньги не спишутся. Тот же ключ с другими параметрами - 409 conflict и ни копейки движения.
|
"+10", "10." отклоняются кодом 422.'],
]" />
Responses
{
"data": {
"id": "b3a91d55-7c02-4c6e-91ad-5f3d2c4b8e70",
"network": "TRON",
"asset": "USDT",
"direction": "out",
"amount": "100.000000000000000000",
"address": "TWd4WrZ9wn84f5x1hZhL4DHvk738ns5jwb",
"counterparty": "TWd4WrZ9wn84f5x1hZhL4DHvk738ns5jwb",
"tx_hash": null,
"status": "pending",
"state": "processing",
"confirmations": 0,
"aml_status": "skipped",
"frozen": false,
"fee": { "platform": "5.000000000000000000", "merchant": "1.000000000000000000" },
"confirmed_at": null,
"created_at": "2026-08-17T12:31:07+00:00",
"duplicate": false
}
}
{
"error": {
"code": "idempotency_key_required",
"message": "Требуется заголовок Idempotency-Key.",
"request_id": "req_Qw3Er5Ty7Ui9Op1As2Df4Gh6"
}
}
{
"error": {
"code": "aml_blocked",
"message": "Операция отклонена комплаенс-проверкой.",
"request_id": "req_M9n8B7v6C5x4Z3a2S1d0F1gH"
}
}
Что проверяется перед списанием
Проверки идут в фиксированном порядке, и первая непройденная возвращает свой код. Тот же порядок и те же коды использует предпросмотр, поэтому расхождений между quote и боевым вызовом не бывает.
Вывод включён
withdraw_disabled
optional
403.Клиент активен
customer_blocked
optional
409.Монета доступна
coin_not_allowed
optional
422.Сумма корректна
amount_below_minimum
optional
min_withdraw монеты. Ноль или отрицательное значение отклоняется кодом invalid_request, положительная сумма ниже минимума - кодом amount_below_minimum. 422.Адрес валиден
invalid_address
optional
422.Адрес внешний
coin_not_allowed
optional
422.Лимиты
withdraw_limit_exceeded
optional
max_per_tx, а вместе с выведенным за последние 24 часа - daily_limit. Окно скользящее, поэтому лимит освобождается постепенно. 422.Нет незавершённых проверок
aml_screening_in_progress
optional
409.Хватает средств
insufficient_funds
optional
402.Адрес назначения чист
aml_blocked
optional
customer.withdrawal.blocked. 422.| Name | Type | Required | Description |
|---|---|---|---|
Вывод включён
|
withdraw_disabled
|
optional |
Вывод средств клиентов доступен вашей учётной записи. 403.
|
Клиент активен
|
customer_blocked
|
optional |
Клиент не заблокирован ни вами, ни комплаенсом. 409.
|
Монета доступна
|
coin_not_allowed
|
optional |
Монета поддерживается, разрешена вашей учётной записи и допускает отправку. 422.
|
Сумма корректна
|
amount_below_minimum
|
optional |
Сумма должна быть положительной и не ниже min_withdraw монеты. Ноль или отрицательное значение отклоняется кодом invalid_request, положительная сумма ниже минимума - кодом amount_below_minimum. 422.
|
Адрес валиден
|
invalid_address
|
optional |
Формат адреса соответствует указанной сети. 422.
|
Адрес внешний
|
coin_not_allowed
|
optional |
Адрес получателя не принадлежит платформе. Переводы внутри платформы делаются операциями charge / payout, а не он-чейн выводом. 422.
|
Лимиты
|
withdraw_limit_exceeded
|
optional |
Сумма не превышает max_per_tx, а вместе с выведенным за последние 24 часа - daily_limit. Окно скользящее, поэтому лимит освобождается постепенно. 422.
|
Нет незавершённых проверок
|
aml_screening_in_progress
|
optional |
По клиенту нет поступлений, ожидающих комплаенс-вердикта. Повторите позже. 409.
|
Хватает средств
|
insufficient_funds
|
optional |
Доступного остатка хватает на сумму вместе с обеими комиссиями. 402.
|
Адрес назначения чист
|
aml_blocked
|
optional |
Синхронная комплаенс-проверка адреса получателя. Отказ приходит до списания, уходит вебхук customer.withdrawal.blocked. 422.
|
Стадии заявки
Поле state
processing
status: pending
optional
sending
status: pending
optional
sent
status: pending
optional
tx_hash есть хеш, идёт набор подтверждений. Вебхук customer.withdrawal.sent.confirmed
status: confirmed
optional
customer.withdrawal.confirmed.failed
status: failed
optional
customer.withdrawal.failed.| Name | Type | Required | Description |
|---|---|---|---|
processing
|
status: pending
|
optional | Заявка принята, деньги с клиента списаны, отправки в сеть ещё не было. |
sending
|
status: pending
|
optional | Команда на отправку отдана, результат ещё не известен. |
sent
|
status: pending
|
optional |
Транзакция ушла в сеть, в tx_hash есть хеш, идёт набор подтверждений. Вебхук customer.withdrawal.sent.
|
confirmed
|
status: confirmed
|
optional |
Сеть подтвердила. Терминальная стадия. Вебхук customer.withdrawal.confirmed.
|
failed
|
status: failed
|
optional |
Отправить не удалось. Сумма, комиссия платформы и ваша надбавка возвращены клиенту, надбавка сторнирована с мастер-счёта. Терминальная стадия. Вебхук customer.withdrawal.failed.
|
confirmed и failed. Все остальные стадии означают «ещё в работе» - не разблокируйте заказ и не начисляйте бонусы раньше терминальной стадии.
/api/v1/customers/{uuid}/wallet/withdrawals/{withdrawalId}
Статус заявки на вывод
{withdrawalId} - значение data.id из ответа на создание заявки. Возвращает тот же объект транзакции с актуальными status и state.Расчёты с клиентом: charge и payout
Внутренние расчёты между вами и клиентом: мгновенные, без он-чейн транзакции и без сетевых комиссий. charge списывает с клиента в вашу пользу и зачисляет сумму на мастер-счёт, payout - обратная операция за ваш счёт.
/api/v1/customers/{uuid}/wallet/charge
Списать с клиента в свою пользу
/api/v1/customers/{uuid}/wallet/payout
Выплатить клиенту со своего мастер-счёта
Заголовки
Idempotency-Key
string
required
200 и duplicate: true, с другими - 409.| Name | Type | Required | Description |
|---|---|---|---|
Idempotency-Key
|
string
|
required |
Обязателен для обеих операций. Правила те же, что у вывода: повтор с теми же параметрами - 200 и duplicate: true, с другими - 409.
|
"+10", "10." отклоняются кодом 422.'],
['name' => 'reason', 'type' => 'string', 'desc' => 'Назначение операции для ваших отчётов, до 240 символов. Попадает в описание строки мастер-счёта.'],
]" />
Responses
{
"data": {
"id": "5d20fa71-9a4c-4b1e-8f77-1c3e6a0b9d24",
"network": "TRON",
"asset": "USDT",
"direction": "out",
"amount": "12.500000000000000000",
"address": "internal:merchant:7",
"counterparty": "Списание в пользу мерчанта",
"tx_hash": null,
"status": "confirmed",
"confirmations": 0,
"aml_status": "skipped",
"frozen": false,
"fee": { "platform": "0.000000000000000000", "merchant": "0.000000000000000000" },
"confirmed_at": "2026-08-17T12:40:55+00:00",
"created_at": "2026-08-17T12:40:55+00:00",
"operation": "charge",
"merchant_balance": "312.5000000000",
"duplicate": false
}
}
{
"error": {
"code": "service_balance_insufficient",
"message": "Недостаточно средств на сервисном счёте. Пополните мастер-счёт.",
"request_id": "req_a1B2c3D4e5F6g7H8i9J0kLmN",
"currency": "USDT",
"required": "50",
"available": "12.4000000000"
}
}
Дополнительные поля ответа
operation
enum
optional
charge или payout.merchant_balance
string
optional
duplicate
bool
optional
true, если это повтор по ранее использованному Idempotency-Key: ответ прежний, денег не двигали. HTTP-код при этом 200, а не 201.| Name | Type | Required | Description |
|---|---|---|---|
operation
|
enum
|
optional |
charge или payout.
|
merchant_balance
|
string
|
optional | Остаток мастер-счёта в валюте операции после проводки. |
duplicate
|
bool
|
optional |
true, если это повтор по ранее использованному Idempotency-Key: ответ прежний, денег не двигали. HTTP-код при этом 200, а не 201.
|
payout, может вывести эти деньги в сеть обычной заявкой - платформа сама обеспечит нужную ликвидность на его адресе, дополнительных действий от вас не требуется.
Песочница
/api/v1/test/customers/{uuid}/simulate-deposit
Сымитировать поступление на кошелёк клиента (только sk_test_)
customer.deposit.detected, комплаенс-проверка. Боевым ключом эндпоинт отвечает 404.Body
coin
string
required
network
string
optional
amount
number
required
| Name | Type | Required | Description |
|---|---|---|---|
coin
|
string
|
required | Тикер монеты. |
network
|
string
|
optional | Сеть, если тикер существует в нескольких. |
amount
|
number
|
required | Сумма поступления, больше нуля. |
Responses
{
"data": {
"id": "1e7b6a54-0c2f-4b39-9d81-6f2a4c8e0b17",
"network": "TRON",
"asset": "USDT",
"direction": "in",
"amount": "100.000000000000000000",
"address": "SBXTRON4F2A9C1E7B6A540C2F4B399D816F2A4C",
"counterparty": "SBXSENDER",
"tx_hash": "sbx:1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d",
"status": "pending",
"confirmations": 0,
"aml_status": "pending",
"frozen": false,
"fee": { "platform": "0.000000000000000000", "merchant": "0.000000000000000000" },
"confirmed_at": null,
"created_at": "2026-08-17T12:45:00+00:00"
},
"sandbox": true
}
Подробнее об отличиях окружений - Sandbox.
Права ключа
Чтение (адреса, балансы, журнал, статус заявки, предпросмотр) доступно любому ключу вашей учётной записи. Операции, двигающие деньги - вывод, charge, payout - требуют роли владельца или администратора; ключ сотрудника получит на них 403 forbidden.
Лимиты частоты
Запросов в минуту
Чтение (балансы, адреса, журнал, статус, quote)
120
optional
Выдача адреса, симуляция депозита
30
optional
30 в минуту делятся между выдачей адреса, симуляцией депозита и блокировкой/разблокировкой клиента - это не 30 на каждый эндпоинт.charge / payout
30
optional
Вывод
6
optional
Принудительная сверка
6
optional
| Name | Type | Required | Description |
|---|---|---|---|
Чтение (балансы, адреса, журнал, статус, quote)
|
120
|
optional | Общая корзина на все читающие вызовы кошельков. |
Выдача адреса, симуляция депозита
|
30
|
optional |
Общая корзина мутирующих вызовов: эти 30 в минуту делятся между выдачей адреса, симуляцией депозита и блокировкой/разблокировкой клиента - это не 30 на каждый эндпоинт.
|
charge / payout
|
30
|
optional | Своя корзина расчётов. |
Вывод
|
6
|
optional | Самая узкая корзина: каждый вызов двигает деньги в сеть. |
Принудительная сверка
|
6
|
optional | Аварийный инструмент, не для регулярного опроса. |
При превышении приходит 429 rate_limited с заголовком Retry-After. Корзины независимы: частый опрос балансов не мешает вызвать вывод.
Коды ошибок раздела
wallets_disabled
403
optional
withdraw_disabled
403
optional
forbidden
403
optional
idempotency_key_required
400
optional
Idempotency-Key.invalid_request
422
optional
0 или меньше.coin_not_allowed
422
optional
amount_below_minimum
422
optional
invalid_address
422
optional
withdraw_limit_exceeded
422
optional
aml_blocked
422
optional
aml_screening_in_progress
409
optional
customer_blocked
409
optional
conflict
409
optional
Idempotency-Key уже использован с другими параметрами.insufficient_funds
402
optional
service_balance_insufficient
402
optional
payout). Ответ содержит currency, required и available.service_unavailable
503
optional
| Name | Type | Required | Description |
|---|---|---|---|
wallets_disabled
|
403
|
optional | Крипто-кошельки клиентов недоступны вашей учётной записи. |
withdraw_disabled
|
403
|
optional | Вывод средств клиентов сейчас недоступен. |
forbidden
|
403
|
optional | У ключа нет прав на операцию с деньгами (роль сотрудника). |
idempotency_key_required
|
400
|
optional |
Не передан обязательный заголовок Idempotency-Key.
|
invalid_request
|
422
|
optional |
Ошибка валидации запроса, например сумма вывода 0 или меньше.
|
coin_not_allowed
|
422
|
optional | Монета или сеть недоступны, либо адрес получателя принадлежит платформе. |
amount_below_minimum
|
422
|
optional | Сумма меньше минимальной для этой монеты. |
invalid_address
|
422
|
optional | Адрес не соответствует формату указанной сети. |
withdraw_limit_exceeded
|
422
|
optional | Превышен лимит на операцию или суточный лимит клиента. |
aml_blocked
|
422
|
optional | Адрес назначения отклонён комплаенс-проверкой. |
aml_screening_in_progress
|
409
|
optional | По клиенту идёт проверка поступления - повторите позже. |
customer_blocked
|
409
|
optional | Клиент заблокирован, операции по нему запрещены. |
conflict
|
409
|
optional |
Idempotency-Key уже использован с другими параметрами.
|
insufficient_funds
|
402
|
optional | На счёте клиента не хватает средств с учётом комиссий. |
service_balance_insufficient
|
402
|
optional |
Не хватает средств на мастер-счёте (актуально для payout). Ответ содержит currency, required и available.
|
service_unavailable
|
503
|
optional | Контур временно недоступен - повторите позже. |
Полный реестр и формат конверта - Error Codes.
Примеры кода
KEY="sk_live_..."
B="https://fin-os.io/api/v1"
UUID="5f8d7a3c-1234-4567-89ab-cdef01234567"
# 1. Выдать клиенту адрес в TRON
curl -X POST $B/customers/$UUID/wallet/addresses \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"chain": "TRON"}'
# 2. Балансы клиента
curl -X GET $B/customers/$UUID/wallet -H "Authorization: Bearer $KEY"
# 3. Предпросмотр вывода
curl -G $B/customers/$UUID/wallet/withdraw/quote \
-H "Authorization: Bearer $KEY" \
--data-urlencode "coin=USDT" \
--data-urlencode "network=TRON" \
--data-urlencode "address=TWd4WrZ9wn84f5x1hZhL4DHvk738ns5jwb" \
--data-urlencode "amount=100"
# 4. Вывод (Idempotency-Key обязателен)
curl -X POST $B/customers/$UUID/wallet/withdraw \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: wd-2026-08-17-0001" \
-d '{"coin":"USDT","network":"TRON","address":"TWd4WrZ9wn84f5x1hZhL4DHvk738ns5jwb","amount":"100"}'
# 5. Статус заявки
curl -X GET $B/customers/$UUID/wallet/withdrawals/$WITHDRAWAL_ID \
-H "Authorization: Bearer $KEY"
# 6. Списать с клиента комиссию сервиса
curl -X POST $B/customers/$UUID/wallet/charge \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: chg-2026-08-17-0001" \
-d '{"coin":"USDT","network":"TRON","amount":"12.5","reason":"Абонентская плата за август"}'
const B = 'https://fin-os.io/api/v1';
const KEY = process.env.FINOS_SECRET_KEY;
const H = { 'Authorization': `Bearer ${KEY}`, 'Content-Type': 'application/json' };
async function call(path, opts = {}) {
const res = await fetch(`${B}${path}`, { ...opts, headers: { ...H, ...(opts.headers || {}) } });
const body = await res.json();
if (!res.ok) throw Object.assign(new Error(body.error.message), body.error);
return body;
}
// Адрес пополнения
const address = (await call(`/customers/${uuid}/wallet/addresses`, {
method: 'POST', body: JSON.stringify({ chain: 'TRON' }),
})).data;
// Предпросмотр: показываем клиенту итоговое списание
const q = new URLSearchParams({ coin: 'USDT', network: 'TRON', address: dest, amount });
const quote = (await call(`/customers/${uuid}/wallet/withdraw/quote?${q}`)).data;
if (!quote.allowed) throw new Error(quote.reason.error);
console.log('спишется', quote.total_debit, 'получит', quote.receives);
// Вывод. Ключ идемпотентности - ваш идентификатор операции, не случайный на каждый ретрай
const withdrawal = (await call(`/customers/${uuid}/wallet/withdraw`, {
method: 'POST',
headers: { 'Idempotency-Key': `wd-${orderId}` },
body: JSON.stringify({ coin: 'USDT', network: 'TRON', address: dest, amount }),
})).data;
// Терминальные стадии: confirmed и failed. Остальное - «ещё в работе»
console.log(withdrawal.status, withdrawal.state); // pending processing
use Illuminate\Support\Facades\Http;
$base = 'https://fin-os.io/api/v1';
$api = Http::withToken(config('services.finos.secret_key'))->acceptJson()->baseUrl($base);
// Адрес пополнения (идемпотентно)
$address = $api->post("/customers/{$uuid}/wallet/addresses", ['chain' => 'TRON'])->json('data');
// Предпросмотр вывода
$quote = $api->get("/customers/{$uuid}/wallet/withdraw/quote", [
'coin' => 'USDT',
'network' => 'TRON',
'address' => $destination,
'amount' => '100',
])->json('data');
if (! $quote['allowed']) {
throw new \RuntimeException($quote['reason']['error']);
}
// Вывод: ключ идемпотентности привязан к вашей операции
$response = $api->withHeaders(['Idempotency-Key' => "wd-{$orderId}"])
->post("/customers/{$uuid}/wallet/withdraw", [
'coin' => 'USDT',
'network' => 'TRON',
'address' => $destination,
'amount' => '100',
]);
if ($response->failed()) {
$err = $response->json('error');
match ($err['code']) {
'insufficient_funds' => notifyTopUp($uuid),
'withdraw_limit_exceeded' => showLimits($quote),
'aml_blocked' => sendToCompliance($destination),
'aml_screening_in_progress' => retryLater(),
default => report($err),
};
}
$withdrawal = $response->json('data'); // status=pending, state=processing
import os, requests
B = 'https://fin-os.io/api/v1'
KEY = os.environ['FINOS_SECRET_KEY']
H = {'Authorization': f'Bearer {KEY}'}
# Адрес пополнения
address = requests.post(f'{B}/customers/{uuid}/wallet/addresses',
headers=H, json={'chain': 'TRON'}).json()['data']
# Журнал: только поступления, подтверждённые сетью
txs = requests.get(f'{B}/customers/{uuid}/wallet/transactions',
headers=H,
params={'direction': 'in', 'status': 'confirmed', 'per_page': 50}
).json()
# Вывод с ключом идемпотентности
r = requests.post(
f'{B}/customers/{uuid}/wallet/withdraw',
headers={**H, 'Idempotency-Key': f'wd-{order_id}'},
json={'coin': 'USDT', 'network': 'TRON', 'address': destination, 'amount': '100'},
)
if r.status_code in (200, 201):
wd = r.json()['data']
# duplicate=True означает повтор ключа: деньги уже были списаны первым вызовом
print(wd['id'], wd['status'], wd['state'], wd['duplicate'])
else:
err = r.json()['error']
print(err['code'], err['message'], err['request_id'])