Referência da API
Todo endpoint abaixo fala JSON, vive sob https://api.infraio.xyz
(prod) ou https://api-dev.infraio.xyz (teste) e autentica via
HMAC-SHA256 — veja Autenticação
para o ritual de assinatura e Erros
para o formato do envelope de erro.
Esta página é o índice. Cada linha aponta para o material mais detalhado existente; se uma linha só referencia um path, o endpoint existe hoje mas está documentado inline na página de conceito relevante em vez de ter uma página de referência própria.
Prefixos de path do gateway e seu modelo de auth:
/b2b/v1/*— Assinado com HMAC usando a sua chave secreta (sk_…). A superfície de backend do lojista./payment/v1/*— Bearer JWT (sessões do dashboard). Usado pelo frontend do dashboard do lojista; não é para integradores de terceiros./pub/v1/*— Bearer-da-verdade no path (um tokenrfqt_…para pedidos de reembolso). Sem credenciais. Seguro chamar do navegador./checkout/:key/*— Prefixo público para o fluxo de checkout hospedado.keyé ocst_…da sessão retornado na criação; o navegador do comprador é o único que chama. Sem credenciais.
Checkout
| Método | Path | Propósito | Notas |
|---|---|---|---|
POST | /b2b/v1/checkout-sessions/quick | Cria uma sessão numa chamada — pedido + sessão de checkout criados juntos. | Veja Início rápido para o body da requisição e exemplo. |
POST | /b2b/v1/checkout-sessions | Cria uma sessão contra um pedido existente. Use quando a sua plataforma já tem o próprio modelo de pedido e você quer uma sessão por tentativa. | O fluxo em dois passos. |
GET | /b2b/v1/checkout-sessions/by-order/{order_id} | Lista todas as sessões já criadas para um pedido. | Útil quando um comprador abandonou uma sessão e você quer mostrar as tentativas anteriores no seu dashboard. |
GET | /checkout/{session_key} | Público — a página de checkout hospedada busca isto. Só campos voltados ao comprador (sem referências internas). | Sem assinatura; toma o session_key como bearer-da-verdade. |
POST | /checkout/{session_key}/intent | Público — escolhe um método de pagamento na página hospedada. Emite um PaymentIntent com o endereço de depósito. | Chamado pelo checkout-web na seleção de método pelo usuário. |
POST | /checkout/{session_key}/verify | Público — deixa o comprador colar um tx hash para curto-circuitar a espera de confirmação. | Cai no watcher de rede se o hash estiver errado. |
Pedidos
Pedidos são a entidade faturável atemporal. Um único pedido pode suportar várias sessões de checkout (por exemplo, o comprador abandona e tenta de novo).
| Método | Path | Propósito | Notas |
|---|---|---|---|
POST | /b2b/v1/orders | Cria um pedido sem sessão. | Use quando você quer mandar para o comprador um link de pagamento depois, em vez de redirecioná-lo imediatamente. |
GET | /b2b/v1/orders/{id} | Lê um único pedido com itens + status. | Status: PENDING → PAID | PARTIAL_PAID | CANCELED. Depois de reembolso: PARTIALLY_REFUNDED | REFUNDED. |
GET | /b2b/v1/orders/by-merchant/{merchant_id} | Lista os seus pedidos, com paginação por cursor. | Veja Paginação por cursor para o protocolo de cursor. |
PATCH | /b2b/v1/orders/{id}/cancel | Marca um pedido não pago como cancelado. Dispara order.canceled. | Falha se o pedido já estiver pago. |
PATCH | /b2b/v1/orders/{id}/reopen | Reverte um auto-cancel (canceled_reason=payment_timeout). | Útil se o comprador volta depois do TTL expirar. |
Reembolsos
Veja a página de conceitos sobre reembolsos para o fluxo da saga e o ciclo de vida do token.
Iniciado pelo lojista
| Método | Path | Propósito | Notas |
|---|---|---|---|
POST | /b2b/v1/merchants/{merchant_id}/refunds | Reembolso iniciado pelo lojista. Auto-aprovado (pula PENDING). | Dispara payment.refund.approved imediatamente. |
Iniciado pelo cliente — tokens de pedido de reembolso
O comprador preenche o formulário de reembolso na nossa página hospedada; você só cria o token e entrega a URL. Dois caminhos de criação (HMAC para backends, JWT para o dashboard), três paths públicos de token (ler contexto, submeter, pedir uma renovação) e dois paths só-dashboard para tratar renovações.
| Método | Path | Auth | Propósito |
|---|---|---|---|
POST | /b2b/v1/merchants/{merchant_id}/refund-requests | HMAC (sk_…) | Cria um token a partir do seu backend. Body: {ref_type, ref_value, amount, ttl_seconds?, metadata?, hide_summary?, hide_header?}. ref_type é um de order_id / order_number / session_id / session_key; ref_value é o identificador correspondente. amount é obrigatório e trava o máximo que o comprador pode submeter. TTL padrão 30 min. Dispara refund_request.created (source: b2b). |
POST | /payment/v1/merchants/{merchant_id}/refund-requests | JWT (dashboard) | Cria um token a partir do modal Issue Refund no dashboard do lojista. Mesmo formato de body da variante B2B. TTL padrão 24 h. Dispara refund_request.created (source: dashboard). |
GET | /pub/v1/refund-requests/{token} | Token no path | Público — o checkout-web lê o contexto do formulário (resumo do pedido, valor travado, estado efetivo atual). |
POST | /pub/v1/refund-requests/{token}/submit | Token no path | Público — comprador submete o formulário. Body: {reason, refund_to_address, amount?, metadata?}. amount é opcional — quando omitido, o valor travado pelo lojista no link é usado; quando presente, o servidor aplica amount ≤ valor travado. Cria a linha de Refund, dispara payment.refund.requested, retorna {link_token, refund_id} para a página de recibo. |
POST | /pub/v1/refund-requests/{token}/request-renewal | Token no path | Público — comprador pede um link novo depois da expiração. Body: {customer_note?}. Dispara refund_request.renewal_requested. |
GET | /payment/v1/merchants/{merchant_id}/refund-requests/renewals | JWT (dashboard) | Lista tokens RENEWAL_REQUESTED pendentes para o widget de renovação do lojista. Paginação por cursor. |
POST | /payment/v1/merchants/{merchant_id}/refund-requests/renewals/{token}/issue-new | JWT (dashboard) | Aprova uma renovação — cria um novo token ACTIVE, aposenta o antigo. Dispara refund_request.renewed + refund_request.created (source: renewal). |
GET | /payment/v1/merchants/{merchant_id}/refund-requests/by-order/{order_id} | JWT (dashboard) | Lista todo token de pedido de reembolso já criado contra um pedido com o estado efetivo. Mais novo primeiro. |
POST | /payment/v1/merchants/{merchant_id}/refund-requests/{token}/send-email | JWT (dashboard) | Enfileira uma entrega por e-mail do link de pedido de reembolso ao cliente. Body: {to}. Dispara refund_request.email_send_requested. |
POST | /payment/v1/merchants/{merchant_id}/refund-requests/{token}/cancel | JWT (dashboard) | Botão de pânico do lojista — vira ACTIVE ou RENEWAL_REQUESTED → CANCELED. Body: {reason?}. Idempotente: uma segunda chamada depois do status já ter movido retorna sucesso sem re-emitir. Dispara refund_request.canceled na primeira transição. |
Ciclo de vida do reembolso (pós-criação)
Aplica aos dois fluxos. Os endpoints abaixo operam na linha do
Refund (id começa com rfn_…), não no token de pedido.
| Método | Path | Propósito | Notas |
|---|---|---|---|
GET | /b2b/v1/refunds/{id} | Lê um reembolso. | Status: PENDING → APPROVED → EXECUTED | REJECTED. |
GET | /b2b/v1/refunds/by-merchant/{merchant_id} | Lista os seus reembolsos, com paginação por cursor. | — |
POST | /b2b/v1/refunds/{id}/approve | Aprova um reembolso PENDING (só iniciado pelo cliente — iniciado pelo lojista já cai em APPROVED). | Cripto: cai em APPROVED, você chama /submit-tx em seguida. |
POST | /b2b/v1/refunds/{id}/reject | Nega um reembolso PENDING. | Dispara payment.refund.rejected. |
POST | /b2b/v1/refunds/{id}/submit-tx | Só cripto — estampa o tx hash on-chain que você transmitiu. | Body: {tx_hash, network, token_address} — todos os três obrigatórios. |
Catálogo (somente leitura)
| Método | Path | Propósito |
|---|---|---|
GET | /v1/supported/networks | Todas as redes em que a InfraIO consegue liquidar (mainnet + testnet, filtradas por ambiente). |
GET | /v1/supported/tokens | Todas as stablecoins nessas redes. |
GET | /v1/supported/currencies | Moedas fiat aceitas para order.currency. |
GET | /v1/merchants/payment-methods | Métodos que ESTE lojista habilitou — combinação do catálogo da plataforma + toggles por lojista. Usado pelo checkout-web. |
GET | /v1/public/merchants/{merchant_id}/branding | Público — o que a página de checkout lê para se personalizar. |
Saúde
| Método | Path | Auth | Propósito |
|---|---|---|---|
GET | /health | Nenhuma (público) | Probe de liveness simples — retorna {"status":"ok"}. Este (sem prefixo /v1) é o único endpoint de saúde não autenticado — aponte os seus monitores k8s / uptime para aqui. |
GET | /payment/v1/merchants/{merchant_id}/health | JWT do dashboard | Visão de saúde por lojista — taxa recente de liquidação de intent, backlog de sweep. Útil para as suas próprias páginas de status. Requer um token de sessão do dashboard, não uma chave de API B2B. Alcançável só sob o prefixo de gateway /payment/ — o path nu /v1/... não é roteado publicamente. |
GET | /payment/v1/stats/health | JWT do dashboard | Saúde agregada na árvore de workspace de um lojista. Não é um probe de liveness público — fica atrás da mesma auth JWT sob o prefixo de gateway /payment/. |
Paginação por cursor
Todo endpoint de lista aceita os mesmos query params e retorna o
mesmo envelope. A gente usa cursores opacos ((created_at, id)
codificados em base64url) em vez de offsets para que uma página
nunca mude quando uma linha aterrissa no meio do scroll.
| Query param | Tipo | Padrão | Notas |
|---|---|---|---|
cursor | string | — | Opaco — copie o next_cursor da resposta anterior literalmente. |
limit | int | 20 | 1..100. |
sort_dir | 'asc' | 'desc' | desc | Ordena por (created_at, id). |
from / to | RFC3339 | — | Filtro opcional de janela de tempo. |
search | string | — | Filtro de texto livre onde suportado. |
Envelope da resposta:
{
"orders": [ /* linhas da página */ ],
"next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wNS0...",
"has_next": true
}has_next está sempre presente. next_cursor é omitido quando
has_next é false. Não tente parsear o cursor — o formato é
interno e vai mudar.
O que falta nesta página
Este índice cobre a superfície voltada ao lojista — endpoints sob
/admin/* (ferramentas do dashboard, revisão KYB, gestão de rede) e
rotas gRPC internas estão intencionalmente fora da lista. A spec
OpenAPI gerada pelo swag cobre a superfície completa; se você
precisar, ping no suporte e a gente compartilha um snapshot atual.