Апелляция по платежу
Если платёж в failed, можно открыть спор: текст причины и файл (чек). Окно ~24 часа после смены статуса. payment в URL — числовой id платежа.
POST
https://api.protopays.io/api/v1/payments/{payment}/appealЗаголовки ключа — как в аутентификации, но подпись не от сырого multipart.
Подпись
HMAC-SHA256 от такой строки (UTF-8, перевод строки LF):
code
appeal-v1
{reason}
{originalFileName}
{sizeBytes}sizeBytes — размер файла в байтах. Результат — hex в нижнем регистре в Signature.
Поля
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| reason | string | да | Причина, до 10000 символов. |
| file | file | да | PDF / JPEG / PNG / WEBP / DOC / DOCX. |
Пример
node
import crypto from "node:crypto";
import fs from "node:fs";
const secret = "<SECRET>";
const paymentId = 1001;
const reason = "Клиент оплатил, статус failed ошибочно";
const filePath = "./receipt.pdf";
const buf = fs.readFileSync(filePath);
const originalName = "receipt.pdf";
const sizeBytes = String(buf.length);
const canonical = `appeal-v1\n${reason}\n${originalName}\n${sizeBytes}`;
const signature = crypto.createHmac("sha256", secret).update(canonical, "utf8").digest("hex");
const form = new FormData();
form.append("reason", reason);
form.append("file", new File([buf], originalName, { type: "application/pdf" }));
const res = await fetch(`https://api.protopays.io/api/v1/payments/${paymentId}/appeal`, {
method: "POST",
headers: {
"X-Merchant-Key-Id": "<KEY_ID>",
"X-Merchant-Secret": secret,
Signature: signature,
},
body: form,
});
console.log(res.status, await res.text());
Ответ 201
json
{
"message": "Appeal opened",
"data": {
"appealId": 1,
"paymentId": 1001,
"paymentStatus": "appeal",
"appealStatus": "open"
}
}Ошибки
- 403 — ключ не подходит
- 409 — спор уже открыт
- 422 — не failed / срок вышел / нет исполнителя