Выплаты

Создание заявки на вывод

Создайте заявку через API с теми же реквизитами и правилами расчёта, что в личном кабинете

POST/integration/payouts

Полный адрес: https://api.cashera.cash/api/v1/integration/payouts. Заявка создаётся со статусом pending, а сумма резервируется на балансе мерчанта. Ответ 201 Created подтверждает создание заявки, а не перевод получателю. Дальше она проходит обычную обработку выплат.

Перед первым запросом

  1. Выберите способ указания получателя: передайте реквизиты в destination либо UUID ранее сохранённого кошелька в wallet_uuid
  2. Укажите HTTPS-адрес уведомлений в настройках мерчанта. Выплата использует этот callback_url
  3. Подготовьте API-ключ и секрет мерчанта. Если настроен список разрешённых IP, добавьте в него адрес своего сервера
  4. Получите предварительный расчёт для тех же суммы, валюты и получателя

Код Telegram не передаётся при каждом создании заявки через API: запрос авторизуется ключом и HMAC-подписью. Для destination кошелёк в личном кабинете не создаётся; реквизиты сохраняются только в заявке. Сохранение кошельков в ЛК по-прежнему требует Telegram-подтверждения.

Валюта и получатель

  • RUB или EUR → USDT в выбранной сети: TRON, Ethereum, BNB Smart Chain, Base, Avalanche, Polygon, Solana или TON. Для сетей, кроме TRON, доступность направления дополнительно проверяется при создании
  • RUB → карта МИР, если выплаты на карты включены для мерчанта. EUR → карта не поддерживается

currency — валюта списания с баланса, а не монета получателя. Для вывода USDT укажите RUB или EUR; значение USDT в этом поле не принимается.

Подписывайте запрос на своём сервере

Нужны X-Api-Key, X-Timestamp и X-Signature. Обычного API-ключа недостаточно. Подпись вычисляется по точному телу запроса и пути /api/v1/integration/payouts. Алгоритм и примеры подписи. Секрет нельзя помещать в браузерный код.

Параметры запроса

ПолеТипОписание
amountобязательноеintegerПолная сумма списания, включая удерживаемую комиссию, в минимальных единицах валюты. 250000 = 2 500 ₽ или 2 500 €. Положительное целое число; дополнительно действуют минимальная сумма USDT и лимиты карт
currencyобязательноеstringБаланс списания: RUB или EUR
external_idобязательноеstringВаш уникальный номер заявки в пределах мерчанта, до 255 символов. Сохраните его до отправки запроса для безопасного повтора
wallet_uuiduuidUUID сохранённых реквизитов именно этого мерчанта. Обязателен, если нет destination. Одновременно передавать оба варианта нельзя
destinationobjectПолучатель без предварительного сохранения. Обязателен, если нет wallet_uuid. Разрешены только type, address и memo
destination.typestringОбязательный тип: usdt_trc20, usdt_erc20, usdt_bep20, usdt_base, usdt_avalanche, usdt_polygon, usdt_solana, usdt_ton или card
destination.addressstringОбязательный адрес выбранной сети или 16-значный номер карты МИР. Проверяются формат и контрольная сумма там, где она предусмотрена. До 255 символов
destination.memostring | nullMemo до 255 символов, только для TON и Solana. Укажите его, если этого требует получатель
expected_usdt_amount_microintegerДля вывода в USDT: минимально допустимая сумма получения, например 25000000 = 25 USDT. Можно передать usdt_amount_micro из расчёта. Если новый расчёт меньше этого значения, вернётся 409, заявка не создастся. Не применяется к картам

Не передавайте metadata и callback_url в теле запроса: эти поля заполняет Cashera. Передача значений в них отклоняется с 422.

Без сохранённого кошелька

{
"amount": 250000,
"currency": "RUB",
"external_id": "withdraw-direct-001",
"destination": {
"type": "usdt_trc20",
"address": "TTt2x7Z7Gg3WpAqvgYqFK3ZQTE5CYL8zSQ"
}
}

Реквизиты в примерах тестовые: перед отправкой замените их на реквизиты получателя. Для прямой выплаты поле wallet в ответе будет null, а destination содержит снимок реквизитов заявки. Старые запросы с wallet_uuid, формат ответов и событие payout.status_updated остаются совместимыми.

