Przejdź do treści
Deweloperzy

Zintegruj w kilka minut

Jedno SDK PHP bez zależności: twórz faktury, przekierowuj do hostowanego checkoutu i weryfikuj podpisane webhooki. REST jest dostępny dla każdego języka.

API w skrócie
  • Podstawowy URLapi.payora.money
  • AutoryzacjaHMAC-SHA256
  • FormatJSON · HTTPS
  • SDKiPHP · Node.js · Python
  • SpecyfikacjaOpenAPI 3.0
szybki start

Od faktury do webhooka

  1. 01

    Utwórz fakturę

    Jedno wywołanie API z identyfikatorem zamówienia oraz kwotą w fiat lub kryptowalucie zwraca hostowany URL płatności.

  2. 02

    Klient płaci

    Wybierają monetę, skanują kod QR lub otwierają portfel, a płatność jest potwierdzana na żywo po finalizacji.

  3. 03

    Otrzymujesz podpisany webhook

    Zweryfikuj podpis HMAC, zaksiegowane zamówienie raz, i obserwuj, jak płatność trafia na twoje saldo.

SDK PHP

Jeden plik, bez zależności. createInvoice(), getInvoice() i verifyWebhook() — wrzuć to do dowolnego projektu.

Autoryzacja HMAC

Żądania i webhooki są podpisane HMAC-SHA256 z przesunięciem czasowym i kluczami idempotencyjnymi.

REST API

Zwykły JSON przez HTTPS — integruj z dowolnego stosu, nie tylko 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

Uzyskaj swój klucz API i sekret, tworząc konto. Pełne SDK znajduje się w twoim panelu.

uwierzytelnianie

Autoryzacja

Każde wywołanie z wyjątkiem /v1/health niesie trzy podpisane nagłówki. Podpis dowodzi, że żądanie pochodzi od posiadacza twojego api_secret i nie zostało zmienione w drodze.

NagłówekWartośćOpis
X-Payora-Keypk_…Twój publiczny api_key. Identyfikuje sklep.
X-Payora-Timestampunix secondsMoment, w którym podpisałeś żądanie, w sekundach Unix.
X-Payora-Signaturehex · 64Małe litery hex HMAC-SHA256 znacznika czasu + "." + surowe ciało, kluczowane twoim api_secret.
X-Payora-Test1Oznacza fakturę jako test twojej integracji: jest prawdziwa i może odbierać monety, ale nie wchodzi w raporty dotyczące popytu i konwersji.
Idempotency-KeystringOpcjonalne w POST /v1/invoice i POST /v1/payout. Ponowne użycie tego samego klucza zwraca pierwszy wynik zamiast tworzyć duplikat; ten sam klucz z innym ciałem odpowiada 409.
Content-Typeapplication/jsonWymagane w żądaniach, które zawierają ciało.
X-Payora-Signature=hex( HMAC-SHA256( api_secret, timestamp + "." + raw_body ) )

Podpisz dokładne bajty, które wysyłasz. Ponowne kodowanie JSON po podpisaniu — nawet zmiana kolejności kluczy lub dodanie spacji — łamie podpis.

Dla żądania GET ciało jest puste, więc podpisany ciąg to znacznik czasu, a następnie kropka.

API odrzuca znacznik czasu, który jest oddalony o więcej niż 120 sekund od jego zegara. Utrzymuj swój serwer zsynchronizowany z NTP.

Przechowuj api_secret na swoim serwerze. Podpisuje zarówno żądania, jak i webhooki: kto go posiada, może tworzyć faktury w twoim imieniu i fałszować wywołania zwrotne.

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

Parametry faktury

Wszystko opcjonalne, z wyjątkiem order_id i amount. Tryb fiat pozwala płacącemu wybrać dowolną monetę włączoną na twoim koncie; tryb kryptowalutowy wymaga również currency.

ParametrTypOpis
order_idstring · requiredTwój unikalny identyfikator zamówienia (≤190 znaków). Powtórzenie odrzuca z kodem 409 — bezpieczne przed podwójnymi zgłoszeniami.
amountstring · requiredKwota fiat (tryb=fiat) lub dokładna kwota kryptowaluty (tryb=crypto).
modefiat | cryptoDomyślny fiat: stawka zablokowana na monetę przy kasie. kryptowaluta ustala monetę + kwotę z góry.
fiat_currencystringKod fiat ISO dla trybu fiat (domyślnie USD).
currencystringMoneta dla trybu kryptowalut (np. TON, TRX, USDT_TRON).
return_urlhttps URLGdzie przycisk checkoutu “Return to store” wysyła klienta z powrotem — na twoją stronę. Tylko absolutne http(s).
langen·ru·uk·es·deJęzyk checkoutu, aby klient z twojego rosyjskiego sklepu widział rosyjski checkout — a nie angielski. Można również ustawić jako ?lang=ru na adresie URL płatności.
ttlsecondsJak długo faktura pozostaje do zapłaty (120–86400 sekund, domyślnie 1800).
customer_emailemailOpcjonalnie — paragon + wysłany do płacącego.
notesstringNotatka w formie wolnej przechowywana na fakturze.

