Sign in
Конверты/Convert API

Convert API

Конвертация криптовалют напрямую из баланса мерчанта — живая котировка и исполнение по рыночной цене.

Convert API позволяет обменивать валюты внутри баланса вашего мерчанта по текущей рыночной цене — тот же движок, что работает во вкладке Обмен в личном кабинете, теперь доступный из вашего бэкенда.

Ручки Convert подписываются вашим обычным API-ключом — тем же, что используется для запросов Payment API, а не ключом Payout. Исполнение конверта сразу списывает и зачисляет баланс мерчанта, поэтому относитесь к этому ключу с той же осторожностью, что и к любому денежному credential.

Получить цену конверта

Возвращает индикативную котировку конверта по текущей рыночной цене — эффективный курс и итоговые суммы. Ничего не списывается и не резервируется; вызывайте сколько угодно раз перед исполнением.

POST/v1/convert/price

Параметры котировки

ПолеТипОбязательноОписаниеЗначение
from_currencystringдаВалюта, из которой конвертируем
to_currencystringдаВалюта, в которую конвертируем. Должна отличаться от from_currency
amountdecimalдаСумма конвертации, больше 0
amount_typestringдаК какой стороне относится amount

amount_type=from — потратить ровно amount в from_currency. amount_type=to — получить ровно amount в to_currency.

🟢 200 OK · application/json

JSON
{
  "state": 0,
  "result": {
    "success": true,
    "from_currency": "BTC",
    "to_currency": "USDT",
    "amount_type": "from",
    "from_amount": "0.01000000",
    "to_amount": "947.86690000",
    "effective_rate": "94786.69000000",
    "from_amount_usd": "947.87",
    "to_amount_usd": "947.87"
  }
}

Поля ответа

ПолеТипОписание
successbooleanУспешно ли рассчитана котировка
from_currencystringИсходная валюта
to_currencystringЦелевая валюта
amount_typestringПовторяет amount_type из запроса
from_amountstringСумма, которая будет списана в from_currency
to_amountstringСумма, которая будет зачислена в to_currency
effective_ratestringКурс, применённый к этой котировке — 1 единица from_currency в to_currency (уже включает ценообразование платформы)
from_amount_usdstring | nullUSD-эквивалент from_amount
to_amount_usdstring | nullUSD-эквивалент to_amount
  • Котировка только индикативная — рыночная цена может измениться между запросом котировки и исполнением.
  • Ничего не списывается и не резервируется этим вызовом.
Credentials
RequestPOST/v1/convert/price
curl -X POST https://api.2328.io/api/v1/convert/price \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyShop/1.0 (+https://myshop.example)" \
  -H "project: YOUR_PROJECT_UUID" \
  -H "sign: YOUR_HMAC_SIGNATURE"
Response
Click Try it to see the response here.

Исполнить конверт

Исполняет конверт по текущей рыночной цене и обновляет баланс мерчанта. Отдельного шага «подтвердить котировку» нет — вызывайте эту ручку напрямую с той суммой, которую хотите конвертировать.

POST/v1/convert

Идемпотентность. Повтор ровно того же запроса (те же from_currency, to_currency, amount, amount_type) в течение примерно минуты после первого вызова вернёт уже существующий конверт вместо создания второго. После истечения этого окна идентичный запрос будет воспринят как новый конверт — не ретраьте вслепую при таймауте, сначала проверьте результат предыдущего вызова.

Эта ручка ограничена 10 запросами в минуту на вызывающего — жёстче общего лимита API, — потому что каждый вызов двигает реальный баланс.

Параметры конверта

ПолеТипОбязательноОписаниеЗначение
from_currencystringдаВалюта, из которой конвертируем
to_currencystringдаВалюта, в которую конвертируем. Должна отличаться от from_currency
amountdecimalдаСумма конвертации, больше 0
amount_typestringдаК какой стороне относится amount

🟢 200 OK · application/json

JSON
{
  "state": 0,
  "result": {
    "id": 12345,
    "type": "manual",
    "status": "completed",
    "from_currency": "BTC",
    "to_currency": "USDT",
    "from_amount": "0.01000000",
    "requested_from_amount": "0.01000000",
    "refund_amount": null,
    "to_amount": "947.86690000",
    "exchange_rate": "94786.69000000",
    "fee_amount": "0.00000000",
    "from_amount_usd": "947.87",
    "to_amount_usd": "947.87",
    "processed_at": "2026-01-20T15:30:24Z",
    "created_at": "2026-01-20T15:30:22Z"
  }
}

Поля ответа

ПолеТипОписание
idintID конверт-ордера, присвоенный системой
typestringВсегда manual для этого API
statusstringТекущий статус (см. «Статусы конверта» ниже)
from_currencystringИсходная валюта
to_currencystringЦелевая валюта
from_amountstringСписанная сумма в from_currency
requested_from_amountstring | nullЗапрошенная вами исходная сумма при amount_type = from. null при amount_type = to
refund_amountstring | nullЧасть предварительно списанной суммы, возвращённая вам после частичного исполнения. null, если ордер исполнился полностью
to_amountstringЗачисленная сумма в to_currency
exchange_ratestringКурс, фактически применённый к этой конвертации — 1 единица from_currency в to_currency (уже включает ценообразование платформы)
fee_amountstringКомиссия платформы по этой конвертации, в from_currency или to_currency в зависимости от направления сделки. Уже учтена в exchange_rate — показана для прозрачности
from_amount_usdstring | nullUSD-эквивалент from_amount
to_amount_usdstring | nullUSD-эквивалент to_amount
processed_atstring (ISO 8601) | nullКогда конвертация завершила исполнение. null, пока она в обработке
created_atstring (ISO 8601)Когда был создан конверт-ордер

