Salta al contenuto
Sviluppatori

Integra in pochi minuti

Un singolo SDK PHP senza dipendenze: crea fatture, reindirizza al checkout ospitato e verifica i webhook firmati. REST è disponibile per qualsiasi linguaggio.

API in sintesi
  • URL di baseapi.payora.money
  • AutenticazioneHMAC-SHA256
  • FormatoJSON · HTTPS
  • SDKPHP · Node.js · Python
  • SpecificheOpenAPI 3.0
avvio rapido

Dalla fattura al webhook

  1. 01

    Crea una fattura

    Una chiamata API con un ID ordine e un importo in fiat o criptovaluta restituisce un URL di pagamento ospitato.

  2. 02

    Il cliente paga

    Scelgono una moneta, scansionano il QR o aprono un portafoglio, e il checkout conferma in tempo reale sulla finalità.

  3. 03

    Ricevi un webhook firmato

    Verifica la firma HMAC, accredita l'ordine una volta e guarda il pagamento arrivare sul tuo saldo.

SDK PHP

Un file, nessuna dipendenza. createInvoice(), getInvoice() e verifyWebhook() — inseriscilo in qualsiasi progetto.

Autenticazione HMAC

Le richieste e i webhook sono firmati HMAC-SHA256 con skew di timestamp e chiavi di idempotenza.

API REST

JSON semplice su HTTPS — integra da qualsiasi stack, non solo 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

Ottieni la tua chiave API e il segreto creando un account. Il SDK completo è nel tuo dashboard.

autenticazione

Autenticazione

Every call except /v1/health carries three signed headers. The signature proves the request comes from the holder of your api_secret and was not changed on the way.

IntestazioneValoreDescrizione
X-Payora-Keypk_…Il tuo api_key pubblico. Identifica il negozio.
X-Payora-Timestampunix secondsIl momento in cui hai firmato la richiesta, in secondi Unix.
X-Payora-Signaturehex · 64HMAC-SHA256 esadecimale in minuscolo di timestamp + "." + corpo raw, chiave con il tuo api_secret.
X-Payora-Test1Segna una fattura come un test della tua integrazione: è reale e può ricevere monete, ma rimane esclusa dai rapporti di domanda e conversione.
Idempotency-KeystringOpzionale su POST /v1/invoice e POST /v1/payout. Un tentativo con la stessa chiave restituisce il primo risultato invece di creare un duplicato; la stessa chiave con un corpo diverso risponde 409.
Content-Typeapplication/jsonRichiesto su richieste che portano un corpo.
X-Payora-Signature=hex( HMAC-SHA256( api_secret, timestamp + "." + raw_body ) )

Firma esattamente i byte che invii. La ricodifica del JSON dopo la firma — anche riordinando le chiavi o aggiungendo uno spazio — rompe la firma.

Per una richiesta GET il corpo è vuoto, quindi la stringa firmata è il timestamp seguito da un punto.

L'API rifiuta un timestamp più di 120 secondi lontano dal suo orologio. Tieni il tuo server sincronizzato con NTP.

Tieni api_secret sul tuo server. Firma richieste e webhook allo stesso modo: chiunque lo detenga può creare fatture a tuo nome e falsificare callback.

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

Parametri della fattura

Tutti opzionali tranne order_id e amount. La modalità fiat consente al pagatore di scegliere qualsiasi moneta abilitata sul tuo account; la modalità crypto richiede anche currency.

ParametroTipoDescrizione
order_idstring · requiredIl tuo riferimento d'ordine unico (≤190 caratteri). Una ripetizione viene rifiutata con 409 — sicura contro invii doppi.
amountstring · requiredImporto fiat (mode=fiat) o importo crypto esatto (mode=crypto).
modefiat | cryptoFiat predefinito: tasso bloccato per moneta al checkout. La crypto fissa la moneta + l'importo in anticipo.
fiat_currencystringCodice fiat ISO per la modalità fiat (predefinito USD).
currencystringMoneta per la modalità crypto (es. TON, TRX, USDT_TRON).
return_urlhttps URLDove il pulsante “Return to store” del checkout riporta il cliente indietro — il tuo sito. Solo http(s) assoluto.
langen·ru·uk·es·deLingua del checkout, quindi un cliente del tuo negozio russo vede il checkout russo — non in inglese. Impostabile anche come ?lang=ru sull'URL di pagamento.
ttlsecondsQuanto tempo la fattura rimane pagabile (120–86400 secondi, default 1800).
customer_emailemailOpzionale — ricevuta + inviata via email al pagatore.
notesstringNota libera memorizzata sulla fattura.

