Pular para o conteúdo
Desenvolvedores

Integre em minutos

Um único SDK PHP sem dependências: crie faturas, redirecione para o checkout hospedado e verifique webhooks assinados. REST está disponível para qualquer linguagem.

API em um relance
  • URL baseapi.payora.money
  • AutenticaçãoHMAC-SHA256
  • FormatoJSON · HTTPS
  • SDKsPHP · Node.js · Python
  • EspecificaçãoOpenAPI 3.0
início rápido

Da fatura ao webhook

  1. 01

    Criar uma fatura

    Uma chamada de API com um ID de pedido e um valor em fiat ou cripto retorna uma URL de pagamento hospedada.

  2. 02

    Cliente paga

    Eles escolhem uma moeda, escaneiam o QR ou abrem uma carteira, e o checkout confirma ao vivo na finalização.

  3. 03

    Você recebe um webhook assinado

    Verifique a assinatura HMAC, credite o pedido uma vez e veja o pagamento cair no seu saldo.

SDK PHP

Um arquivo, sem dependências. createInvoice(), getInvoice() e verifyWebhook() — insira em qualquer projeto.

Autenticação HMAC

As solicitações e webhooks são assinados com HMAC-SHA256 com desvio de timestamp e chaves de idempotência.

API REST

JSON simples sobre HTTPS — integre de qualquer stack, não apenas 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

Obtenha sua chave de API e segredo ao criar uma conta. O SDK completo está no seu painel.

autenticação

Autenticação

Cada chamada, exceto /v1/health, carrega três cabeçalhos assinados. A assinatura prova que a solicitação vem do detentor do seu api_secret e não foi alterada no caminho.

CabeçalhoValorDescrição
X-Payora-Keypk_…Seu api_key público. Identifica a loja.
X-Payora-Timestampunix secondsO momento em que você assinou a solicitação, em segundos Unix.
X-Payora-Signaturehex · 64HMAC-SHA256 em hex minúsculo de timestamp + "." + corpo bruto, chaveado com seu api_secret.
X-Payora-Test1Marca uma fatura como um teste da sua integração: é real e pode receber moedas, mas fica fora dos relatórios de demanda e conversão.
Idempotency-KeystringOpcional em POST /v1/invoice e POST /v1/payout. Uma nova tentativa com a mesma chave retorna o primeiro resultado em vez de criar um duplicado; a mesma chave com um corpo diferente responde 409.
Content-Typeapplication/jsonObrigatório em solicitações que carregam um corpo.
X-Payora-Signature=hex( HMAC-SHA256( api_secret, timestamp + "." + raw_body ) )

Assine os bytes exatos que você envia. Recodificar o JSON após a assinatura — até mesmo reordenar chaves ou adicionar um espaço — quebra a assinatura.

Para uma solicitação GET, o corpo está vazio, então a string assinada é o timestamp seguida de um ponto.

A API rejeita um timestamp mais de 120 segundos distante de seu relógio. Mantenha seu servidor sincronizado com NTP.

Mantenha o api_secret em seu servidor. Ele assina solicitações e webhooks da mesma forma: quem o possui pode criar faturas em seu nome e forjar callbacks.

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

Parâmetros da fatura

Todos opcionais, exceto order_id e amount. O modo fiat permite que o pagador escolha qualquer moeda habilitada em sua conta; o modo cripto também precisa de currency.

ParâmetroTipoDescrição
order_idstring · requiredSua referência de pedido única (≤190 caracteres). Uma repetição é rejeitada com 409 — seguro contra envios duplicados.
amountstring · requiredValor fiat (modo=fiat) ou valor exato em cripto (modo=crypto).
modefiat | cryptoFiat padrão: taxa bloqueada por moeda no checkout. O cripto fixa a moeda + valor antecipadamente.
fiat_currencystringCódigo fiat ISO para modo fiat (padrão USD).
currencystringMoeda para modo cripto (por exemplo, TON, TRX, USDT_TRON).
return_urlhttps URLOnde o botão do checkout “Return to store” envia o cliente de volta — seu site. Apenas http(s) absoluto.
langen·ru·uk·es·deIdioma do checkout, para que um cliente da sua loja russa veja o checkout em russo — não em inglês. Também pode ser definido como ?lang=ru na URL de pagamento.
ttlsecondsQuanto tempo a fatura permanece pagável (120–86400 segundos, padrão 1800).
customer_emailemailOpcional — recibo + enviado por e-mail ao pagador.
notesstringNota em formato livre armazenada na fatura.

