Создание платежа
RUB collect: реквизит в data.requisite. Текущий статус можно опрашивать через GET /payments/status; финальный результат — в webhook.
POST https://api.protopays.io/api/v1/payments
Параметры тела (JSON)
Мерчант — из заголовков, не из тела. Подпись — от байт JSON ниже.
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| orderId | string | да | Ваш id заказа, до 255 (trim). Повтор с тем же `orderId` и методом — тот же платёж. |
| amount | number | string | да | Сумма, минимум 1. В валюте RUB; в ответе может быть строка с 2 дробными. |
| currency | string | да | Сейчас: только RUB. |
| callbackUri | string (URL) | да | HTTPS URL для POST webhook о смене статуса, до 2048 симв. |
| method | string | да | Метод RUB collect: sbp | card (как `payment_type` в других API). |
| payer | object | нет | Опц.: метаданные плательщика. Все поля необязательны; при передаче сохраняются на платеже (в ответе create не возвращаются). userId, userIp — привязка к пользователю; type — ftd | std | trusted; payments.successful / payments.expired — неотрицательные целые. |
Заголовки запроса
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| Content-Type | string | да | Должен быть application/json. |
| X-Merchant-Key-Id | string | да | Публичный key_id строки API-ключа в кабинете. |
| Signature | string (hex) | да | HMAC-SHA256 от байт тела JSON (UTF-8) в нижнем hex; ключ HMAC — сырой секрет ключа (только для расчёта, не в HTTP). |
Подробнее: аутентификация.
Примеры запроса
curl
curl -X POST 'https://api.protopays.io/api/v1/payments' \
-H 'Content-Type: application/json' \
-H 'X-Merchant-Key-Id: <KEY_ID>' \
-H 'Signature: <SIGNATURE>' \
-d '{
"orderId": "order-001",
"amount": "1000",
"currency": "RUB",
"callbackUri": "https://example.com/hooks/protopays",
"method": "sbp",
"payer": {
"userId": "u-4095",
"userIp": "188.11.55.10",
"type": "trusted",
"payments": {
"successful": 5,
"expired": 1
}
}
}'PHP (cURL + hash_hmac)
Base URL, <SECRET>, <KEY_ID> из кабинета. Один и тот же $body — в HMAC и в тело.
<?php
$base = rtrim("https://api.protopays.io", '/');
$keyId = '<KEY_ID>';
$secret = '<SECRET>';
$payload = [
'orderId' => 'order-001',
'amount' => '1000',
'currency' => 'RUB',
'callbackUri' => 'https://example.com/hooks/protopays',
'method' => 'sbp',
'payer' => [
'userId' => 'u-4095',
'userIp' => '188.11.55.10',
'type' => 'trusted',
'payments' => [
'successful' => 5,
'expired' => 1,
],
],
];
$body = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$signature = hash_hmac('sha256', $body, $secret);
$ch = curl_init("{$base}/api/v1/payments");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Merchant-Key-Id: ' . $keyId,
'Signature: ' . $signature,
],
CURLOPT_POSTFIELDS => $body,
]);
echo curl_exec($ch);Ответ (успех)
200, корень: message + data. «Обяз.» — в нормальном сценарии ожидаемо; часть полей может быть null.
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| message | string | да | Корень. Сообщение о результате (часто `Payment created`). |
| id | string (UUID) | да | В `data`. Публичный id (callback, appeal, и т.д.). |
| orderId | string | да | В `data`. Тот же `orderId`, что в запросе. |
| status | string | да | В `data`. Текущий статус; значения — в OpenAPI. |
| amount | string | да | В `data`. Сумма строкой (RUB с двумя десятичными). |
| currency | string | да | В `data`. RUB. |
| requisite | object | null | нет | В `data`. Снимок реквизита: `value`, `holder`, `bank` — если выдали; иначе ключа нет или сценарий иной. |
| expiresAt | string | null | да | В `data`, ключ всегда. ISO 8601; `null` если нет срока резерва / сделки. |
{
"message": "Payment created",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"orderId": "order-001",
"status": "pending",
"amount": "1000.00",
"currency": "RUB",
"requisite": {
"value": "+79991234567",
"holder": "И. Иванов",
"bank": "Пример банк"
},
"expiresAt": "2026-04-20T15:30:00+00:00"
}
}