<!-- Source: https://docs.infraio.xyz/pt-BR/api-reference -->
<!-- Last updated: 2026-10-04 -->

# 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](https://docs.infraio.xyz/pt-BR/api-reference/authentication)
para a assinatura de requisições e [Erros](https://docs.infraio.xyz/pt-BR/api-reference/errors)
para o formato do envelope de erro.

Esta página lista os endpoints para integrações de lojistas. Quando
um endpoint não tem página própria, ele é descrito na página de
conceito relacionada.

> **Note:**
>
> Os endpoints sob **`/b2b/v1/*`** são assinados com HMAC usando a sua
> chave **secreta** (`sk_…`). Esta é a superfície que o seu backend
> chama. O dashboard do lojista e o checkout hospedado usam os próprios
> endpoints, que não fazem parte da API de integração.

## 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](https://docs.infraio.xyz/pt-BR/get-started/quickstart#2-crie-uma-sessao-de-checkout-servidor) 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. |

## 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](#paginacao-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](https://docs.infraio.xyz/pt-BR/concepts/refunds)
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. Você pode criar
tokens a partir do seu backend (abaixo) ou do dashboard do lojista.
Renovações e cancelamentos são tratados no dashboard.

| 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`). |

### Ciclo de vida do reembolso (pós-criação)

Aplica aos dois fluxos. Os endpoints abaixo operam no próprio
reembolso (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 Pay consegue liquidar (mainnet + testnet, filtradas por ambiente). |
| `GET` | `/v1/supported/tokens` | Todas as stablecoins nessas redes. |
| `GET` | `/v1/supported/currencies` | Moedas aceitas para `order.currency`. |

## Saúde

| Método | Path | Auth | Propósito |
| --- | --- | --- | --- |
| `GET` | `/health` | Nenhuma (público) | Verificação de liveness. Retorna `{"status":"ok"}`. Aponte os seus monitores de uptime para aqui. |

## Paginação por cursor

Todo endpoint de lista aceita os mesmos query params e retorna o
mesmo envelope. Os cursores são opacos e usados em vez de offsets, para que uma página
nunca mude quando uma nova linha chega enquanto você pagina.

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

```json
{
  "orders": [ /* linhas da página */ ],
  "next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wNS0...",
  "has_next": true
}
```

`has_next` está sempre presente. `next_cursor` é omitido quando
`has_next` é `false`. Trate o cursor como uma string opaca.

## O que falta nesta página

Esta página cobre os endpoints destinados a integrações de lojistas.
Se você precisa de um endpoint que não está listado, ou de uma spec
OpenAPI, fale com o suporte.