return_url e lang também funcionam como parâmetros de consulta anexados ao pay_url que a API fornece — <pay_url>&lang=ru&return_url=https://shop.example/thanks. Sempre envie o comprador para o pay_url retornado pela API: ele carrega um token de acesso por fatura, então uma página de checkout não pode ser acessada adivinhando números de fatura. Não reconstrua o link a partir do id da fatura.

Construtor de solicitação

Construa uma solicitação de fatura assinada

Preencha os campos e copie um comando cURL pronto. Ele se assina em seu shell com $PAYORA_KEY e $PAYORA_SECRET — esta página nunca vê suas chaves e não envia nada.

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

Nada é enviado desta página.

webhooks

Webhooks

Quando uma fatura ou um pagamento muda de estado, a Payora envia um evento JSON assinado para sua URL de callback. Verifique a assinatura primeiro, credite o pedido uma vez, responda 2xx.

EventostatusQuando é acionado
invoice.paidpaidO pagamento é confirmado na blockchain. Carrega o valor, a moeda e tx_hash.
invoice.underpaidunderpaidA fatura expirou após menos do que o valor esperado ter chegado.
invoice.expiredexpiredA fatura expirou sem nada recebido.
invoice.cancelledcancelledA fatura foi cancelada. O dinheiro que já havia chegado, se houver, é descrito no evento.
invoice.cancel_settled—O dinheiro que chegou em uma fatura cancelada foi tratado: creditado ou devolvido.
invoice.late_payment—Dinheiro que chegou em uma fatura após ser cancelada. Enviado uma vez para cada depósito desse tipo; o resultado diz se foi creditado ou está sendo devolvido.
payout.sentsentUm lote de pagamento foi assinado e transmitido. Carrega cada item com seu tx_hash.

Cabeçalhos de cada entrega

CabeçalhoValorDescrição
X-Payora-IduuidID de evento único, o mesmo que o id no corpo. Armazene-o para ignorar repetições.
X-Payora-Eventinvoice.paidNome do evento.
X-Payora-Timestampunix secondsQuando esta tentativa foi assinada.
X-Payora-Signaturehex · 64Mesma estrutura que os pedidos: HMAC-SHA256 de timestamp + "." + corpo bruto com seu api_secret.

payload de invoice.paid

CampoTipoDescrição
iduuidID do evento para desduplicação.
eventstringNome do evento.
invoice_idintNúmero da fatura Payora.
order_idstringSua referência de pedido, conforme enviada quando a fatura foi criada.
statusstringpaid para invoice.paid.
currencystringMoeda utilizada pelo pagador, ex. USDT_TRON.
amountdecimal stringValor recebido.
amount_unitsinteger stringO mesmo valor nas menores unidades da moeda — use para comparações exatas.
expecteddecimal stringValor que a fatura solicitou.
fiat_amountdecimal string | nullPreço fiat da fatura como você a criou; nulo para faturas em modo cripto.
fiat_currencystring | nullCódigo ISO de fiat_amount; nulo para faturas em modo cripto.
tx_hashstringHash da transação on-chain.
paid_atunix secondsQuando o evento foi criado.
testbooltrue para faturas de 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 o valor recebido difere da fatura, amount_received e amount_expected são adicionados.

Entrega e tentativas

Qualquer coisa diferente de 2xx, ou nenhuma resposta dentro de 15 segundos, é tentada novamente com retrocesso exponencial limitado a uma hora entre as tentativas — até 12 tentativas. Cada tentativa é assinada novamente com um novo timestamp; o corpo e o ID do evento permanecem os mesmos, então desduplicar pelo ID.

