До вмісту
Розробникам

Інтеграція за лічені хвилини

Один PHP-SDK без залежностей: створити рахунок, надіслати на готовий чек-аут і перевірити підпис вебхука. Для будь-якої іншої мови є REST.

API коротко
  • Базова адресаapi.payora.money
  • АвтентифікаціяHMAC-SHA256
  • ФорматJSON · HTTPS
  • SDKPHP · Node.js · Python
  • СпецифікаціяOpenAPI 3.0
швидкий старт

Від рахунка до вебхука

  1. 01

    Створіть рахунок

    Один виклик API з номером замовлення та сумою у фіаті чи крипті повертає посилання на оплату.

  2. 02

    Клієнт платить

    Він обирає монету, сканує QR або відкриває гаманець — оплата підтверджується наживо після фіналізації.

  3. 03

    Ви отримуєте підписаний вебхук

    Перевірте підпис HMAC, зарахуйте замовлення один раз — і платіж уже на вашому балансі.

PHP-SDK

Один файл, без залежностей. createInvoice(), getInvoice() і verifyWebhook() — кладеться в будь-який проєкт.

Автентифікація HMAC

Запити й вебхуки підписані HMAC-SHA256 з допуском за часом і ключами ідемпотентності.

REST API

Звичайний JSON поверх HTTPS — інтеграція з будь-якого стека, не лише з PHP.

checkout
<?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 retries

Отримайте свій API key і secret, створивши акаунт. Повний SDK — у вашій панелі.

автентифікація

Автентифікація

Кожен виклик, крім /v1/health, несе три підписані заголовки. Підпис доводить, що запит надіслав власник вашого api_secret і дорогою його не змінили.

ЗаголовокЗначенняОпис
X-Payora-Keypk_…Ваш публічний api_key. Визначає магазин.
X-Payora-Timestampunix secondsМомент підпису запиту, у секундах Unix.
X-Payora-Signaturehex · 64HMAC-SHA256 від timestamp + "." + сире тіло на ключі api_secret, малими літерами hex.
X-Payora-Test1Позначає рахунок як перевірку інтеграції: рахунок справжній і може прийняти монети, але в показники попиту та конверсії не йде.
Idempotency-KeystringНеобов’язковий для POST /v1/invoice і POST /v1/payout. Повтор із тим самим ключем повертає перший результат замість дубліката; той самий ключ з іншим тілом отримує 409.
Content-Typeapplication/jsonОбов’язковий для запитів із тілом.
X-Payora-Signature=hex( HMAC-SHA256( api_secret, timestamp + "." + raw_body ) )

Підписуйте саме ті байти, які надсилаєте. Повторне кодування JSON після підпису — навіть інший порядок ключів чи зайвий пробіл — ламає підпис.

У GET-запиту тіло порожнє, тож підписується timestamp із крапкою в кінці.

API відхиляє timestamp, що розходиться з його годинником більш ніж на 120 секунд. Синхронізуйте час сервера через NTP.

Зберігайте api_secret лише на сервері. Ним підписуються і запити, і вебхуки: хто його має, той може створювати рахунки від вашого імені й підробляти сповіщення.

sign-request
<?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);
POST /v1/invoice

Параметри рахунка

Усе необов’язкове, крім order_id та amount. У режимі fiat платник може обрати будь-яку монету, увімкнену у вашому акаунті; режиму crypto також потрібен currency.

ПараметрТипОпис
order_idstring · requiredВаш унікальний ідентифікатор замовлення (≤190 символів). Повтор відхиляється з 409 — захист від подвійного надсилання.
amountstring · requiredСума у фіаті (mode=fiat) або точна сума у крипті (mode=crypto).
modefiat | cryptoЗа замовчуванням fiat: курс фіксується для кожної монети на checkout. crypto заздалегідь фіксує монету та суму.
fiat_currencystringISO-код фіату для режиму fiat (default USD).
currencystringМонета для режиму crypto (наприклад, TON, TRX, USDT_TRON).
return_urlhttps URLКуди кнопка «Повернутися до магазину» на checkout повертає клієнта — на ваш сайт. Лише абсолютний http(s).
langen·ru·uk·es·deМова checkout, щоб клієнт із вашого російського магазину бачив checkout російською, а не англійською. Також задається як ?lang=ru в URL оплати.
ttlsecondsСкільки рахунок лишається доступним для оплати (120–86400 секунд, типово 1800).
customer_emailemailНеобов'язково — потрапляє в чек і надсилається платнику поштою.
notesstringДовільна нотатка, що зберігається в рахунку.

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 — ця сторінка не бачить ваших ключів і нічого не надсилає.

