PHP-SDK
Один файл, без залежностей. createInvoice(), getInvoice() і verifyWebhook() — кладеться в будь-який проєкт.
Один PHP-SDK без залежностей: створити рахунок, надіслати на готовий чек-аут і перевірити підпис вебхука. Для будь-якої іншої мови є REST.
api.payora.moneyОдин виклик API з номером замовлення та сумою у фіаті чи крипті повертає посилання на оплату.
Він обирає монету, сканує QR або відкриває гаманець — оплата підтверджується наживо після фіналізації.
Перевірте підпис HMAC, зарахуйте замовлення один раз — і платіж уже на вашому балансі.
Один файл, без залежностей. createInvoice(), getInvoice() і verifyWebhook() — кладеться в будь-який проєкт.
Запити й вебхуки підписані HMAC-SHA256 з допуском за часом і ключами ідемпотентності.
Звичайний JSON поверх HTTPS — інтеграція з будь-якого стека, не лише з PHP.
<?php
require 'Payora.php';
$payora = new Payora('https://api.payora.money', getenv('PAYORA_KEY'), getenv('PAYORA_SECRET'));
// 1 — create an invoice (fiat-priced; the payer picks a coin)
$inv = $payora->createInvoice([
'order_id' => 'ORDER-42',
'mode' => 'fiat',
'amount' => '9.99',
'return_url' => 'https://shop.example/thanks',
'lang' => 'en',
], 'ORDER-42'); // Idempotency-Key: a retry never creates a second invoice
header('Location: ' . $inv['pay_url']);
// 2 — webhook endpoint: ALWAYS verify the signature first
$event = $payora->verifyWebhook(file_get_contents('php://input'), getallheaders());
if ($event === null) { http_response_code(400); exit; }
if ($event['status'] === 'paid') {
creditOrderOnce($event['id'], $event['order_id'], $event['amount'], $event['currency']);
}
http_response_code(200); // 2xx stops retriesconst Payora = require('./payora');
const payora = new Payora('https://api.payora.money', process.env.PAYORA_KEY, process.env.PAYORA_SECRET);
// 1 — create an invoice and redirect
app.post('/checkout', async (req, res) => {
const inv = await payora.createInvoice({ order_id: 'ORDER-42', mode: 'fiat', amount: '9.99' }, 'ORDER-42');
res.redirect(inv.pay_url);
});
// 2 — webhook: verify over the RAW body
app.post('/payora/webhook', express.raw({ type: '*/*' }), (req, res) => {
const event = payora.verifyWebhook(req.body, req.headers);
if (event === null) return res.status(400).end();
if (event.status === 'paid') creditOrderOnce(event.id, event.order_id);
res.status(200).end();
});import os
from payora import Payora
payora = Payora('https://api.payora.money', os.environ['PAYORA_KEY'], os.environ['PAYORA_SECRET'])
# 1 — create an invoice and redirect
inv = payora.create_invoice({'order_id': 'ORDER-42', 'mode': 'fiat', 'amount': '9.99'}, 'ORDER-42')
return redirect(inv['pay_url'])
# 2 — webhook: verify over the RAW body
event = payora.verify_webhook(request.get_data(), dict(request.headers))
if event is None:
return ('', 400)
if event['status'] == 'paid':
credit_order_once(event['id'], event['order_id'])
return ('', 200)# signature = lowercase hex HMAC-SHA256(api_secret, timestamp + "." + raw_body)
BODY='{"order_id":"ORDER-42","mode":"fiat","amount":"9.99"}'
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$PAYORA_SECRET" | cut -d' ' -f2)
curl -X POST https://api.payora.money/v1/invoice \
-H "X-Payora-Key: $PAYORA_KEY" -H "X-Payora-Timestamp: $TS" \
-H "X-Payora-Signature: $SIG" -H 'Idempotency-Key: ORDER-42' \
-H 'Content-Type: application/json' -d "$BODY"
# → 201 { "invoice_id": …, "status": "pending", "pay_url": "https://pay.payora.money/i/…", "expires": … }Отримайте свій API key і secret, створивши акаунт. Повний SDK — у вашій панелі.
Кожен виклик, крім /v1/health, несе три підписані заголовки. Підпис доводить, що запит надіслав власник вашого api_secret і дорогою його не змінили.
| Заголовок | Значення | Опис |
|---|---|---|
X-Payora-Key | pk_… | Ваш публічний api_key. Визначає магазин. |
X-Payora-Timestamp | unix seconds | Момент підпису запиту, у секундах Unix. |
X-Payora-Signature | hex · 64 | HMAC-SHA256 від timestamp + "." + сире тіло на ключі api_secret, малими літерами hex. |
X-Payora-Test | 1 | Позначає рахунок як перевірку інтеграції: рахунок справжній і може прийняти монети, але в показники попиту та конверсії не йде. |
Idempotency-Key | string | Необов’язковий для POST /v1/invoice і POST /v1/payout. Повтор із тим самим ключем повертає перший результат замість дубліката; той самий ключ з іншим тілом отримує 409. |
Content-Type | application/json | Обов’язковий для запитів із тілом. |
hex( HMAC-SHA256( api_secret, timestamp + "." + raw_body ) )Підписуйте саме ті байти, які надсилаєте. Повторне кодування JSON після підпису — навіть інший порядок ключів чи зайвий пробіл — ламає підпис.
У GET-запиту тіло порожнє, тож підписується timestamp із крапкою в кінці.
API відхиляє timestamp, що розходиться з його годинником більш ніж на 120 секунд. Синхронізуйте час сервера через NTP.
Зберігайте api_secret лише на сервері. Ним підписуються і запити, і вебхуки: хто його має, той може створювати рахунки від вашого імені й підробляти сповіщення.
<?php
$body = json_encode(['order_id' => 'ORDER-42', 'mode' => 'fiat', 'amount' => '9.99'], JSON_UNESCAPED_SLASHES);
$ts = (string) time();
$sig = hash_hmac('sha256', $ts . '.' . $body, $apiSecret); // lowercase hex
$ch = curl_init('https://api.payora.money/v1/invoice');
curl_setopt_array($ch, [
CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-Payora-Key: ' . $apiKey,
'X-Payora-Timestamp: ' . $ts,
'X-Payora-Signature: ' . $sig,
'Idempotency-Key: ORDER-42',
'Content-Type: application/json',
],
]);
$invoice = json_decode(curl_exec($ch), true);const crypto = require('crypto');
const body = JSON.stringify({ order_id: 'ORDER-42', mode: 'fiat', amount: '9.99' });
const ts = String(Math.floor(Date.now() / 1000));
const sig = crypto.createHmac('sha256', API_SECRET).update(ts + '.' + body).digest('hex');
const res = await fetch('https://api.payora.money/v1/invoice', {
method: 'POST',
headers: {
'X-Payora-Key': API_KEY,
'X-Payora-Timestamp': ts,
'X-Payora-Signature': sig,
'Idempotency-Key': 'ORDER-42',
'Content-Type': 'application/json',
},
body, // send exactly the bytes you signed
});import hashlib, hmac, json, time, urllib.request
body = json.dumps({'order_id': 'ORDER-42', 'mode': 'fiat', 'amount': '9.99'}, separators=(',', ':'))
ts = str(int(time.time()))
sig = hmac.new(API_SECRET.encode(), (ts + '.' + body).encode(), hashlib.sha256).hexdigest()
req = urllib.request.Request('https://api.payora.money/v1/invoice', data=body.encode(), method='POST', headers={
'X-Payora-Key': API_KEY,
'X-Payora-Timestamp': ts,
'X-Payora-Signature': sig,
'Idempotency-Key': 'ORDER-42',
'Content-Type': 'application/json',
})
invoice = json.load(urllib.request.urlopen(req))# GET has an empty body: the signed string is just the timestamp and a dot
TS=$(date +%s)
SIG=$(printf '%s.' "$TS" | openssl dgst -sha256 -hmac "$PAYORA_SECRET" | cut -d' ' -f2)
curl https://api.payora.money/v1/invoice/1042 \
-H "X-Payora-Key: $PAYORA_KEY" \
-H "X-Payora-Timestamp: $TS" \
-H "X-Payora-Signature: $SIG"Усе необов’язкове, крім order_id та amount. У режимі fiat платник може обрати будь-яку монету, увімкнену у вашому акаунті; режиму crypto також потрібен currency.
| Параметр | Тип | Опис |
|---|---|---|
order_id | string · required | Ваш унікальний ідентифікатор замовлення (≤190 символів). Повтор відхиляється з 409 — захист від подвійного надсилання. |
amount | string · required | Сума у фіаті (mode=fiat) або точна сума у крипті (mode=crypto). |
mode | fiat | crypto | За замовчуванням fiat: курс фіксується для кожної монети на checkout. crypto заздалегідь фіксує монету та суму. |
fiat_currency | string | ISO-код фіату для режиму fiat (default USD). |
currency | string | Монета для режиму crypto (наприклад, TON, TRX, USDT_TRON). |
return_url | https URL | Куди кнопка «Повернутися до магазину» на checkout повертає клієнта — на ваш сайт. Лише абсолютний http(s). |
lang | en·ru·uk·es·de | Мова checkout, щоб клієнт із вашого російського магазину бачив checkout російською, а не англійською. Також задається як ?lang=ru в URL оплати. |
ttl | seconds | Скільки рахунок лишається доступним для оплати (120–86400 секунд, типово 1800). |
customer_email | Необов'язково — потрапляє в чек і надсилається платнику поштою. | |
notes | string | Довільна нотатка, що зберігається в рахунку. |
return_url та lang також працюють як query-параметри, що додаються до pay_url, який повертає API — <pay_url>&lang=ru&return_url=https://shop.example/thanks. Завжди надсилайте покупця на pay_url, повернутий API: він несе одноразовий токен доступу до рахунку, тому сторінку checkout не можна відкрити, вгадавши номер рахунку. Не збирайте посилання заново з id рахунку.
Заповніть поля й скопіюйте готову команду cURL. Вона підписується сама у вашій оболонці через $PAYORA_KEY і $PAYORA_SECRET — ця сторінка не бачить ваших ключів і нічого не надсилає.
BODY='{"order_id":"ORDER-42","mode":"fiat","amount":"9.99","fiat_currency":"USD","return_url":"https://shop.example/thanks","lang":"uk","ttl":1800}'
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$PAYORA_SECRET" | cut -d' ' -f2)
curl -X POST https://api.payora.money/v1/invoice \
-H "X-Payora-Key: $PAYORA_KEY" \
-H "X-Payora-Timestamp: $TS" \
-H "X-Payora-Signature: $SIG" \
-H 'Idempotency-Key: ORDER-42' \
-H 'Content-Type: application/json' \
-d "$BODY"З цієї сторінки нічого не надсилається.
Коли рахунок або виплата змінює стан, Payora надсилає POST із підписаною JSON-подією на вашу адресу сповіщень. Спершу перевірте підпис, зарахуйте замовлення один раз, відповідайте 2xx.
| Подія | status | Коли надходить |
|---|---|---|
invoice.paid | paid | Платіж підтверджено в мережі. Містить суму, монету й tx_hash. |
invoice.underpaid | underpaid | Строк рахунку минув, а надійшло менше за очікувану суму. |
invoice.expired | expired | Строк рахунку минув, оплати не було. |
invoice.cancelled | cancelled | Рахунок скасовано. Якщо гроші вже надійшли, це описано в події. |
invoice.cancel_settled | — | З грошима, що надійшли на скасований рахунок, усе вирішено: зараховано або повернено. |
invoice.late_payment | — | Гроші надійшли на рахунок уже після його скасування. Надсилається на кожне таке надходження; у result — зараховано їх чи вони повертаються. |
payout.sent | sent | Пакет виплат підписано й надіслано в мережу. Містить кожну виплату з її tx_hash. |
| Заголовок | Значення | Опис |
|---|---|---|
X-Payora-Id | uuid | Унікальний id події, той самий, що id у тілі. Зберігайте його, щоб пропускати повтори. |
X-Payora-Event | invoice.paid | Назва події. |
X-Payora-Timestamp | unix seconds | Коли підписано цю спробу. |
X-Payora-Signature | hex · 64 | Та сама схема, що в запитів: HMAC-SHA256 від timestamp + "." + сире тіло на ключі api_secret. |
| Поле | Тип | Опис |
|---|---|---|
id | uuid | Id події для захисту від повторів. |
event | string | Назва події. |
invoice_id | int | Номер рахунку в Payora. |
order_id | string | Ваш номер замовлення, як його передали під час створення рахунку. |
status | string | paid для invoice.paid. |
currency | string | Монета, якою заплатили, наприклад USDT_TRON. |
amount | decimal string | Отримана сума. |
amount_units | integer string | Та сама сума в найменших одиницях монети — для точних порівнянь. |
expected | decimal string | Сума, виставлена в рахунку. |
fiat_amount | decimal string | null | Ціна рахунку у фіаті, як ви її виставили; null у рахунків у крипто-режимі. |
fiat_currency | string | null | ISO-код валюти fiat_amount; null у рахунків у крипто-режимі. |
tx_hash | string | Хеш транзакції в мережі. |
paid_at | unix seconds | Коли створено подію. |
test | bool | true для тестових рахунків. |
{
"id": "6f1c2a4e-8b0d-4c1e-9a57-2f3d9e1b7c40",
"event": "invoice.paid",
"invoice_id": 1042,
"order_id": "ORDER-42",
"status": "paid",
"currency": "USDT_TRON",
"amount": "9.99",
"amount_units": "9990000",
"expected": "9.99",
"fiat_amount": "9.99",
"fiat_currency": "USD",
"tx_hash": "3f9a…c21e",
"paid_at": 1758038400,
"test": false
}Якщо отримана сума відрізняється від суми рахунку, додаються amount_received і amount_expected.
Будь-яка відповідь, крім 2xx, або відсутність відповіді за 15 секунд — повтор з експоненційною паузою, не більше години між спробами, загалом до 12 спроб. Кожна спроба підписується заново з новим timestamp; тіло та id події не змінюються, тож відсікайте повтори за id.
Після останньої спроби подію позначають невдалою, а власник магазину отримує лист. Переспрямування не виконуються, а адреса сповіщень має бути доступна з інтернету — без localhost і приватних адрес.
hash_equals, crypto.timingSafeEqual, hmac.compare_digest.<?php
require 'Payora.php';
$payora = new Payora('https://api.payora.money', getenv('PAYORA_KEY'), getenv('PAYORA_SECRET'));
$raw = file_get_contents('php://input'); // raw, before any parsing
$event = $payora->verifyWebhook($raw, getallheaders()); // HMAC + ±300 s window, constant-time
if ($event === null) { http_response_code(400); exit; } // bad / forged / stale
if ($event['event'] === 'invoice.paid' && !alreadyProcessed($event['id'])) {
creditOrder($event['order_id'], $event['amount'], $event['currency'], $event['tx_hash']);
rememberProcessed($event['id']);
}
http_response_code(200); // 2xx stops retries// Express: capture the RAW body for this route
app.post('/payora/webhook', express.raw({ type: '*/*' }), (req, res) => {
const event = payora.verifyWebhook(req.body, req.headers); // HMAC + ±300 s, timingSafeEqual
if (event === null) return res.status(400).end();
if (event.event === 'invoice.paid' && !alreadyProcessed(event.id)) {
creditOrder(event.order_id, event.amount, event.currency, event.tx_hash);
rememberProcessed(event.id);
}
res.status(200).end(); // 2xx stops retries
});# Flask: request.get_data() is the exact raw body
@app.post('/payora/webhook')
def payora_webhook():
event = payora.verify_webhook(request.get_data(), dict(request.headers))
if event is None:
return ('', 400) # bad / forged / stale
if event['event'] == 'invoice.paid' and not already_processed(event['id']):
credit_order(event['order_id'], event['amount'], event['currency'], event['tx_hash'])
remember_processed(event['id'])
return ('', 200) # 2xx stops retries# Recompute the signature of a delivery you saved byte-for-byte to body.json
TS='1758038400' # X-Payora-Timestamp
SIG='…' # X-Payora-Signature
EXPECTED=$(printf '%s.' "$TS" | cat - body.json | openssl dgst -sha256 -hmac "$PAYORA_SECRET" | cut -d' ' -f2)
[ "$EXPECTED" = "$SIG" ] && echo valid || echo forgedВведіть секрет, timestamp і сире тіло — і побачите саме той підпис, який надішле Payora. Або перевірте отриманий.
Працює у вашому браузері через WebCrypto. Ніщо з введеного не залишає цю сторінку. На чужому комп’ютері використовуйте тестовий секрет, а не бойовий.
1758038400.{…}X-Payora-Timestamp: 1758038400
X-Payora-Signature: …Вставте підпис для порівняння
Надсилайте крипту на 500 гаманців одним підписаним ідемпотентним запитом — зарплата, партнерські виплати, виведення. Сума пакета плюс порядкова комісія одразу утримується на внутрішньому балансі; далі оператор підписує й транслює, і спрацьовує підписаний вебхук payout.sent. Авторизація HMAC та сама, що й усюди.
# create a payout batch — funds held instantly, sent by the operator
curl -X POST https://api.payora.money/v1/payout \
-H 'X-Payora-Key: pk_…' -H 'X-Payora-Timestamp: 1700000000' \
-H 'X-Payora-Signature: <hmac-sha256>' -H 'Idempotency-Key: payroll-2026-01' \
-d '{"currency":"USDT_TRON","items":[
{"address":"TR7…","amount":"250.00"},
{"address":"TX9…","amount":"99.50","tag":"batch-A"}]}'
# → 201 Created
{ "batch_id": 812, "status": "pending", "currency": "USDT_TRON",
"item_count": 2, "total": "349.50", "fee": "…", "items": [ … ] }
# poll status, or receive a signed payout.sent webhook when it is sent
curl https://api.payora.money/v1/payout/812 -H 'X-Payora-Key: …' …<?php
// The one-file PHP SDK covers invoices and webhooks; payouts are one signed POST.
$body = json_encode(['currency' => 'USDT_TRON', 'items' => [
['address' => 'TR7…', 'amount' => '250.00'],
['address' => 'TX9…', 'amount' => '99.50', 'tag' => 'batch-A'],
]], JSON_UNESCAPED_SLASHES);
$ts = (string) time();
$sig = hash_hmac('sha256', $ts . '.' . $body, $apiSecret);
$ch = curl_init('https://api.payora.money/v1/payout');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-Payora-Key: ' . $apiKey, 'X-Payora-Timestamp: ' . $ts, 'X-Payora-Signature: ' . $sig,
'Idempotency-Key: payroll-2026-01', 'Content-Type: application/json']]);
$batch = json_decode(curl_exec($ch), true); // 201: batch_id, status, totals, fee, itemsconst batch = await payora.createPayout({
currency: 'USDT_TRON',
items: [
{ address: 'TR7…', amount: '250.00' },
{ address: 'TX9…', amount: '99.50', tag: 'batch-A' },
],
}, 'payroll-2026-01'); // Idempotency-Key: a retried run never doubles
const status = await payora.getPayout(batch.batch_id);
// still pending? await payora.cancelPayout(batch.batch_id) releases the holdbatch = payora.create_payout({
'currency': 'USDT_TRON',
'items': [
{'address': 'TR7…', 'amount': '250.00'},
{'address': 'TX9…', 'amount': '99.50', 'tag': 'batch-A'},
],
}, 'payroll-2026-01') # Idempotency-Key: a retried run never doubles
status = payora.get_payout(batch['batch_id'])
# still pending? payora.cancel_payout(batch['batch_id']) releases the holdПеревірка сувора: будь-яка невірна адреса або сума з надмірною точністю відхиляють увесь пакет (HTTP 422) з індексами проблемних позицій — під час виплати зарплат жоден отримувач не зникне мовчки. Скасуйте пакет, що ще очікує, через POST /v1/payout/{id}/cancel, щоб зняти утримання. Див. розбір архітектури.
Кожен ендпоінт спілкується звичайним JSON поверх HTTPS за адресою api.payora.money. Усі, крім /v1/health, використовують ту саму автентифікацію запитів за HMAC-SHA256. Машиночитана специфікація доступна за адресою openapi.json.
| Метод | Доступ | Опис |
|---|---|---|
GET/v1/health | no auth | Статус сервісу плюс список увімкнених валют. |
POST/v1/invoice | auth | Створіть рахунок (режим fiat або crypto). Підтримує Idempotency-Key. Повертає 201 з invoice_id, status, pay_url та expires; у режимі crypto додаються адреса, сума та deeplink. |
GET/v1/invoice/{id} | auth | Статус рахунка (лише власні рахунки): status, remaining та charge — currency, адреса, очікувана/отримана суми та tx_hash. |
POST/v1/payout | auth · Pro+ | Створіть пакет масових виплат (сувора перевірка, кошти утримуються миттєво). Підтримує Idempotency-Key. Повертає 201 з поданням пакета: batch_id, status, підсумки, комісія, позиції. |
GET/v1/payout | auth | Список ваших нещодавніх пакетів виплат (?limit=, default 50). |
GET/v1/payout/{id} | auth | Статус пакета виплат та його позиції (лише власні пакети). |
POST/v1/payout/{id}/cancel | auth | Скасуйте пакет, що ще очікує, і звільніть утриманий баланс. Повертає 409, якщо пакет уже не можна скасувати. |
Жоден метод не підходить.
Окремі файли без залежностей. Усі SDK однаково підписують запити й перевіряють вебхуки.
PHP 7.4+ і cURL, один файл. createInvoice, getInvoice і verifyWebhook.
Node.js лише з вбудованими https і crypto. Рахунки, баланс, виплати й verifyWebhook.
Лише стандартна бібліотека Python. Рахунки, баланс, виплати й verify_webhook.
Колекція Postman, яка сама підписує кожен виклик.
Машинозчитувана специфікація всіх методів — для генераторів коду й API-клієнтів.
Готовий модуль зробить усе це за вас: рахунок, перехід до оплати й перевірений вебхук.
Прямі відповіді, зокрема на незручні питання: зберігання коштів, комісії та що буде, якщо щось піде не так.
Довідковий центрПоставте однофайловий PHP-SDK (без залежностей) або звертайтеся до REST API напряму. Створіть рахунок через createInvoice(), надішліть покупця на його pay_url і обробіть одну подію вебхука: status=paid. Досвідчений розробник запускається за 30–60 хвилин.
Так. Усе це звичайний JSON поверх HTTPS, тому інтегруватися можна з будь-якої мови. PHP-SDK — просто зручна обгортка над тими самими адресами: створити рахунок, отримати рахунок і перевірити підпис вебхука.
Так. Передайте return_url під час створення рахунка (або ?return_url= у платіжному посиланні) — і на екрані успіху, і під час оплати чек-аут покаже кнопку «Повернутися до магазину». Передайте lang (en, ru, uk, es, de) або ?lang= у посиланні, щоб покупець із вашого українського магазину потрапив на український чек-аут, а не на англійський. Обидва параметри необов’язкові; return_url має бути абсолютною http(s)-адресою.
Запити й вебхуки підписуються HMAC-SHA256 за міткою часу та сирим тілом вашим api_secret, допуск за часом ±120 секунд, плюс ключі ідемпотентності. Підписи порівнюються за сталий час, щоб унеможливити атаку за часом.
Створіть безкоштовний акаунт. Публічний api_key і секретний api_secret з’являться в кабінеті разом із SDK для завантаження та повним описом вебхуків. Ключі можна будь-коли перевипустити в налаштуваннях.
Підписана подія у JSON: ідентифікатор рахунка, ваш order_id, статус (наприклад, paid), сума й валюта, а також унікальний id події для ідемпотентності. Завжди перевіряйте підпис до зарахування замовлення й запам’ятовуйте id події, щоб повторна доставка не обробилася двічі.
Так. POST /v1/payout надсилає крипту на 500 гаманців одним запитом — по одному {address, amount, optional tag} на рядок, у будь-якій увімкненій у вас монеті. Та сама авторизація HMAC-SHA256 і той самий Idempotency-Key, що й в API рахунків, тож повтор запиту не створює другого пакета. Сума пакета плюс порядкова комісія резервується на балансі одразу; підписує та транслює оператор, після чого спрацьовує підписаний вебхук payout.sent. Перевірка сувора: одна хибна адреса або надто точна сума відхиляють увесь пакет (422), щоб зарплатний прогін не втратив одержувача мовчки.
Зберіть список одержувачів у себе, потім викличте POST /v1/payout один раз за прогін зі сталим Idempotency-Key (наприклад, payroll-2026-01). Опитуйте GET /v1/payout/{id} або дочекайтеся вебхука payout.sent, щоб підтвердити доставку й записати хеші. Надсилання пакета резервує кошти, але саме їх не рухає: підписує та транслює оператор, тому за одним викликом API нічого не йде.
Один PHP-SDK без залежностей: створити рахунок, надіслати на готовий чек-аут і перевірити підпис вебхука. Для будь-якої іншої мови є REST.