Após a última tentativa, o evento é marcado como falhado e o proprietário da loja recebe um e-mail. Redirecionamentos nunca são seguidos, e a URL de callback deve ser acessível pela internet — sem localhost ou endereços privados.

Antes de creditar um pedido

  • Leia o corpo bruto antes de qualquer análise JSON.
  • Recalcule a assinatura e compare em tempo constante: hash_equals, crypto.timingSafeEqual, hmac.compare_digest.
  • Rejeite timestamps fora da sua janela — os SDKs aceitam ±300 segundos.
  • Verifique o status e o valor em relação ao seu pedido, então credite uma vez por ID de evento.
  • Responda 2xx rapidamente e faça o trabalho lento após responder.
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

Playground de assinatura de Webhook

Insira um segredo, um timestamp e o corpo bruto para ver a assinatura exata que a Payora enviaria — ou verifique uma que você recebeu.

Executa no seu navegador com WebCrypto. Nada do que você digita sai desta página. Use um segredo de teste, não um ativo, em um computador compartilhado.

X-Payora-Timestamp
String assinada
1758038400.{…}
Cabeçalhos que a Payora envia
headers
X-Payora-Timestamp: 1758038400
X-Payora-Signature: …

Cole uma assinatura para comparar

pagamentos em massa

API de Pagamento em Massa

Envie cripto para até 500 carteiras em uma solicitação assinada e idempotente — para payroll, pagamentos de afiliados ou retiradas. O total do lote mais a taxa por item é mantido em seu saldo interno instantaneamente; o operador assina e transmite, então um webhook assinado payout.sent é acionado. A mesma autenticação HMAC que tudo o mais.

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

A validação é rigorosa: qualquer endereço inválido ou valor excessivamente preciso rejeita todo o lote (HTTP 422) com os índices dos itens problemáticos — uma execução de folha de pagamento nunca descarta silenciosamente um destinatário. Cancele um lote ainda pendente com POST /v1/payout/{id}/cancel para liberar a retenção. Veja o artigo sobre a arquitetura.

referência

Referência de endpoint

Cada endpoint fala JSON simples sobre HTTPS em api.payora.money. Todos, exceto /v1/health, usam a mesma autenticação de solicitação HMAC-SHA256. A especificação legível por máquina está em openapi.json.

EndpointAcessoDescrição
GET/v1/healthno authStatus do serviço mais a lista de moedas habilitadas.
POST/v1/invoiceauthCrie uma fatura (modo fiat ou cripto). Suporta Idempotency-Key. Retorna 201 com invoice_id, status, pay_url e expires; o modo cripto adiciona o endereço, valor e deeplink.
GET/v1/invoice/{id}authStatus da fatura (apenas faturas próprias): status, remaining, e o charge — moeda, endereço, valores esperados/recebidos e tx_hash.
POST/v1/payoutauth · Pro+Crie um lote de pagamento em massa (validação rigorosa, fundos retidos instantaneamente). Suporta Idempotency-Key. Retorna 201 com a visualização do lote: batch_id, status, totais, taxa, itens.
GET/v1/payoutauthListe seus lotes de pagamento recentes (?limit=, padrão 50).
GET/v1/payout/{id}authStatus do lote de pagamento e itens (apenas lotes próprios).
POST/v1/payout/{id}/cancelauthCancele um lote ainda pendente e libere o saldo retido. Retorna 409 se o lote não puder mais ser cancelado.
downloads

SDKs e downloads

Arquivos únicos sem dependências. Cada SDK assina solicitações e verifica webhooks da mesma forma.

phpPHPPayora.php

PHP 7.4+ com cURL, um arquivo. createInvoice, getInvoice e verifyWebhook.

jsNode.jspayora.js

Node.js com https e crypto integrados apenas. Faturas, saldo, pagamentos e verifyWebhook.

pyPythonpayora.py

Apenas biblioteca padrão do Python. Faturas, saldo, pagamentos e verify_webhook.

{ }Postmanpayora.postman_collection.json

