Base URL для запросов: https://api-stage.paysoutsfi.io (в примерах подписи указывайте путь как на проде, например /v1/requests)
Каждый запрос требует четыре заголовка:
| Заголовок | Описание |
|---|---|
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-атак.Создаёт заявку на пополнение (type: "deposit"). Если заявка с таким 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 (интеграция только для пополнений) |
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 для каждой новой заявки.POST /v1/requests возвращается сразу после создания заявки. Исходящий webhook на ваш webhook_url (если задан) отправляется в фоне и не задерживает HTTP-ответ.Возвращает текущий статус заявки. Доступны только заявки вашего мерчанта.
{
"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.Список транзакций мерчанта с фильтрами по дате и пользователю.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
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, webhook_secret (подпись X-Signature) и опционально webhook_key_id — значение для заголовка X-Api-Key исходящих POST на ваш сервер (если приёмник требует идентификатор ключа). Требуется та же авторизация, что и для остальных методов.
{
"webhook_url": "https://example.com/callback",
"webhook_secret": "секрет для проверки подписи",
"webhook_key_id": "key_live_…"
}
Каждый вызов записывает все три поля в БД: передайте актуальные webhook_url, webhook_secret и webhook_key_id; пустое значение или null для поля сбрасывает его. Чтобы не затереть Secret или Key ID при смене только URL, сначала прочитайте текущие настройки из кабинета бота или храните копию у себя. В боте: 🔗 Webhook — правка URL, Secret и Key ID по отдельности.
На каждое изменение статуса на ваш 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 | Вывод отклонён |
POST /v1/requests) и не блокируют HTTP-ответ API. Если ваш сервер недоступен — доставка не повторяется, ориентируйтесь на GET /v1/requests/{id}.X-Api-Key (опционально)Если в настройках мерчанта задан webhook_key_id (в API — PUT /v1/merchant/webhook, в боте — поле Key ID в разделе Webhook), исходящий POST содержит заголовок X-Api-Key с этим значением — для приёмников, которые требуют идентификатор ключа отдельно от подписи.
Если задан 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}, GET /transactions) статусы выводов (если такие заявки есть) нормализованы. В вебхуках приходят оригинальные значения.После привязки Telegram-аккаунта к мерчанту открывается доступ к кабинету в боте через кнопку 🏪 Кабинет мерчанта.
key_id и secret активных API-ключейX-Api-Key для исходящего колбэка)| Кнопка | Действие |
|---|---|
| 📊 Сегодня / 📅 7 дней / 📋 Всё | Статистика за выбранный период |
| 🗂 Заявки | Последние заявки (все статусы) |
| ✅ Одобренные / ❌ Отклонённые | Фильтр в списке заявок |
| 🔑 API ключи | Показать key_id и secret активных ключей |
| 🔗 Webhook | Просмотр и редактирование URL, Secret и Key ID |
Проверка доступности API. Авторизация не нужна.
{ "ok": true }
| Код | Причина |
|---|---|
400 | Некорректный запрос |
401 | Отсутствуют заголовки, неверная подпись или повторный nonce |
403 | Мерчант или API-ключ отключены |
404 | Заявка не найдена или не принадлежит вашему мерчанту |
409 | Нет подходящего терминала для суммы/метода |
422 | Невалидное тело запроса (отсутствует обязательное поле) |
staging: api-stage.paysoutsfi.io/docs/api · prod: api.paysoutsfi.io/docs