return_url e lang funzionano anche come parametri di query aggiunti al pay_url fornito dall'API — <pay_url>&lang=ru&return_url=https://shop.example/thanks. Invia sempre l'acquirente al pay_url restituito dall'API: contiene un token di accesso unico per fattura, quindi una pagina di checkout non può essere raggiunta indovinando i numeri delle fatture. Non ricostruire il link dall'id della fattura.

Costruttore di richieste

Crea una richiesta di fattura firmata

Compila i campi e copia un comando cURL pronto. Si firma da solo nella tua shell con $PAYORA_KEY e $PAYORA_SECRET — questa pagina non vede mai le tue chiavi e non invia nulla.

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

Niente viene inviato da questa pagina.

webhook

Webhook

Quando una fattura o un pagamento cambia stato, Payora invia un evento JSON firmato al tuo URL di callback. Verifica prima la firma, accredita l'ordine una volta, rispondi 2xx.

EventostatusQuando si attiva
invoice.paidpaidIl pagamento è confermato on-chain. Contiene l'importo, la moneta e tx_hash.
invoice.underpaidunderpaidLa fattura è scaduta dopo che è arrivato meno dell'importo previsto.
invoice.expiredexpiredLa fattura è scaduta senza ricevere nulla.
invoice.cancelledcancelledLa fattura è stata annullata. Il denaro che era già arrivato, se presente, è descritto nell'evento.
invoice.cancel_settled—Il denaro che è arrivato su una fattura annullata è stato gestito: accreditato o restituito.
invoice.late_payment—Denaro che è arrivato su una fattura dopo che è stata annullata. Inviato una sola volta per ogni deposito di questo tipo; il risultato indica se è stato accreditato o se viene restituito.
payout.sentsentUn lotto di pagamento è stato firmato e trasmesso. Contiene ogni elemento con il suo tx_hash.

Intestazioni di ogni consegna

IntestazioneValoreDescrizione
X-Payora-IduuidID evento unico, lo stesso di id nel corpo. Conservalo per ignorare i ripetuti.
X-Payora-Eventinvoice.paidNome dell'evento.
X-Payora-Timestampunix secondsQuando questo tentativo è stato firmato.
X-Payora-Signaturehex · 64Stessa modalità delle richieste: HMAC-SHA256 di timestamp + "." + corpo raw con il tuo api_secret.

payload invoice.paid

CampoTipoDescrizione
iduuidID evento per la deduplicazione.
eventstringNome dell'evento.
invoice_idintNumero fattura Payora.
order_idstringIl tuo riferimento ordine, come inviato quando è stata creata la fattura.
statusstringpaid per invoice.paid.
currencystringMoneta utilizzata dal pagatore, ad es. USDT_TRON.
amountdecimal stringImporto ricevuto.
amount_unitsinteger stringLo stesso importo nelle unità più piccole della moneta — usalo per confronti esatti.
expecteddecimal stringImporto richiesto dalla fattura.
fiat_amountdecimal string | nullPrezzo fiat della fattura come l'hai creata; null per le fatture in modalità crypto.
fiat_currencystring | nullCodice ISO di fiat_amount; null per le fatture in modalità crypto.
tx_hashstringHash della transazione on-chain.
paid_atunix secondsQuando è stato creato l'evento.
testbooltrue per fatture 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
}

Quando l'importo ricevuto differisce dalla fattura, amount_received e amount_expected vengono aggiunti.

Consegna e ripetizioni

Qualsiasi cosa diversa da 2xx, o nessuna risposta entro 15 secondi, viene ripetuta con un backoff esponenziale limitato a un'ora tra i tentativi — fino a 12 tentativi. Ogni tentativo è nuovamente firmato con un nuovo timestamp; il corpo e l'ID evento rimangono gli stessi, quindi deduplica per ID.