return_url i lang również działają jako parametry zapytania dodane do pay_url, które daje ci API — <pay_url>&lang=ru&return_url=https://shop.example/thanks. Zawsze wysyłaj kupującego do pay_url zwróconego przez API: zawiera on token dostępu na jedną fakturę, więc strona kasy nie może być osiągnięta przez zgadywanie numerów faktur. Nie odbudowuj linku z identyfikatora faktury.

Kreator żądań

Zbuduj podpisane żądanie faktury

Wypełnij pola i skopiuj gotowe polecenie cURL. Podpisuje się samo w twoim terminalu za pomocą $PAYORA_KEY i $PAYORA_SECRET — ta strona nigdy nie widzi twoich kluczy i nic nie wysyła.

mode
POST /v1/invoice
BODY='{"order_id":"ORDER-42","mode":"fiat","amount":"9.99","fiat_currency":"USD","return_url":"https://shop.example/thanks","lang":"pl","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"

Nic nie jest wysyłane z tej strony.

webhooki

Webhooki

Gdy faktura lub wypłata zmienia stan, Payora wysyła podpisane zdarzenie JSON do twojego adresu URL zwrotnego. Najpierw zweryfikuj podpis, zakredytuj zamówienie raz, odpowiedz 2xx.

WydarzeniestatusKiedy się uruchamia
invoice.paidpaidPłatność jest potwierdzona w łańcuchu. Zawiera kwotę, monetę i tx_hash.
invoice.underpaidunderpaidFaktura wygasła po tym, jak dotarła mniejsza kwota niż oczekiwana.
invoice.expiredexpiredFaktura wygasła bez otrzymania czegokolwiek.
invoice.cancelledcancelledFaktura została anulowana. Pieniądze, które już dotarły, jeśli w ogóle, są opisane w zdarzeniu.
invoice.cancel_settled—Pieniądze, które dotarły na anulowanej fakturze, zostały rozliczone: zaksięgowane lub odesłane.
invoice.late_payment—Pieniądze, które wpłynęły na fakturę po jej anulowaniu. Wysłane raz dla każdego takiego depozytu; wynik mówi, czy zostały zaksięgowane, czy są zwracane.
payout.sentsentPartia wypłat została podpisana i nadana. Zawiera każdy element z jego tx_hash.

Nagłówki każdej dostawy

NagłówekWartośćOpis
X-Payora-IduuidUnikalny identyfikator zdarzenia, taki sam jak id w treści. Przechowuj go, aby zignorować powtórzenia.
X-Payora-Eventinvoice.paidNazwa wydarzenia.
X-Payora-Timestampunix secondsKiedy ta próba została podpisana.
X-Payora-Signaturehex · 64Ta sama zasada co w żądaniach: HMAC-SHA256 znacznika czasu + "." + surowe ciało z twoim api_secret.

ładunek invoice.paid

PoleTypOpis
iduuidIdentyfikator zdarzenia do de-duplikacji.
eventstringNazwa wydarzenia.
invoice_idintNumer faktury Payora.
order_idstringTwój numer zamówienia, wysłany przy tworzeniu faktury.
statusstringpaid dla invoice.paid.
currencystringMoneta użyta przez płacącego, np. USDT_TRON.
amountdecimal stringKwota otrzymana.
amount_unitsinteger stringTa sama kwota w najmniejszych jednostkach monety — użyj jej do dokładnych porównań.
expecteddecimal stringKwota, o którą prosiła faktura.
fiat_amountdecimal string | nullCena fiat faktury, jak ją utworzyłeś; null dla faktur w trybie kryptowalut.
fiat_currencystring | nullKod ISO fiat_amount; null dla faktur w trybie kryptowalut.
tx_hashstringHash transakcji on-chain.
paid_atunix secondsKiedy zdarzenie zostało utworzone.
testbooltrue dla faktur sandbox.
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
}

Gdy kwota otrzymana różni się od faktury, amount_received i amount_expected są dodawane.

Dostawa i ponowne próby

Wszystko inne niż 2xx lub brak odpowiedzi w ciągu 15 sekund jest ponawiane z wykładniczym opóźnieniem, ograniczonym do jednej godziny między próbami — do 12 prób. Każda próba jest ponownie podpisywana z nowym znacznikiem czasu; ciało i identyfikator zdarzenia pozostają takie same, więc de-duplikuj po id.

