protopaysAPI

первый успешный запрос

Сценарий: ключ, подпись, запрос, ответ, webhook. Актуальный Base URL — на главной.

1. получите api key

В личном кабинете мерчанта откройте шлюз и выпустите credentials для API. Открыть кабинет

2. сформируйте подпись

Как в аутентификации: HMAC от байт JSON-тела.

3. отправьте запрос (демо-скрипт)

Сохраните как pay-demo.mjs, укажите ключ и секрет, запустите node pay-demo.mjs.

node
// pay-demo.mjs — подпись считается при каждом запуске (готовых hex в тексте нет).
// Node.js 18+
import crypto from "node:crypto";

const PP_API = "https://api.protopays.io";
if (!PP_API) {
  console.error("Укажите PP_API — см. главную страницу документации, поле Base URL.");
  process.exit(1);
}

const PP_KEY_ID = ""; // публичный key_id строки ключа из кабинета
const PP_SECRET = ""; // секрет той же строки
if (!PP_KEY_ID) {
  console.error("Укажите PP_KEY_ID.");
  process.exit(1);
}
if (!PP_SECRET) {
  console.error("Укажите PP_SECRET.");
  process.exit(1);
}

const body = JSON.stringify({
  orderId: "merchant-order-" + Date.now(),
  amount: "5000",
  currency: "RUB",
  callbackUri: "https://your-site.example/hooks/protopays",
  method: "sbp",
  payer: {
    userId: "u-4095",
    userIp: "188.11.55.10",
    fullName: "Kim Min-jun",
    type: "trusted",
    payments: { successful: 5, expired: 1 },
  },
});

const signature = crypto.createHmac("sha256", PP_SECRET).update(body, "utf8").digest("hex");

const res = await fetch(PP_API + "/api/v1/payments", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Merchant-Key-Id": PP_KEY_ID,
    "X-Merchant-Secret": PP_SECRET,
    Signature: signature,
  },
  body,
});

const text = await res.text();
console.log("HTTP", res.status);
console.log(text);

4. ожидаемый ответ (успех)

При корректной подписи и валидных полях — 200 OK и JSON. В теле всегда есть message; в data — поля платежа; для СБП часто приходит requisite и expiresAt (срок резерва реквизита). Пример:

http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "message": "Payment created",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "orderId": "merchant-order-173",
    "status": "pending",
    "amount": "5000.00",
    "currency": "RUB",
    "method": "sbp",
    "requisite": {
      "value": "+79991234567",
      "holder": "И. Иванов",
      "bank": "Пример банк"
    },
    "paymentPageUrl": "https://pay.protopays.io/r/rpt_<token>",
    "expiresAt": "2026-04-20T15:30:00+00:00"
  }
}

Сохраните id, откройте клиенту paymentPageUrl (или покажите requisite). Поля — в справочнике по созданию платежа.

5. webhook

При смене статуса — POST на ваш URL. Дубликаты и порядок — в разделе webhooks.

если что-то пошло не так

Ошибки, идемпотентность.