Dopo l'ultimo tentativo, l'evento è contrassegnato come fallito e il proprietario del negozio riceve un'email. I reindirizzamenti non vengono mai seguiti e l'URL di callback deve essere raggiungibile da Internet — niente indirizzi localhost o privati.

Prima di accreditare un ordine

  • Leggi il corpo raw prima di qualsiasi parsing JSON.
  • Ricalcola la firma e confronta in tempo costante: hash_equals, crypto.timingSafeEqual, hmac.compare_digest.
  • Rifiuta i timestamp al di fuori della tua finestra — gli SDK accettano ±300 secondi.
  • Controlla lo stato e l'importo rispetto al tuo ordine, quindi accredita una volta per ID evento.
  • Rispondi rapidamente con 2xx e fai lavori lenti dopo aver risposto.
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
Playground

Area di test della firma del webhook

Inserisci un segreto, un timestamp e il corpo raw per vedere la firma esatta che Payora invierebbe — o controlla una che hai ricevuto.

Funziona nel tuo browser con WebCrypto. Nulla di ciò che digiti lascia questa pagina. Usa un segreto di test, non uno reale, su un computer condiviso.

X-Payora-Timestamp
Stringa firmata
1758038400.{…}
Intestazioni inviate da Payora
headers
X-Payora-Timestamp: 1758038400
X-Payora-Signature: …

Incolla una firma da confrontare

pagamenti di massa

API di pagamento di massa

Invia crypto a un massimo di 500 portafogli in una richiesta firmata e idempotente — per payroll, pagamenti affiliati o prelievi. Il totale del batch più la commissione per articolo è trattenuto sul tuo internal balance istantaneamente; il operatore firma e trasmette, quindi si attiva un webhook firmato payout.sent. Stessa autenticazione HMAC come tutto il resto.

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

La validazione è rigorosa: qualsiasi indirizzo errato o importo eccessivamente preciso rifiuta l'intero lotto (HTTP 422) con gli indici degli elementi problematici — un pagamento stipendiale non elimina mai silenziosamente un destinatario. Annulla un lotto ancora in attesa con POST /v1/payout/{id}/cancel per rilasciare la sospensione. Vedi il documento sull'architettura.

riferimento

Riferimento all'endpoint

Ogni endpoint parla JSON semplice su HTTPS a api.payora.money. Tutti tranne /v1/health utilizzano la stessa autenticazione della richiesta HMAC-SHA256. La specifica leggibile dalla macchina si trova su openapi.json.

EndpointAccessoDescrizione
GET/v1/healthno authStato del servizio più l'elenco delle valute abilitate.
POST/v1/invoiceauthCrea una fattura (modalità fiat o crypto). Supporta Idempotency-Key. Restituisce 201 con invoice_id, status, pay_url e expires; la modalità crypto aggiunge l'indirizzo, l'importo e il deeplink.
GET/v1/invoice/{id}authStato della fattura (solo fatture proprie): status, remaining, e il charge — valuta, indirizzo, importi attesi/ricevuti e tx_hash.
POST/v1/payoutauth · Pro+Crea un lotto di pagamento di massa (validazione rigorosa, fondi trattenuti immediatamente). Supporta Idempotency-Key. Restituisce 201 con la vista del lotto: batch_id, status, totali, commissione, articoli.
GET/v1/payoutauthElenca i tuoi recenti lotti di pagamento (?limit=, predefinito 50).
GET/v1/payout/{id}authStato del lotto di pagamento e articoli (solo lotti propri).
POST/v1/payout/{id}/cancelauthAnnulla un lotto ancora in attesa e rilascia il saldo trattenuto. Restituisce 409 se il lotto non è più cancellabile.
download

SDK e download

File singoli senza dipendenze. Ogni SDK firma le richieste e verifica i webhook allo stesso modo.

phpPHPPayora.php

PHP 7.4+ con cURL, un file. createInvoice, getInvoice e verifyWebhook.

jsNode.jspayora.js

Node.js con https e crypto integrati solo. Fatture, saldo, pagamenti e verifyWebhook.

pyPythonpayora.py

Solo libreria standard di Python. Fatture, saldo, pagamenti e verify_webhook.

{ }Postmanpayora.postman_collection.json

Una collezione Postman che firma ogni chiamata per te.

