/integration/payoutsПолный адрес: https://api.cashera.cash/api/v1/integration/payouts. Заявка создаётся со статусом pending, а сумма резервируется на балансе мерчанта. Ответ 201 Created подтверждает создание заявки, а не перевод получателю. Дальше она проходит обычную обработку выплат.
Перед первым запросом
- Выберите способ указания получателя: передайте реквизиты в
destinationлибо UUID ранее сохранённого кошелька вwallet_uuid - Укажите HTTPS-адрес уведомлений в настройках мерчанта. Выплата использует этот
callback_url - Подготовьте API-ключ и секрет мерчанта. Если настроен список разрешённых IP, добавьте в него адрес своего сервера
- Получите предварительный расчёт для тех же суммы, валюты и получателя
Код 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_uuid | uuid | UUID сохранённых реквизитов именно этого мерчанта. Обязателен, если нет destination. Одновременно передавать оба варианта нельзя |
destination | object | Получатель без предварительного сохранения. Обязателен, если нет wallet_uuid. Разрешены только type, address и memo |
destination.type | string | Обязательный тип: usdt_trc20, usdt_erc20, usdt_bep20, usdt_base, usdt_avalanche, usdt_polygon, usdt_solana, usdt_ton или card |
destination.address | string | Обязательный адрес выбранной сети или 16-значный номер карты МИР. Проверяются формат и контрольная сумма там, где она предусмотрена. До 255 символов |
destination.memo | string | null | Memo до 255 символов, только для TON и Solana. Укажите его, если этого требует получатель |
expected_usdt_amount_micro | integer | Для вывода в 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_idbody=$(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, osbody = 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 не пересчитывает уже созданную заявку.
Ошибки
| Поле | Тип | Описание |
|---|---|---|
401 | Unauthorized | Неверный ключ, подпись или время запроса |
403 | Forbidden | Мерчант отключён, баланс заморожен, IP не разрешён, секрет не настроен либо выплаты на карту не подключены |
404 | Not Found | Кошелёк не найден или принадлежит другому мерчанту |
409 | Conflict | Другие параметры с тем же external_id, сумма USDT стала меньше expected_usdt_amount_micro либо действует ограничение сверки баланса. Проверяйте message; не создавайте новую заявку вслепую |
422 | Unprocessable Entity | Ошибки полей, нет HTTPS callback_url, недостаточно доступных средств, неподдерживаемая пара валюты и кошелька, недоступная сеть или нарушение лимитов выплаты |
429 | Too Many Requests | Превышен лимит запросов. Повторите позже с тем же external_id |
502 / 503 | Временная недоступность | Не удалось получить курс или проверить направление. Сохраните исходный external_id и проверьте статус перед повтором |