Пример создания

# Задайте CASHERA_API_KEY, CASHERA_API_SECRET и CASHERA_WALLET_UUID в окружении сервера
# Выполняйте один и тот же логический вывод с неизменным external_id
body=$(printf '{"amount":250000,"currency":"RUB","external_id":"withdraw-001","wallet_uuid":"%s"}' "$CASHERA_WALLET_UUID")
timestamp=$(date +%s)
export CASHERA_SIGNING_BODY="$body" CASHERA_SIGNING_TIMESTAMP="$timestamp"
signature=$(python3 - <<'PY'
import hashlib, hmac, os
body = os.environ["CASHERA_SIGNING_BODY"].encode("utf-8")
parts = [os.environ["CASHERA_SIGNING_TIMESTAMP"], "POST",
"/api/v1/integration/payouts", hashlib.sha256(body).hexdigest()]
print(hmac.new(os.environ["CASHERA_API_SECRET"].encode("utf-8"),
"\n".join(parts).encode("utf-8"), hashlib.sha256).hexdigest())
PY
)
curl --fail-with-body --request POST 'https://api.cashera.cash/api/v1/integration/payouts' \
--header "X-Api-Key: $CASHERA_API_KEY" \
--header "X-Timestamp: $timestamp" \
--header "X-Signature: $signature" \
--header 'Content-Type: application/json' \
--data-binary "$body"

Числа комиссии и конвертации в примере условные. При указанном расчёте резервируется 2 500 ₽, удерживается 150 ₽, а 2 350 ₽ конвертируются в 24,1815 USDT. Используйте значения своего ответа. Полная структура описана в объекте выплаты.

Комиссии и баланс

amount целиком переводится из доступного остатка в резерв выплат.withdrawal_fee_amount — удержанная комиссия в валюте баланса,net_amount = amount − withdrawal_fee_amount. Для USDT сумма получателю находится в payout_usdt_amount_micro (1 USDT = 1 000 000). Для карт используйте card_payout.net_card_rub_amount в копейках: комиссия учитывает настройки провайдера и FX, зачисление округляется вниз до целого рубля. Не прибавляйте комиссию к amount повторно.

При failed резерв освобождается полностью. Если к этому времени есть задолженность, возврат сначала погашает её; при заморозке остаток возвращается на замороженный баланс. Без этих ограничений средства снова становятся доступными.

Повтор запроса и проверка результата

  • Повтор с теми же external_id, amount, currency и получателем (wallet_uuid либо type/address/memo в destination) возвращает существующую заявку с 201, без повторного резервирования
  • Изменение суммы, валюты, адреса, сети, memo или способа задания получателя с уже использованным external_id возвращает 409. Для новой заявки нужен новый идентификатор
  • При таймауте не создавайте новый external_id: повторите исходное тело со свежими timestamp и подписью либо найдите заявку в истории по external_id
  • Следите за статусом по UUID: pending → processing → completed или failed. Заявка может быть отклонена и из pending

Уведомления приходят на callback_url мерчанта с событием payout.status_updated. Проверяйте подпись уведомления и обрабатывайте повторы идемпотентно. Изменение expected_usdt_amount_micro не пересчитывает уже созданную заявку.

Ошибки

ПолеТипОписание
401UnauthorizedНеверный ключ, подпись или время запроса
403ForbiddenМерчант отключён, баланс заморожен, IP не разрешён, секрет не настроен либо выплаты на карту не подключены
404Not FoundКошелёк не найден или принадлежит другому мерчанту
409ConflictДругие параметры с тем же external_id, сумма USDT стала меньше expected_usdt_amount_micro либо действует ограничение сверки баланса. Проверяйте message; не создавайте новую заявку вслепую
422Unprocessable EntityОшибки полей, нет HTTPS callback_url, недостаточно доступных средств, неподдерживаемая пара валюты и кошелька, недоступная сеть или нарушение лимитов выплаты
429Too Many RequestsПревышен лимит запросов. Повторите позже с тем же external_id
502 / 503Временная недоступностьНе удалось получить курс или проверить направление. Сохраните исходный external_id и проверьте статус перед повтором