{…}OpenAPI 3.0openapi.json

La specifica leggibile dalla macchina di ogni endpoint, per generatori di codice e client API.

api.payora.moneyApri
Stai eseguendo WooCommerce, WHMCS, Magento o un altro CMS?

Un modulo pronto fa tutto quanto sopra per te: fattura, reindirizzamento e un webhook verificato.

Sfoglia i plugin
FAQ

Domande frequenti

Risposte dirette, comprese quelle scomode: custodia, commissioni e cosa succede quando qualcosa va storto.

Centro assistenza

Come posso integrare Payora?

Installa il PHP SDK in un unico file (senza dipendenze) o chiama direttamente l'API REST. Crea una fattura con createInvoice(), reindirizza il cliente al suo pay_url e gestisci un evento webhook: status=paid. Un sviluppatore competente è attivo in 30–60 minuti.

Esiste un'API REST per stack non PHP?

Sì. Tutto è semplice JSON su HTTPS, quindi puoi integrare da qualsiasi linguaggio. Il PHP SDK è un wrapper di convenienza attorno agli stessi endpoint — crea fattura, ottieni fattura e verifica le firme dei webhook.

Il cliente può tornare al mio sito dopo aver pagato, nella lingua giusta?

Sì. Passa return_url quando crei la fattura (o ?return_url= sul link di pagamento) e il checkout mostra un pulsante “Torna al negozio” per tornare al tuo sito nella schermata di successo — e mentre si paga. Passa lang (en, ru, uk, es, de), o ?lang= sul link, in modo che un cliente del tuo negozio russo atterri sul checkout russo invece che in inglese. Entrambi sono opzionali; return_url deve essere un URL http(s) assoluto.

Come viene gestita l'autenticazione API?

Le richieste e i webhook sono autenticati con HMAC-SHA256 sul timestamp e sul corpo raw utilizzando il tuo api_secret, con una finestra di skew di ±120 secondi e chiavi di idempotenza. Le firme vengono confrontate in tempo costante per prevenire attacchi di timing.

Come ottengo le chiavi API?

Crea un account gratuito. La tua api_key pubblica e il tuo api_secret segreto appaiono nel dashboard, insieme al SDK scaricabile e alla completa referenza dei webhook. Ruota le chiavi in qualsiasi momento dalle impostazioni.

Cosa contiene il payload del webhook?

Un evento JSON firmato con l'id della fattura, il tuo order_id, lo stato (ad esempio pagato), l'importo e la valuta, e un id evento unico per l'idempotenza. Verifica sempre la firma prima di accreditare un ordine, quindi registra l'id evento per evitare elaborazioni duplicate nei tentativi.

Esiste un'API per pagamenti massivi in criptovaluta?

Sì. POST /v1/payout invia crypto a un massimo di 500 wallet in una richiesta — un {indirizzo, importo, tag opzionale} per elemento, in qualsiasi moneta abilitata sul tuo account. Utilizza la stessa autenticazione HMAC-SHA256 e Idempotency-Key dell'API delle fatture, quindi una richiesta ripetuta non crea mai un lotto duplicato. Il totale del lotto più la commissione per elemento è riservato sul tuo saldo immediatamente; l'operatore firma e trasmette, quindi si attiva un webhook di pagamento firmato. La validazione è rigorosa — qualsiasi indirizzo non valido o importo eccessivamente preciso rifiuta l'intero lotto (422) quindi un'operazione di pagamento non scarta mai silenziosamente un destinatario.

Come posso automatizzare i pagamenti in criptovaluta per stipendi o affiliati?

Crea l'elenco dei destinatari nel tuo sistema, quindi chiama POST /v1/payout una volta per esecuzione con una Idempotency-Key stabile (ad esempio payroll-2026-01). Interroga GET /v1/payout/{id} o aspetta il webhook payout.sent per confermare la consegna e registrare ogni tx hash. Inviare il batch riserva fondi ma non li sposta da solo — l'operatore firma e trasmette, quindi nulla esce con una sola chiamata API.

Ottieni le tue chiavi API

Un singolo SDK PHP senza dipendenze: crea fatture, reindirizza al checkout ospitato e verifica i webhook firmati. REST è disponibile per qualsiasi linguaggio.

Cosa risponde questa pagina