Po ostatniej próbie zdarzenie jest oznaczane jako nieudane, a właściciel sklepu otrzymuje e-mail. Przekierowania nigdy nie są śledzone, a adres URL zwrotny musi być dostępny z internetu — brak localhost lub prywatnych adresów.

Zanim zaksięgujesz zamówienie

  • Przeczytaj surowe ciało przed jakimkolwiek parsowaniem JSON.
  • Ponownie oblicz podpis i porównaj w stałym czasie: hash_equals, crypto.timingSafeEqual, hmac.compare_digest.
  • Odrzuć znaczniki czasu poza twoim oknem — SDK akceptują ±300 sekund.
  • Sprawdź status i kwotę w odniesieniu do twojego zamówienia, a następnie zaksięguj raz na identyfikator zdarzenia.
  • Szybko odpowiadaj na 2xx i wykonuj wolną pracę po odpowiedzi.
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
Plac zabaw

Plac zabaw dla podpisów webhooków

Wprowadź sekret, znacznik czasu i surowe dane, aby zobaczyć dokładny podpis, który Payora by wysłała — lub sprawdź ten, który otrzymałeś.

Działa w twojej przeglądarce z WebCrypto. Nic, co wpiszesz, nie opuszcza tej strony. Użyj sekretu testowego, a nie na żywo, na wspólnym komputerze.

X-Payora-Timestamp
Podpisany ciąg
1758038400.{…}
Nagłówki wysyłane przez Payora
headers
X-Payora-Timestamp: 1758038400
X-Payora-Signature: …

Wklej podpis do porównania

masowe wypłaty

API masowych wypłat

Wyślij kryptowalutę do maksymalnie 500 portfeli w jednym podpisanym, idempotentnym żądaniu — dla payroll, wypłat afiliacyjnych lub wypłat. Całkowita kwota partii plus opłata za pozycję jest natychmiast zatrzymywana na twoim internal balance; operator podpisuje i nadaje, a następnie uruchamia się podpisany payout.sent webhook. Ta sama autoryzacja HMAC jak w przypadku wszystkiego innego.

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

Walidacja jest surowa: każdy zły adres lub zbyt precyzyjna kwota odrzuca całą partię (HTTP 422) z indeksami problematycznych przedmiotów — proces płacowy nigdy nie pomija cicho odbiorcy. Anuluj wciąż oczekującą partię za pomocą POST /v1/payout/{id}/cancel, aby zwolnić blokadę. Zobacz opis architektury.

referencja

Referencja punktu końcowego

Każdy punkt końcowy komunikuje się w prostym JSON przez HTTPS na api.payora.money. Wszystkie oprócz /v1/health używają tej samej autoryzacji HMAC-SHA256. Specyfikacja czytelna maszynowo znajduje się pod adresem openapi.json.

Punkt końcowyDostępOpis
GET/v1/healthno authStatus usługi oraz lista włączonych walut.
POST/v1/invoiceauthUtwórz fakturę (tryb fiat lub kryptowalutowy). Wspiera Idempotency-Key. Zwraca 201 z invoice_id, status, pay_url i expires; tryb kryptowalutowy dodaje adres, kwotę i deeplink.
GET/v1/invoice/{id}authStatus faktury (tylko własne faktury): status, remaining oraz charge — waluta, adres, oczekiwane/otrzymane kwoty oraz tx_hash.
POST/v1/payoutauth · Pro+Utwórz masową partię wypłat (ścisła walidacja, środki zablokowane natychmiast). Wspiera Idempotency-Key. Zwraca 201 z widokiem partii: batch_id, status, sumy, opłata, przedmioty.
GET/v1/payoutauthWyświetl swoje ostatnie partie wypłat (?limit=, domyślnie 50).
GET/v1/payout/{id}authStatus partii wypłat i przedmioty (tylko własne partie).
POST/v1/payout/{id}/cancelauthAnuluj wciąż oczekującą partię i zwolnij zablokowany bilans. Zwraca 409, jeśli partia nie może być już anulowana.
pobrania

SDK i pobrania

Pojedyncze pliki bez zależności. Każde SDK podpisuje żądania i weryfikuje webhooki w ten sam sposób.

phpPHPPayora.php

PHP 7.4+ z cURL, jeden plik. createInvoice, getInvoice i verifyWebhook.

jsNode.jspayora.js

Node.js z wbudowanym https i tylko kryptografią. Faktury, saldo, wypłaty i verifyWebhook.

pyPythonpayora.py

Tylko standardowa biblioteka Pythona. Faktury, saldo, wypłaty i verify_webhook.

{ }Postmanpayora.postman_collection.json

Kolekcja Postman, która podpisuje każde wywołanie za Ciebie.

{…}OpenAPI 3.0openapi.json