mode
POST /v1/invoice
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.paidpaidПлатіж підтверджено в мережі. Містить суму, монету й tx_hash.
invoice.underpaidunderpaidСтрок рахунку минув, а надійшло менше за очікувану суму.
invoice.expiredexpiredСтрок рахунку минув, оплати не було.
invoice.cancelledcancelledРахунок скасовано. Якщо гроші вже надійшли, це описано в події.
invoice.cancel_settled—З грошима, що надійшли на скасований рахунок, усе вирішено: зараховано або повернено.
invoice.late_payment—Гроші надійшли на рахунок уже після його скасування. Надсилається на кожне таке надходження; у result — зараховано їх чи вони повертаються.
payout.sentsentПакет виплат підписано й надіслано в мережу. Містить кожну виплату з її tx_hash.

Заголовки кожної доставки

ЗаголовокЗначенняОпис
X-Payora-IduuidУнікальний id події, той самий, що id у тілі. Зберігайте його, щоб пропускати повтори.
X-Payora-Eventinvoice.paidНазва події.
X-Payora-Timestampunix secondsКоли підписано цю спробу.
X-Payora-Signaturehex · 64Та сама схема, що в запитів: HMAC-SHA256 від timestamp + "." + сире тіло на ключі api_secret.

Тіло invoice.paid

