Base URL: https://api.paysoutsfi.io
Каждый запрос требует четыре заголовка:
| Заголовок | Описание |
|---|---|
X-Api-Key | Идентификатор ключа (key_id) |
X-Timestamp | Unix-время в секундах. Допуск ±300 сек от времени сервера |
X-Nonce | Случайная строка, уникальная для каждого запроса (в течение 5 мин) |
X-Signature | HMAC-SHA256 подпись (hex) |
METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
Поля соединяются через символ перевода строки \n. Тело — точная строка байт запроса (без изменений).
import crypto from "crypto";
function sign(secret, method, path, ts, nonce, body = "") {
const msg = [method.toUpperCase(), path, String(ts), String(nonce), body].join("\n");
return crypto.createHmac("sha256", secret).update(msg).digest("hex");
}
import hmac, hashlib
def sign(secret, method, path, ts, nonce, body=""):
msg = "\n".join([method.upper(), path, str(ts), str(nonce), body])
return hmac.new(secret.encode(), msg.encode(), hashlib.sha256).hexdigest()
nonce принимается только один раз в течение 5 минут — защита от replay-атак.Создаёт заявку на пополнение или вывод. Если заявка с таким merchant_request_id уже существует — возвращает её без создания новой ("created": false).
{
"merchant_request_id": "order-12345",
"type": "deposit",
"user_tg_id": 123456789,
"account_id": "player_42",
"amount_rub": 1500,
"method_key": "card",
"meta": {"note": "опционально"}
}
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
merchant_request_id | string | да | Уникальный ID заявки на вашей стороне (1–64 символа) |
type | string | да | deposit или withdraw |
user_tg_id | int | да | Telegram ID пользователя |
account_id | string | да | ID аккаунта пользователя в вашей системе |
amount_rub | int | да | Сумма в рублях, больше 0 |
method_key | string | да | Метод: sbp, card |
meta | object | нет | Произвольные данные |
{
"request_id": 42,
"status": "waiting_requisites",
"terminal_id": 10,
"method_key": "card",
"amount_rub": 1500,
"created": true
}
"created": false — заявка уже существует, повторное уведомление трейдеру не отправляется. Используйте новый merchant_request_id для каждой новой заявки.Возвращает текущий статус заявки. Доступны только заявки вашего мерчанта.
{
"request_id": 42,
"status": "approved",
"type": "deposit",
"terminal_id": 10,
"method_key": "card",
"amount_rub": 1500,
"commission_amount": 75.0,
"requisites_sent": true,
"proof_submitted": true,
"created_at": "2025-01-15 12:00:00",
"updated_at": "2025-01-15 12:05:30"
}
withdraw_approved → approved, withdraw_rejected → rejected, withdraw_pending → pending.Подтвердить или отклонить заявку на вывод. Доступно только для статуса pending (вывод ожидает решения).
{
"action": "approve",
"reason": null
}
| Поле | Тип | Описание |
|---|---|---|
action | string | approve или reject |
reason | string | Причина отказа (опционально, для reject) |
{
"request_id": 42,
"status": "approved",
"action": "approve"
}
Список транзакций мерчанта с фильтрами по дате и пользователю.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
date_from | string | — | Начало периода, формат YYYY-MM-DD |
date_to | string | — | Конец периода, формат YYYY-MM-DD |
user_tg_id | int | — | Фильтр по Telegram ID пользователя |
limit | int | 50 | Количество записей (1–500) |
offset | int | 0 | Смещение для пагинации |
{
"transactions": [
{
"request_id": 42,
"type": "deposit",
"status": "approved",
"user_tg_id": 123456789,
"account_id": "player_42",
"method_key": "card",
"amount_rub": 1500,
"commission_amount": 75.0,
"terminal_id": 10,
"created_at": "2025-01-15 12:00:00",
"updated_at": "2025-01-15 12:05:30"
}
],
"total": 156
}
На каждое изменение статуса на ваш webhook_url отправляется POST-запрос. Набор полей одинаков для всех статусов.
{
"event": "request.status_changed",
"request_id": 42,
"merchant_id": 1,
"type": "deposit",
"user_tg_id": 123456789,
"account_id": "player_42",
"amount_rub": 1500,
"method_key": "card",
"terminal_id": 10,
"payment_submethod": "card",
"commission_amount": 75.0,
"created_at": "2025-01-15 12:00:00",
"status": "approved"
}
При отклонении добавляется поле reason:
{
"status": "rejected",
"reason": "Чек не прошёл проверку",
...
}
| Статус в вебхуке | Событие |
|---|---|
waiting_requisites | Заявка создана, ожидаются реквизиты |
requisites_sent | Реквизиты отправлены пользователю |
proof_submitted | Пользователь отправил чек |
approved | Заявка принята |
rejected | Заявка отклонена (есть поле reason) |
locked | Заявка заблокирована трейдером на 24 часа |
withdraw_pending | Заявка на вывод создана |
withdraw_approved | Вывод подтверждён |
withdraw_rejected | Вывод отклонён |
GET /v1/requests/{id}.Если задан webhook_secret, к каждому запросу добавляются заголовки:
| Заголовок | Описание |
|---|---|
X-Timestamp | Unix-время отправки |
X-Nonce | Случайная строка |
X-Signature | HMAC-SHA256(secret, {ts}.{nonce}.{body}) |
import hmac, hashlib
def verify(secret, body_bytes, ts, nonce, sig):
msg = f"{ts}.{nonce}.{body_bytes.decode()}".encode()
expected = hmac.new(secret.encode(), msg, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig)
import crypto from "crypto";
function verify(secret, body, ts, nonce, sig) {
const msg = `${ts}.${nonce}.${body}`;
const expected = crypto.createHmac("sha256", secret).update(msg).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}
Ссылка для перехода пользователя в бота с вашего сайта. Бот автоматически привяжет заявку к вашему мерчанту и заполнит сумму.
a. Нижнее подчёркивание _ в некоторых Telegram-клиентах склеивается с числами и искажает значения.| Формат | Пример | merchant_id | account_id | amount |
|---|---|---|---|---|
{merchant_id}a{user_id}a{amount} |
6a68595a2010 |
✅ 6 | ✅ 68595 | ✅ 2010 ₽ |
{merchant_id}a{user_id} |
6a68595 |
✅ 6 | ✅ 68595 | — вводится вручную |
{user_id}_{amount} |
68595_2010 |
— | ✅ 68595 | ✅ 2010 ₽ |
{user_id} |
68595 |
— | ✅ 68595 | — вводится вручную |
| Параметр | Описание |
|---|---|
merchant_id | Ваш ID мерчанта. Если передан — вебхуки уходят на ваш webhook_url |
user_id | ID пользователя в вашей системе — записывается в поле account_id заявки |
amount | Сумма пополнения в рублях. Если не передана — пользователь вводит сам |
https://t.me/BOTUSERNAME?start={merchant_id}a{user_id}a{amount}
# Пример:
https://t.me/BOTUSERNAME?start=6a68595a2010
| Статус | Описание |
|---|---|
waiting_requisites | Заявка создана, трейдер ещё не выдал реквизиты |
requisites_sent | Реквизиты отправлены пользователю |
waiting_proof | Пользователь нажал «Оплатил», ожидается чек |
proof_submitted | Чек получен, ожидается решение трейдера |
locked | Заявка заблокирована на 24 часа (спорная ситуация) |
approved | Оплата подтверждена |
rejected | Заявка отклонена |
| Внутренний статус | В API (нормализованный) | Описание |
|---|---|---|
withdraw_pending | pending | Создана, ожидает решения мерчанта |
withdraw_approved | approved | Вывод подтверждён |
withdraw_rejected | rejected | Вывод отклонён |
GET /requests/{id}, POST /requests/{id}/decide, GET /transactions) статусы выводов нормализованы. В вебхуках приходят оригинальные значения.После привязки Telegram-аккаунта к мерчанту открывается доступ к кабинету в боте через кнопку 🏪 Кабинет мерчанта.
key_id и secret активных API-ключей| Кнопка | Действие |
|---|---|
| 📊 Сегодня / 📅 7 дней / 📋 Всё | Статистика за выбранный период |
| 🗂 Заявки | Последние заявки (все статусы) |
| ✅ Одобренные / ❌ Отклонённые | Фильтр в списке заявок |
| 🔑 API ключи | Показать key_id и secret активных ключей |
| 🔗 Webhook | Просмотр и редактирование URL и Secret |
Проверка доступности API. Авторизация не нужна.
{ "ok": true }
| Код | Причина |
|---|---|
400 | Некорректный запрос (например, неверный action в decide) |
401 | Отсутствуют заголовки, неверная подпись или повторный nonce |
403 | Мерчант или API-ключ отключены |
404 | Заявка не найдена или не принадлежит вашему мерчанту |
409 | Нет подходящего терминала для суммы/метода; конфликт статуса при decide |
422 | Невалидное тело запроса (отсутствует обязательное поле) |