ProtoPays · API
кабинет

Создание платежа

Создаёт новый платёж в режиме RUB collect с выдачей реквизита для оплаты. После успешного ответа покажите клиенту данные из requisite; итоговый статус приходит в webhook.

POST https://api.protopays.io/api/v1/payments

Заголовки запроса

ПолеТипОбяз.Описание
Content-TypestringдаДолжен быть application/json.
X-Merchant-SecretstringдаСекрет ключа из кабинета (как в настройках API).
Signaturestring (hex)даHMAC-SHA256 от сырого тела запроса в UTF-8, hex в нижнем регистре.
X-Merchant-Key-IdstringдаПубличный key_id строки API-ключа в кабинете.

Подробнее: аутентификация.

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

curl

curl -X POST 'https://api.protopays.io/api/v1/payments' \
  -H 'Content-Type: application/json' \
  -H 'X-Merchant-Secret: <SECRET>' \
  -H 'Signature: <SIGNATURE>' \
  -d '{
    "orderId": "order-001",
    "amount": "1000",
    "currency": "RUB",
    "callbackUri": "https://example.com/hooks/protopays",
    "method": "sbp"
  }'

Node.js (fetch)

Подставьте Base URL и секрет; тело для подписи должно совпадать с телом запроса байт в байт.

import crypto from "node:crypto";

const body = JSON.stringify({
  orderId: "order-001",
  amount: "1000",
  currency: "RUB",
  callbackUri: "https://example.com/hooks/protopays",
  method: "sbp",
});
const secret = "<SECRET>";
const signature = crypto.createHmac("sha256", secret).update(body, "utf8").digest("hex");

const res = await fetch("https://api.protopays.io/api/v1/payments", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Merchant-Secret": secret,
    Signature: signature,
  },
  body,
});
console.log(res.status, await res.text());

Тело запроса (JSON)

Валидация соответствует серверным правилам: валюта только RUB; канал оплаты задаётся через rubCollect.method или корневое поле method (сервер мержит в rubCollect).

Обязательные поля

ПолеТипОбяз.Описание
orderIdstringдаВаш идентификатор заказа, до 255 символов (trim). Идемпотентность — по связке с каналом.
amountnumber | stringдаСумма, минимум 1. Для RUB в ответе может форматироваться с двумя знаками.
currencystringдаТолько RUB для данного сценария.
callbackUristring (URL)даHTTPS URL для webhook о смене статуса, до 2048 символов.
rubCollectobjectдаОбязателен объект; поле method внутри — канал (sbp, card и т.д. по enum). Альтернатива: передать method на корне тела.
rubCollect.methodstringдаКанал RUB collect, например sbp или card (см. OpenAPI enum).

Необязательные поля

ПолеТипОбяз.Описание
methodstringнетДублирует rubCollect.method; удобно для плоского JSON.
descriptionstringнетОписание, до 255 символов.
ratePercentnumberнетЕсли поддерживается сценарием.
payerobjectнетВложенные payer.userId, payer.userIp — при необходимости.

Ответ (успех)

HTTP 200. Корень содержит человекочитаемое message и объект data.

{
  "message": "Payment created",
  "data": {
    "id": 1001,
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "orderId": "order-001",
    "status": "pending",
    "amount": "1000.00",
    "currency": "RUB",
    "requisite": {
      "type": "sbp",
      "method": "sbp",
      "value": "+79991234567",
      "holder": "И. Иванов",
      "bank": "Пример банк"
    },
    "expiresAt": "2026-04-20T15:30:00+00:00"
  }
}

Поля data

ПолеТипОбяз.Описание
idnumberдаВнутренний id платежа.
uuidstring (UUID)даСтабильный публичный идентификатор.
orderIdstringдаТот же orderId, что в запросе.
statusstringдаТекущий статус (см. ниже).
amountstringдаСумма строкой (формат для RUB).
currencystringдаRUB.
requisiteobjectнетРеквизит для оплаты; может отсутствовать, если выдача иная по сценарию.
expiresAtstring (ISO8601)нетСрок действия резерва реквизита.

Статусы платежа

Значения status в API (основные): pending, completed, failed, cancelled, appeal. Точный набор и переходы — в OpenAPI и бизнес-логике.

Реквизиты (requisite)

Для СБП типично type / method указывают на сценарий, value — номер телефона или иной идентификатор; holder и bank — при наличии.

Подробнее: реквизиты — отдельная страница.

Webhook после создания

После смены статуса сервис отправит POST на callbackUri. Пример JSON и поля тела — в Webhook по платежу; повторы и тайминги — в Webhooks.

Срок жизни реквизита

Поле expiresAt в ответе задаёт момент истечения резерва; по истечении сценарий может потребовать нового платежа — уточняйте по статусам и webhook.

Идемпотентность

Повтор с тем же orderId и каналом возвращает тот же платёж. См. идемпотентность.

Полная машиночитаемая схема (OpenAPI JSON): /openapi/api-docs.json