ПолеТипОпис
iduuidId події для захисту від повторів.
eventstringНазва події.
invoice_idintНомер рахунку в Payora.
order_idstringВаш номер замовлення, як його передали під час створення рахунку.
statusstringpaid для invoice.paid.
currencystringМонета, якою заплатили, наприклад USDT_TRON.
amountdecimal stringОтримана сума.
amount_unitsinteger stringТа сама сума в найменших одиницях монети — для точних порівнянь.
expecteddecimal stringСума, виставлена в рахунку.
fiat_amountdecimal string | nullЦіна рахунку у фіаті, як ви її виставили; null у рахунків у крипто-режимі.
fiat_currencystring | nullISO-код валюти fiat_amount; null у рахунків у крипто-режимі.
tx_hashstringХеш транзакції в мережі.
paid_atunix secondsКоли створено подію.
testbooltrue для тестових рахунків.
invoice.paid
{
    "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 і приватних адрес.

Перш ніж зарахувати замовлення

  • Читайте сире тіло до будь-якого розбору JSON.
  • Перерахуйте підпис і порівняйте за сталий час: hash_equals, crypto.timingSafeEqual, hmac.compare_digest.
  • Відхиляйте timestamp поза своїм вікном — SDK приймають ±300 секунд.
  • Звірте статус і суму із замовленням, потім зараховуйте один раз на id події.
  • Відповідайте 2xx швидко, а довгу роботу робіть після відповіді.
webhook
<?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
Пісочниця

Пісочниця підпису вебхука

Введіть секрет, timestamp і сире тіло — і побачите саме той підпис, який надішле Payora. Або перевірте отриманий.

Працює у вашому браузері через WebCrypto. Ніщо з введеного не залишає цю сторінку. На чужому комп’ютері використовуйте тестовий секрет, а не бойовий.

X-Payora-Timestamp
Рядок для підпису
1758038400.{…}
Заголовки, які надішле Payora
headers
X-Payora-Timestamp: 1758038400
X-Payora-Signature: …

Вставте підпис для порівняння

масові виплати

API масових виплат

Надсилайте крипту на 500 гаманців одним підписаним ідемпотентним запитом — зарплата, партнерські виплати, виведення. Сума пакета плюс порядкова комісія одразу утримується на внутрішньому балансі; далі оператор підписує й транслює, і спрацьовує підписаний вебхук payout.sent. Авторизація HMAC та сама, що й усюди.

payout
# 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: …' …

Перевірка сувора: будь-яка невірна адреса або сума з надмірною точністю відхиляють увесь пакет (HTTP 422) з індексами проблемних позицій — під час виплати зарплат жоден отримувач не зникне мовчки. Скасуйте пакет, що ще очікує, через POST /v1/payout/{id}/cancel, щоб зняти утримання. Див. розбір архітектури.

довідник

Довідник адрес API

Кожен ендпоінт спілкується звичайним JSON поверх HTTPS за адресою api.payora.money. Усі, крім /v1/health, використовують ту саму автентифікацію запитів за HMAC-SHA256. Машиночитана специфікація доступна за адресою openapi.json.

МетодДоступОпис
GET/v1/healthno authСтатус сервісу плюс список увімкнених валют.
POST/v1/invoiceauthСтворіть рахунок (режим 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/payoutauth · Pro+Створіть пакет масових виплат (сувора перевірка, кошти утримуються миттєво). Підтримує Idempotency-Key. Повертає 201 з поданням пакета: batch_id, status, підсумки, комісія, позиції.
GET/v1/payoutauthСписок ваших нещодавніх пакетів виплат (?limit=, default 50).
GET/v1/payout/{id}authСтатус пакета виплат та його позиції (лише власні пакети).
POST/v1/payout/{id}/cancelauthСкасуйте пакет, що ще очікує, і звільніть утриманий баланс. Повертає 409, якщо пакет уже не можна скасувати.
завантаження

SDK і завантаження

Окремі файли без залежностей. Усі SDK однаково підписують запити й перевіряють вебхуки.

phpPHPPayora.php

PHP 7.4+ і cURL, один файл. createInvoice, getInvoice і verifyWebhook.

jsNode.jspayora.js

Node.js лише з вбудованими https і crypto. Рахунки, баланс, виплати й verifyWebhook.

pyPythonpayora.py

Лише стандартна бібліотека Python. Рахунки, баланс, виплати й verify_webhook.

{ }Postmanpayora.postman_collection.json

Колекція Postman, яка сама підписує кожен виклик.

{…}OpenAPI 3.0openapi.json

Машинозчитувана специфікація всіх методів — для генераторів коду й API-клієнтів.

api.payora.moneyВідкрити
У вас WooCommerce, WHMCS, Magento чи інша CMS?

Готовий модуль зробить усе це за вас: рахунок, перехід до оплати й перевірений вебхук.

Каталог плагінів
Питання

Часто задавані питання

Прямі відповіді, зокрема на незручні питання: зберігання коштів, комісії та що буде, якщо щось піде не так.

Довідковий центр

Як інтегрувати Payora?

Поставте однофайловий PHP-SDK (без залежностей) або звертайтеся до REST API напряму. Створіть рахунок через createInvoice(), надішліть покупця на його pay_url і обробіть одну подію вебхука: status=paid. Досвідчений розробник запускається за 30–60 хвилин.

Чи є REST API для не-PHP?

Так. Усе це звичайний JSON поверх HTTPS, тому інтегруватися можна з будь-якої мови. PHP-SDK — просто зручна обгортка над тими самими адресами: створити рахунок, отримати рахунок і перевірити підпис вебхука.

Чи повернеться покупець після оплати на мій сайт і потрібною мовою?

Так. Передайте return_url під час створення рахунка (або ?return_url= у платіжному посиланні) — і на екрані успіху, і під час оплати чек-аут покаже кнопку «Повернутися до магазину». Передайте lang (en, ru, uk, es, de) або ?lang= у посиланні, щоб покупець із вашого українського магазину потрапив на український чек-аут, а не на англійський. Обидва параметри необов’язкові; return_url має бути абсолютною http(s)-адресою.

Як влаштована автентифікація API?

Запити й вебхуки підписуються HMAC-SHA256 за міткою часу та сирим тілом вашим api_secret, допуск за часом ±120 секунд, плюс ключі ідемпотентності. Підписи порівнюються за сталий час, щоб унеможливити атаку за часом.

Як отримати ключі API?

Створіть безкоштовний акаунт. Публічний api_key і секретний api_secret з’являться в кабінеті разом із SDK для завантаження та повним описом вебхуків. Ключі можна будь-коли перевипустити в налаштуваннях.

Що приходить у вебхуку?

Підписана подія у JSON: ідентифікатор рахунка, ваш order_id, статус (наприклад, paid), сума й валюта, а також унікальний id події для ідемпотентності. Завжди перевіряйте підпис до зарахування замовлення й запам’ятовуйте id події, щоб повторна доставка не обробилася двічі.

Чи є API для масових крипто-виплат?

Так. 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 нічого не йде.

Отримати ключі API

Один PHP-SDK без залежностей: створити рахунок, надіслати на готовий чек-аут і перевірити підпис вебхука. Для будь-якої іншої мови є REST.

На які запити відповідає ця сторінка