Перейти к основному содержимому

Колбэки (вебхуки)

RollyPay отправляет на ваш сервер HTTP POST при наступлении событий (оплата, отмена, вывод и т.д.).

Настройка

URL для колбэков задаётся в настройках кассы (callback_url). Его можно задать при создании кассы или через API:

PUT /api/v1/terminals/{terminalID}

{
"callback_url": "https://your-server.com/webhooks/rollypay"
}

Сервер должен отвечать кодом 2xx в течение 10 секунд. Иначе запрос будет повторён по политике retry.

Тело запроса

Каждый колбэк — JSON, например:

{
"event_type": "payment.paid",
"payment_id": "pay_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"order_id": "order_12345",
"status": "paid",
"amount": "1500.00",
"currency": "RUB"
}

Проверка подписи

В заголовке X-Signature передаётся HMAC-SHA256 от сырого тела запроса (JSON), ключ — signing_secret кассы. Проверять подпись обязательно перед обработкой.

JavaScript (Node)

const crypto = require("crypto");

function verifySignature(body, signature, signingSecret) {
const expected = crypto
.createHmac("sha256", signingSecret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}

app.post("/webhooks/rollypay", (req, res) => {
const signature = req.headers["x-signature"];
const rawBody = req.rawBody; // нужен именно сырой body, не распарсенный

if (!verifySignature(rawBody, signature, process.env.SIGNING_SECRET)) {
return res.status(403).send("Invalid signature");
}

const event = JSON.parse(rawBody);
// Обработка event...

res.status(200).send("OK");
});

Go

import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
)

func verifySignature(body []byte, signature, signingSecret string) bool {
mac := hmac.New(sha256.New, []byte(signingSecret))
mac.Write(body)
expected := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(expected), []byte(signature))
}

Типы событий

СобытиеКогда приходит
payment.createdПлатёж создан
payment.paidОплата подтверждена провайдером
payment.canceledПлатёж отменён
payment.chargebackЧарджбек по оплаченному платежу
payout.completedВывод успешно выполнен

Повторные попытки

Если ваш endpoint вернул не 2xx или не ответил в течение 10 секунд, RollyPay повторяет запрос с экспоненциальной задержкой:

ПопыткаЗадержка после неудачи
130 сек
21 мин
32 мин
44 мин
58 мин
616 мин
732 мин
864 мин (последняя)

Формула: 30 сек × 2^(попытка − 1), не более 8 попыток. После успешного 2xx повторная отправка этого события не выполняется.