SDK PHP
Jeden plik, bez zależności. createInvoice(), getInvoice() i verifyWebhook() — wrzuć to do dowolnego projektu.
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.payora.moneyJedno wywołanie API z identyfikatorem zamówienia oraz kwotą w fiat lub kryptowalucie zwraca hostowany URL płatności.
Wybierają monetę, skanują kod QR lub otwierają portfel, a płatność jest potwierdzana na żywo po finalizacji.
Zweryfikuj podpis HMAC, zaksiegowane zamówienie raz, i obserwuj, jak płatność trafia na twoje saldo.
Jeden plik, bez zależności. createInvoice(), getInvoice() i verifyWebhook() — wrzuć to do dowolnego projektu.
Żądania i webhooki są podpisane HMAC-SHA256 z przesunięciem czasowym i kluczami idempotencyjnymi.
Zwykły JSON przez HTTPS — integruj z dowolnego stosu, nie tylko 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": … }Uzyskaj swój klucz API i sekret, tworząc konto. Pełne SDK znajduje się w twoim panelu.
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łówek | Wartość | Opis |
|---|---|---|
X-Payora-Key | pk_… | Twój publiczny api_key. Identyfikuje sklep. |
X-Payora-Timestamp | unix seconds | Moment, w którym podpisałeś żądanie, w sekundach Unix. |
X-Payora-Signature | hex · 64 | Małe litery hex HMAC-SHA256 znacznika czasu + "." + surowe ciało, kluczowane twoim api_secret. |
X-Payora-Test | 1 | Oznacza fakturę jako test twojej integracji: jest prawdziwa i może odbierać monety, ale nie wchodzi w raporty dotyczące popytu i konwersji. |
Idempotency-Key | string | Opcjonalne 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-Type | application/json | Wymagane w żądaniach, które zawierają ciało. |
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.
<?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"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.
| Parametr | Typ | Opis |
|---|---|---|
order_id | string · required | Twój unikalny identyfikator zamówienia (≤190 znaków). Powtórzenie odrzuca z kodem 409 — bezpieczne przed podwójnymi zgłoszeniami. |
amount | string · required | Kwota fiat (tryb=fiat) lub dokładna kwota kryptowaluty (tryb=crypto). |
mode | fiat | crypto | Domyślny fiat: stawka zablokowana na monetę przy kasie. kryptowaluta ustala monetę + kwotę z góry. |
fiat_currency | string | Kod fiat ISO dla trybu fiat (domyślnie USD). |
currency | string | Moneta dla trybu kryptowalut (np. TON, TRX, USDT_TRON). |
return_url | https URL | Gdzie przycisk checkoutu “Return to store” wysyła klienta z powrotem — na twoją stronę. Tylko absolutne http(s). |
lang | en·ru·uk·es·de | Ję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. |
ttl | seconds | Jak długo faktura pozostaje do zapłaty (120–86400 sekund, domyślnie 1800). |
customer_email | Opcjonalnie — paragon + wysłany do płacącego. | |
notes | string | Notatka 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.
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.
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.
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.
| Wydarzenie | status | Kiedy się uruchamia |
|---|---|---|
invoice.paid | paid | Płatność jest potwierdzona w łańcuchu. Zawiera kwotę, monetę i tx_hash. |
invoice.underpaid | underpaid | Faktura wygasła po tym, jak dotarła mniejsza kwota niż oczekiwana. |
invoice.expired | expired | Faktura wygasła bez otrzymania czegokolwiek. |
invoice.cancelled | cancelled | Faktura 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.sent | sent | Partia wypłat została podpisana i nadana. Zawiera każdy element z jego tx_hash. |
| Nagłówek | Wartość | Opis |
|---|---|---|
X-Payora-Id | uuid | Unikalny identyfikator zdarzenia, taki sam jak id w treści. Przechowuj go, aby zignorować powtórzenia. |
X-Payora-Event | invoice.paid | Nazwa wydarzenia. |
X-Payora-Timestamp | unix seconds | Kiedy ta próba została podpisana. |
X-Payora-Signature | hex · 64 | Ta sama zasada co w żądaniach: HMAC-SHA256 znacznika czasu + "." + surowe ciało z twoim api_secret. |
| Pole | Typ | Opis |
|---|---|---|
id | uuid | Identyfikator zdarzenia do de-duplikacji. |
event | string | Nazwa wydarzenia. |
invoice_id | int | Numer faktury Payora. |
order_id | string | Twój numer zamówienia, wysłany przy tworzeniu faktury. |
status | string | paid dla invoice.paid. |
currency | string | Moneta użyta przez płacącego, np. USDT_TRON. |
amount | decimal string | Kwota otrzymana. |
amount_units | integer string | Ta sama kwota w najmniejszych jednostkach monety — użyj jej do dokładnych porównań. |
expected | decimal string | Kwota, o którą prosiła faktura. |
fiat_amount | decimal string | null | Cena fiat faktury, jak ją utworzyłeś; null dla faktur w trybie kryptowalut. |
fiat_currency | string | null | Kod ISO fiat_amount; null dla faktur w trybie kryptowalut. |
tx_hash | string | Hash transakcji on-chain. |
paid_at | unix seconds | Kiedy zdarzenie zostało utworzone. |
test | bool | true dla faktur sandbox. |
{
"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.
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.
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 forgedWprowadź 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.
1758038400.{…}X-Payora-Timestamp: 1758038400
X-Payora-Signature: …Wklej podpis do porównania
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.
# 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 holdWalidacja 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.
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ńcowy | Dostęp | Opis |
|---|---|---|
GET/v1/health | no auth | Status usługi oraz lista włączonych walut. |
POST/v1/invoice | auth | Utwó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} | auth | Status faktury (tylko własne faktury): status, remaining oraz charge — waluta, adres, oczekiwane/otrzymane kwoty oraz tx_hash. |
POST/v1/payout | auth · 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/payout | auth | Wyświetl swoje ostatnie partie wypłat (?limit=, domyślnie 50). |
GET/v1/payout/{id} | auth | Status partii wypłat i przedmioty (tylko własne partie). |
POST/v1/payout/{id}/cancel | auth | Anuluj wciąż oczekującą partię i zwolnij zablokowany bilans. Zwraca 409, jeśli partia nie może być już anulowana. |
Brak dopasowanego punktu końcowego.
Pojedyncze pliki bez zależności. Każde SDK podpisuje żądania i weryfikuje webhooki w ten sam sposób.
PHP 7.4+ z cURL, jeden plik. createInvoice, getInvoice i verifyWebhook.
Node.js z wbudowanym https i tylko kryptografią. Faktury, saldo, wypłaty i verifyWebhook.
Tylko standardowa biblioteka Pythona. Faktury, saldo, wypłaty i verify_webhook.
Kolekcja Postman, która podpisuje każde wywołanie za Ciebie.
Specyfikacja maszynowo czytelna każdego punktu końcowego, dla generatorów kodu i klientów API.
Gotowy moduł robi to wszystko za Ciebie: faktura, przekierowanie i zweryfikowany webhook.
Proste odpowiedzi, w tym te niewygodne: przechowywanie, opłaty i co się dzieje, gdy coś pójdzie nie tak.
Centrum pomocyZainstaluj 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.
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.
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).
Żą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.
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ń.
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.
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.
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.
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.