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

# Pedidos

Se a [CheckoutSession](https://docs.infraio.xyz/pt-BR/concepts/sessions) é o que o comprador vê,
o **Order** é o que *você* se importa. É o registro permanente de:

- O que estava sendo comprado (itens)
- Quanto foi devido e quanto já foi pago
- Reembolsos pendentes e aplicados
- A sua referência externa (`external_ref`) — tipicamente o ID do
  pedido do seu próprio sistema, armazenado no Order e retornado em
  `GET /b2b/v1/orders/{id}` (não ecoado nos payloads de webhook —
  veja abaixo)

Um pedido não precisa de itens: envie `amount` em vez de `items` para cobrar um valor fixo (uma fatura, um depósito, um link de pagamento com valor livre). Envie um ou outro, nunca os dois.

Uma CheckoutSession morre depois que um dos seus PaymentIntents
liquida ou o TTL expira. O Order vive para sempre.

## Quando um Order é criado

Quando você chama `POST /b2b/v1/checkout-sessions/quick`, a
InfraIO Pay cria **ao mesmo tempo** um Order novo *e* uma
CheckoutSession nova em uma única transação. Se você já tem um Order
e quer tentar o checkout de novo (por exemplo, depois que o comprador
abandonou), use `POST /b2b/v1/checkout-sessions` no lugar para
anexar uma sessão nova ao pedido existente — preservando a trilha de
auditoria.

## Ciclo de vida

```mermaid
stateDiagram-v2
    [*] --> PENDING: pedido criado
    PENDING --> PAID:              pagamento total liquidado
    PENDING --> PARTIAL_PAID:      pagamento insuficiente liquidado
    PENDING --> CANCELED:          sessão expirou ou foi cancelada
    PARTIAL_PAID --> PAID:         lojista resolve OU restante é pago
    PAID --> PARTIALLY_REFUNDED:   reembolso parcial executado
    PAID --> REFUNDED:             reembolso total executado
    PARTIALLY_REFUNDED --> REFUNDED: reembolso seguinte cobre o resto
    PAID --> [*]
    REFUNDED --> [*]
    CANCELED --> [*]
```

| Estado | Significa |
| --- | --- |
| `PENDING` | Uma CheckoutSession está viva e ainda não resolvida. |
| `PAID` | Valor total liquidado. **O webhook `payment.settled` dispara aqui.** Seguro para entregar. |
| `PARTIAL_PAID` | O dinheiro chegou, mas menos que o total. Veja "Pagamento insuficiente" abaixo. |
| `CANCELED` | Sessão expirou ou o lojista cancelou. `metadata.canceled_reason` explica o motivo (`payment_timeout`, `merchant_canceled`, …). |
| `REFUNDED` | Todo o valor pago foi reembolsado. |
| `PARTIALLY_REFUNDED` | Algum reembolso executado mas o saldo permanece pago. |

> **Note:**
>
> **O estado para acionar a sua lógica de entrega é `PAID`** — não o
> `COMPLETED` da CheckoutSession. O webhook `payment.settled` é o
> sinal oficial.

## O campo `external_ref`

Ao criar uma sessão você pode incluir `external_ref` (qualquer string
de até 255 caracteres — tipicamente o ID do pedido do seu próprio
sistema). Ele percorre toda a pipeline:

- Armazenado no Order
- Visível no dashboard do lojista para buscas de suporte
- Retornado em `GET /b2b/v1/orders/{id}` para que um handler de
  webhook possa buscá-lo depois de receber `payment.settled`

> **Warning:**
>
> Os payloads de webhook **não** incluem `external_ref`. Para mapear um
> webhook `payment.*` de volta ao seu próprio registro, pegue `order_id`
> do payload e busque o pedido.

## Pagamento insuficiente

Se a transferência on-chain do comprador é confirmada por menos do
que o total do pedido, o Order vai para `PARTIAL_PAID`. Você tem três
opções:

1. **Aceitar e resolver.** Move o pedido para `PAID` e dispara
   `order.resolved`. Isso não está disponível pela API REST, então para
   um fluxo self-service use a opção 2 (cobrar o restante).
2. **Esperar o restante.** Crie uma nova CheckoutSession contra o
   mesmo Order com `amount_due` = residual. O comprador paga a
   diferença; quando isso liquida, o Order vai para `PAID`.
3. **Cancelar e reembolsar.** Reembolse o valor parcial e cancele o
   Order. O comprador é responsável por quaisquer taxas de rede.

## Reembolsos

Reembolsos são uma superfície de API separada e uma página de
conceitos separada. Veja [Conceitos → Reembolsos](https://docs.infraio.xyz/pt-BR/concepts/refunds).

## Endpoints da API

| Método | Path | Notas |
| --- | --- | --- |
| `POST` | `/b2b/v1/orders` | Cria um Order sem sessão (raro) |
| `GET` | `/b2b/v1/orders/:order_id` | Lê o pedido completo com itens + histórico de pagamentos |
| `PATCH` | `/b2b/v1/orders/:order_id/cancel` | Cancela um pedido não pago |
| `PATCH` | `/b2b/v1/orders/:order_id/reopen` | Reabre um pedido auto-cancelado (`payment_timeout`) |

## Próximos passos

- [Conceitos → Sessões](https://docs.infraio.xyz/pt-BR/concepts/sessions) — a casca voltada
  ao comprador que envelopa um Order.
- [Conceitos → Reembolsos](https://docs.infraio.xyz/pt-BR/concepts/refunds) — estados de
  reembolso e o passo de envio manual on-chain.
- [Webhooks → Visão geral](https://docs.infraio.xyz/pt-BR/webhooks/overview) — todo evento
  disparado durante o ciclo de vida de um Order.