Uma coleção do Postman que assina cada chamada para você.

{…}OpenAPI 3.0openapi.json

A especificação legível por máquina de cada endpoint, para geradores de código e clientes de API.

api.payora.moneyAbrir
Executando WooCommerce, WHMCS, Magento ou outro CMS?

Um módulo pronto faz tudo isso por você: fatura, redirecionamento e um webhook verificado.

Navegar por plugins
FAQ

Perguntas frequentes

Respostas diretas, incluindo as desconfortáveis: custódia, taxas e o que acontece quando algo dá errado.

Centro de ajuda

Como faço para integrar o Payora?

Instale o SDK PHP de arquivo único (sem dependências) ou chame a API REST diretamente. Crie uma fatura com createInvoice(), redirecione o cliente para seu pay_url e trate um evento de webhook: status=paid. Um desenvolvedor competente está ativo em 30–60 minutos.

Existe uma API REST para pilhas que não são PHP?

Sim. Tudo é JSON simples sobre HTTPS, então você pode integrar de qualquer linguagem. O SDK PHP é um wrapper de conveniência em torno dos mesmos endpoints — criar fatura, obter fatura e verificar assinaturas de webhook.

O cliente pode retornar ao meu site após pagar, no idioma correto?

Sim. Passe return_url ao criar a fatura (ou ?return_url= no link de pagamento) e o checkout mostrará um botão “Retornar à loja” de volta ao seu site na tela de sucesso — e enquanto paga. Passe lang (en, ru, uk, es, de), ou ?lang= no link, para que um cliente da sua loja russa chegue ao checkout russo em vez do inglês. Ambos são opcionais; return_url deve ser uma URL http(s) absoluta.

Como a autenticação da API é tratada?

As solicitações e webhooks são autenticados com HMAC-SHA256 sobre o timestamp e o corpo bruto usando seu api_secret, com uma janela de desvio de ±120 segundos e chaves de idempotência. As assinaturas são comparadas em tempo constante para prevenir ataques de temporização.

Como eu obtenho chaves da API?

Crie uma conta gratuita. Sua api_key pública e api_secret secreta aparecem no painel, junto com o SDK para download e a referência completa de webhook. Gire as chaves a qualquer momento nas configurações.

O que contém o payload do webhook?

Um evento JSON assinado com o id da fatura, seu order_id, o status (por exemplo, pago), o valor e a moeda, e um id de evento único para idempotência. Sempre verifique a assinatura antes de creditar um pedido, depois registre o id do evento para evitar processamento duplo em tentativas.

Existe uma API para pagamentos em massa de criptomoedas?

Sim. POST /v1/payout envia criptomoeda para até 500 carteiras em uma única solicitação — um {endereço, valor, tag opcional} por item, em qualquer moeda habilitada em sua conta. Ele usa a mesma autenticação HMAC-SHA256 e Idempotency-Key que a API de fatura, então uma solicitação reprocessada nunca cria um lote duplicado. O total do lote mais a taxa por item é reservado em seu saldo imediatamente; o operador assina e transmite, então um webhook de pagamento assinado é acionado. A validação é rigorosa — qualquer endereço inválido ou valor excessivamente preciso rejeita todo o lote (422), então uma execução de folha de pagamento nunca descarta silenciosamente um destinatário.

Como posso automatizar a folha de pagamento em criptomoedas ou pagamentos de afiliados?

Construa a lista de destinatários em seu próprio sistema, depois chame POST /v1/payout uma vez por execução com uma Idempotency-Key estável (por exemplo, payroll-2026-01). Consulte GET /v1/payout/{id} ou aguarde o webhook payout.sent para confirmar a entrega e registrar cada tx hash. Enviar o lote reserva fundos, mas não os move por si só — o operador assina e transmite, então nada sai apenas com uma chamada de API.

Obtenha suas chaves de API

Um único SDK PHP sem dependências: crie faturas, redirecione para o checkout hospedado e verifique webhooks assinados. REST está disponível para qualquer linguagem.

O que esta página responde