Specyfikacja maszynowo czytelna każdego punktu końcowego, dla generatorów kodu i klientów API.

api.payora.moneyOtwórz
Używasz WooCommerce, WHMCS, Magento lub innego CMS-a?

Gotowy moduł robi to wszystko za Ciebie: faktura, przekierowanie i zweryfikowany webhook.

Przeglądaj wtyczki
FAQ

Najczęściej zadawane pytania

Proste odpowiedzi, w tym te niewygodne: przechowywanie, opłaty i co się dzieje, gdy coś pójdzie nie tak.

Centrum pomocy

Jak zintegrować Payora?

Zainstaluj jednofunkcyjny SDK PHP (bez zależności) lub wywołaj REST API bezpośrednio. Utwórz fakturę za pomocą createInvoice(), przekieruj klienta do jego pay_url i obsłuż jedno zdarzenie webhook: status=paid. Kompetentny programista jest dostępny w ciągu 30–60 minut.

Czy istnieje REST API dla stosów nie-PHP?

Tak. Wszystko to czysty JSON przez HTTPS, więc możesz integrować z dowolnego języka. SDK PHP to wygodny wrapper wokół tych samych punktów końcowych — utwórz fakturę, pobierz fakturę i zweryfikuj podpisy webhook.

Czy klient może wrócić na moją stronę po dokonaniu płatności, w odpowiednim języku?

Tak. Przekaż return_url, gdy tworzysz fakturę (lub ?return_url= w linku płatności), a proces zakupu wyświetli przycisk „Powrót do sklepu” na ekranie sukcesu — oraz podczas płatności. Przekaż lang (en, ru, uk, es, de) lub ?lang= w linku, aby klient z twojego rosyjskiego sklepu trafił na rosyjski proces zakupu zamiast angielskiego. Oba są opcjonalne; return_url musi być absolutnym adresem http(s).

Jak obsługiwana jest autoryzacja API?

Żądania i webhooki są autoryzowane za pomocą HMAC-SHA256 na podstawie znacznika czasu i surowego ciała przy użyciu twojego api_secret, z ±120-sekundowym oknem przesunięcia i kluczami idempotencyjnymi. Podpisy są porównywane w stałym czasie, aby zapobiec atakom czasowym.

Jak zdobyć klucze API?

Utwórz darmowe konto. Twój publiczny api_key i tajny api_secret pojawią się w panelu, wraz z do pobrania SDK i pełną dokumentacją webhook. Zmieniaj klucze w dowolnym momencie z ustawień.

Co zawiera ładunek webhook?

Podpisane zdarzenie JSON z identyfikatorem faktury, twoim order_id, statusem (na przykład opłacone), kwotą i walutą oraz unikalnym identyfikatorem zdarzenia dla idempotencji. Zawsze weryfikuj podpis przed zaksięgowaniem zamówienia, a następnie zapisz identyfikator zdarzenia, aby uniknąć podwójnego przetwarzania przy ponownych próbach.

Czy istnieje API do masowych wypłat kryptowalut?

Tak. POST /v1/payout wysyła kryptowalutę do maksymalnie 500 portfeli w jednym żądaniu — jeden {adres, kwota, opcjonalny tag} na przedmiot, w dowolnej walucie włączonej na twoim koncie. Używa tego samego uwierzytelnienia HMAC-SHA256 i klucza Idempotency-Key co API faktur, więc ponowione żądanie nigdy nie tworzy duplikatu partii. Całkowita kwota partii plus opłata za przedmiot jest natychmiast rezerwowana na twoim saldzie; operator podpisuje i nadaje, a następnie uruchamia webhook wypłaty. Walidacja jest rygorystyczna — każdy nieprawidłowy adres lub zbyt precyzyjna kwota odrzuca całą partię (422), więc uruchomienie listy płac nigdy nie pomija cicho odbiorcy.

Jak zautomatyzować wypłaty wynagrodzeń w kryptowalutach lub wypłaty dla partnerów?

Zbuduj listę odbiorców w swoim systemie, a następnie wywołaj POST /v1/payout raz na uruchomienie z stabilnym Idempotency-Key (na przykład payroll-2026-01). Sprawdź GET /v1/payout/{id} lub poczekaj na webhook payout.sent, aby potwierdzić dostawę i zarejestrować każdy hash transakcji. Złożenie partii rezerwuje środki, ale samo w sobie ich nie przenosi — operator podpisuje i nadaje, więc nic nie opuszcza na samym wywołaniu API.

Pobierz swoje klucze API

Jedno SDK PHP bez zależności: twórz faktury, przekierowuj do hostowanego checkoutu i weryfikuj podpisane webhooki. REST jest dostępny dla każdego języka.

Na co odpowiada ta strona