Статусы конверта

СтатусОписание
pendingСоздан, ещё не отправлен на биржу
processingБаланс заблокирован, ордер выставлен на биржу
completedПолностью исполнен — to_amount зачислен на ваш баланс
failedНе удалось исполнить — предварительно списанная сумма возвращена автоматически
partially_completedТолько для валютных пар без прямого рынка (маршрутизация через промежуточную валюту): первый хоп исполнился, второй — нет. Вам зачислена промежуточная валюта вместо to_currency — сконвертируйте её ещё раз, чтобы достичь исходной цели
RequestPOST/v1/convert
curl -X POST https://api.2328.io/api/v1/convert \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyShop/1.0 (+https://myshop.example)" \
  -H "project: YOUR_PROJECT_UUID" \
  -H "sign: YOUR_HMAC_SIGNATURE"
Response
Click Try it to see the response here.

Ошибки

При ошибке ответ содержит state: 1 и error_code — общие для /v1/convert/price и /v1/convert:

🔴 422 / 400 · application/json

JSON
{
  "state": 1,
  "error_code": "amount_too_small",
  "errors": {
    "amount": "Amount is too small for this conversion. Please increase the amount and try again."
  }
}
error_codeHTTP-статусОписание
validation_failed422Неверные или отсутствующие параметры, либо отказ по бизнес-правилу (например, недостаточно баланса) — детали в поле errors
amount_too_small422amount меньше минимального торгуемого размера для этой валютной пары
convert_unavailable400Конвертацию не удалось исполнить прямо сейчас (недоступны рыночные данные или нет маршрута между двумя валютами) — повторите чуть позже
internal_error400Непредвиденная ошибка сервера при обработке запроса

Автоматическая конвертация входящих платежей

Автоконвертация — настройка проекта для входящих платежей и пополнений статических кошельков. Она задаётся в панели управления мерчанта, а не дополнительными полями запроса /v1/payment. Каждое правило связывает одну или несколько исходных валют с целевой валютой.

После успешной конвертации данные платежа и webhook-уведомления мерчанта могут содержать:

JSON
{
  "payment_amount": "0.14800000",
  "merchant_amount": "0.146520000000000000",
  "payer_currency": "XMR",
  "convert": {
    "to_currency": "USDT",
    "commission": "0.09000000",
    "rate": "323.21000000",
    "amount": "47.262015740000000000"
  }
}

Эти суммы намеренно относятся к разным этапам обработки:

  • payment_amount — сумма, обнаруженная в блокчейне, в исходной валюте платежа;
  • merchant_amount — чистая сумма мерчанта в исходной валюте до конвертации;
  • convert.amount — сумма, зачисленная в валюте convert.to_currency;
  • convert.rate и convert.commission — фактический результат выполненной конвертации, а не исходные данные для локального пересчёта.

Отсутствие convert — допустимый результат: конвертация могла ещё не завершиться, не быть настроена для этой исходной валюты либо завершиться зачислением в исходной валюте. Не рассчитывайте целевую сумму самостоятельно по /exchange-rates или публичному рыночному курсу.

Сбой автоконвертации и резервный сценарий

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

  • Депозиты ниже глобального или проектного минимума не проходят конвертацию и зачисляются в исходной валюте.
  • После временного сбоя система может повторить попытку асинхронно.
  • Крупные или неликвидные депозиты после исчерпания попыток могут быть зачислены в исходной валюте.
  • Поэтому платёж может быть корректно получен, даже если конвертация в целевую валюту не состоялась.

Сначала сохраните подтверждённый платёж, затем определите фактически зачисленную валюту по данным платежа, необязательному блоку convert и балансам мерчанта. Не задерживайте обработку подтверждающего webhook из-за ожидания собственной аналитики или уведомлений.

Приёмочные тесты автоконвертации

Как минимум проверьте: успешную прямую конвертацию; конвертацию через промежуточную валюту или несколько переходов; сумму ниже минимальной; повтор после временного сбоя; зачисление в исходной валюте; недоплату; переплату; дубликат webhook; отсутствие convert; сверку после неоднозначного тайм-аута.

Нестандартные ситуации при ручной конвертации

  • /v1/convert/price возвращает ориентировочный предварительный расчёт; движение рынка может изменить фактический результат исполнения.
  • amount_type: from фиксирует сумму исходной валюты, а amount_type: to запрашивает сумму целевой валюты. Не меняйте это значение между показом экрана подтверждения и отправкой запроса.
  • Если для пары нет прямого рынка, обмен может пройти через промежуточную валюту. Статус partially_completed означает, что завершён только один этап и средства находятся в промежуточной валюте.
  • Если запрос завершился тайм-аутом, сначала выполните сверку и только затем повторяйте операцию: рыночный ордер мог исполниться, даже если HTTP-ответ потерян.
  • Статус failed требует сверки и не даёт права самостоятельно проводить компенсирующую запись по локальному балансу; учёт списания и возврата ведёт платформа.