RRUBREK PayДокументация API

RUBREK Pay — API для приёма платежей

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

Базовый адрес: https://pay.rubrek.com.

Формат: JSON, UTF-8. Суммы — числа с не более чем двумя знаками после запятой.

Авторизация: заголовок Authorization: Bearer <API-ключ> в каждом запросе.

Кабинет: https://pay.rubrek.com/cabinet/ — баланс, платежи с выгрузкой в Excel, выплаты (и запрос выплаты) и ссылки на оплату без программирования. Логин и пароль выдаёт менеджер.

Тестовый стенд: https://pay-demo.rubrek.com — тот же API, ссылки, уведомления и баланс, но оплата имитируется: на странице оплаты есть кнопки «картой», «по СБП» и «отказ банка», деньги не списываются. Интеграцию можно собрать и проверить на стенде до подключения боевого приёма, затем сменить базовый адрес и ключ. Ключ для стенда тоже выдаёт менеджер.

Способы оплаты

Плательщик открывает ссылку и выбирает удобный способ: банковская карта, СБП и другие доступные методы. Валюта ссылки — RUB, USD или EUR. Минимальная сумма — 10 ₽, 1 $, 1 €.

Создать ссылку на оплату

POST /v1/links

ПолеОбяз.ТипОписание
amountдаnumberСумма, например 1500.50
currencyдаstringRUB, USD, EUR
orderIdнетstringНомер заказа в вашей системе (до 200 символов) — по нему удобно искать платежи
descriptionнетstringНазначение, его видит плательщик (до 500 символов)
successUrlнетstringКуда вернуть плательщика после успешной оплаты
failUrlнетstringКуда вернуть после неуспешной
expiresAtнетstringСрок действия, ISO 8601. От 10 минут до 30 дней; по умолчанию 3 дня
reusableнетbooleantrue — многоразовая ссылка (оплат может быть несколько). По умолчанию одноразовая
POST /v1/links
Authorization: Bearer rk_...
Content-Type: application/json

{ "amount": 1500.50, "currency": "RUB", "orderId": "A-1001", "description": "Пополнение баланса" }

Ответ 201:

{
  "id": "KMcYc_1LMqjPrhyR",
  "url": "https://pay.rubrek.com/p/KMcYc_1LMqjPrhyR",
  "amount": 1500.5,
  "currency": "RUB",
  "orderId": "A-1001",
  "description": "Пополнение баланса",
  "reusable": false,
  "status": "open",
  "expiresAt": "2026-11-08T11:35:53.678Z",
  "createdAt": "2026-11-05T11:35:53.679Z"
}

Отправьте url плательщику. Одноразовая ссылка закрывается после оплаты: повторно открытая, она показывает «Заказ оплачен». Истёкшая открывает страницу «Ссылка на оплату недействительна».

Ссылка

GET /v1/links/{id} — та же структура. status: open, closed (оплачена), expired.

Платежи

GET /v1/transactions?orderId=&from=YYYY-MM-DD&to=YYYY-MM-DD&limit=200 — новые первыми, до 500.

{
  "transactions": [{
    "id": "t_l3Ll_KUsA5FRxAiW", "linkId": "KMcYc_1LMqjPrhyR", "orderId": "A-1001",
    "kind": "payment", "status": "paid", "method": "sbp",
    "amount": 15000, "currency": "RUB", "fee": 825, "net": 14175,
    "paidAt": "2026-11-05T11:36:15.882Z", "createdAt": "2026-11-05T11:36:15.900Z", "error": null
  }]
}

kind: payment или refund. status: created, pending, paid, declined. fee — комиссия RUBREK по операции, net — сумма к зачислению вам (у возврата отрицательная).

Баланс

GET /v1/balance

{ "balances": [{ "currency": "RUB", "payments": 12, "turnover": 180000, "fee": 9900, "refunds": 1000,
  "net": 169100, "paidOut": 150000, "adjustments": 0, "due": 19100 }] }

due — сумма к выплате на текущий момент. Выплаты в USDT проводит менеджер RUBREK.

Уведомления о платежах

Если при подключении указан адрес для уведомлений, на него приходит POST при каждом итоговом статусе: payment.paid, payment.declined, refund.paid, refund.declined.

{ "event": "payment.paid", "id": "t_l3Ll_KUsA5FRxAiW", "linkId": "KMcYc_1LMqjPrhyR", "orderId": "A-1001",
  "amount": 15000, "currency": "RUB", "fee": 825, "net": 14175, "status": "paid", "method": "sbp",
  "paidAt": "2026-11-05T11:36:15.882Z", "error": null }

Проверяйте подпись до того, как зачислить деньги. Заголовки:

import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(rawBody, headers, secret) {
  const ts = headers['x-rubrek-timestamp'];
  const expected = 'sha256=' + createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
  const got = String(headers['x-rubrek-signature'] || '');
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && got.length === expected.length && timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}

Считайте подпись по сырому телу, до разбора JSON. Ответьте любым кодом 2xx, когда приняли уведомление. Если ответа нет за 10 секунд или код другой, уведомление повторяется примерно через 10 минут, 30 минут, 1, 3, 6, 12 и 24 часа — всего 8 попыток примерно за двое суток. Тело повтора то же, меняются только X-Rubrek-Timestamp и подпись. Поэтому одно уведомление может прийти несколько раз — обрабатывайте его по id идемпотентно. Статус всегда можно получить и через GET /v1/transactions. Повторить уведомление по завершённому платежу можно и вручную — в кабинете: «Платежи» → платёж → «Отправить уведомление повторно».

Ошибки

КодЧто значит
400Неверные параметры — текст в поле error
401Нет ключа или ключ неверный
403Приём платежей приостановлен — свяжитесь с менеджером
404Объект не найден
502Платёжная система отклонила запрос — текст в поле error
503Приём платежей временно недоступен — свяжитесь с менеджером