Sessões
Uma CheckoutSession é com o que o comprador interage: um objeto com tempo limitado, de uso único, que é dono da URL do checkout hospedado. É a mais leve das três entidades centrais. A maior parte da sua lógica trabalha com Orders e Payment Intents (veja abaixo).
O modelo de dados de três entidades
CheckoutSession ← 1:1 → Order ← 1:N → PaymentIntent
(comprador) (catálogo) (cada tentativa de pagamento)| Entidade | Propósito | Tempo de vida |
|---|---|---|
| CheckoutSession | Voltado ao comprador — tem session_key, checkout_url, TTL | Minutos (padrão 30) |
| Order | Seu estado de catálogo — itens, totais, reembolsos | Registro permanente |
| PaymentIntent | Uma tentativa de pagamento em uma rede/ativo | Horas; liquida ou expira |
Você cria uma sessão e um pedido juntos (via POST /b2b/v1/checkout-sessions/quick).
Cada vez que o comprador escolhe um ativo na página de checkout, um
PaymentIntent novo é aberto na rede certa. Se ele trocar de ativo no
meio do checkout, o intent anterior vai para EXPIRED e um novo começa.
Identificador
Uma sessão é identificada pelo seu session_key:
cst_G-SO92J7HNWkwMHEHjD4oO1ZURL-safe, com cerca de 24 caracteres depois do prefixo. A página de checkout hospedada
é https://checkout.infraio.xyz/<session_key> — trate o session key
como uma credencial bearer para aquele único checkout.
Ciclo de vida — CheckoutSession
| Estado | Significa |
|---|---|
ACTIVE | Sessão criada e aberta. A URL do checkout está utilizável. |
COMPLETED | Um PaymentIntent dessa sessão foi liquidado. O Order agora está PAID (ou PARTIAL_PAID se foi pagamento insuficiente). |
EXPIRED | expires_at passou sem liquidação. Qualquer Order aberto é cancelado. |
CANCELED | Cancelamento explícito — o comprador clicou em “cancelar” ou você chamou o endpoint de cancel. |
Os três estados terminais são mutuamente exclusivos e finais. Uma nova CheckoutSession contra o mesmo Order pode ser criada se você quiser tentar de novo (por exemplo, depois de um pagamento insuficiente).
TTL
- Padrão: 30 minutos (configurável pelo campo
expires_inna criação, em segundos). - Limites: Não há mínimo nem máximo aplicado. Escolha um valor que combine com a janela de decisão esperada do seu comprador: menos de 60 segundos arrisca expirar compradores legítimos, e uma sessão que fica aberta por mais de 7 dias provavelmente foi abandonada.
- Padrão por lojista: Você pode definir um padrão no dashboard, mas
só
POST /b2b/v1/checkout-sessions(em dois passos) o honra.POST /b2b/v1/checkout-sessions/quickusa 30 minutos quandoexpires_iné omitido, independentemente da configuração do dashboard. Para usar um padrão diferente com/quick, envieexpires_inem toda chamada. - Aplicação: Uma sessão cujo
expires_atjá passou é tratada comoEXPIREDmesmo que o estado ainda não tenha sido atualizado, então não dependa do valor do estado no instante exato da expiração.
Pagamento insuficiente
Se o comprador envia menos do que o valor da sessão, o PaymentIntent
ainda liquida pelo valor parcial e o Order transita para
PARTIAL_PAID. A CheckoutSession vai para COMPLETED (um
PaymentIntent liquidou), então deixa de ser reaproveitável.
Para aceitar o déficit como pagamento total, o pedido pode ser
resolvido para PAID. Veja Conceitos → Pedidos
(a resolução não está disponível pela API; para continuar self-service,
cobre o restante). Para cobrar o restante, crie uma nova
CheckoutSession contra o mesmo Order com o valor residual.
Pagamento excedente
Se o comprador envia mais do que o valor da sessão (raro, mas acontece com transferências manuais), a InfraIO Pay detecta o excedente dentro de 24 horas e avisa você. Ele não é reembolsado automaticamente. Emita o reembolso pela API de reembolsos ou pelo dashboard.
Pagamentos com ativo errado
O endereço de depósito é gerado para uma sessão, uma rede e um ativo. Se um comprador envia um ativo diferente para ele, o pagamento não é reconhecido e o PaymentIntent fica aberto até a sessão expirar. O suporte pode ajudar a recuperar os fundos, mas isso não é automático. Oriente os compradores a enviar exatamente o ativo mostrado na página de checkout.
Em TRON, Solana e TON não há endereço de depósito, então isto vale apenas para redes EVM: o comprador paga diretamente a sua carteira. Veja Redes com pagamento direto na carteira.
Idempotência na criação
POST /b2b/v1/checkout-sessions/quick aceita um campo
idempotency_key no body da requisição (atenção: campo do body, não
header HTTP). Gere um UUID se você não tiver uma chave natural.
A chave deduplica o Order, não a CheckoutSession. Em uma
retentativa com a mesma chave, /quick retorna o pedido original
(order_id é estável), mas cria uma CheckoutSession nova — um
session_key e uma checkout_url novos a cada vez. Isso é
intencional: um Order pode dar suporte a várias tentativas de
checkout (veja Pedidos), então um /quick
em retry entrega ao comprador uma sessão limpa sem duplicar o pedido.
Dois comportamentos para ter em mente:
- O body não é hasheado nem comparado. Reusar uma chave com um
body diferente não retorna
409— o servidor silenciosamente retorna o pedido já armazenado sob aquela chave e ignora o body novo. Então trate umaidempotency_keycomo um token de uso único para um único pedido lógico; nunca reaproveite uma entre carrinhos diferentes. - Só o Order é deduplicado, não a sessão. Se você precisa da
mesma URL de checkout de volta, persista
session_key/checkout_urlda primeira resposta — chamar/quickde novo não vai retornar a antiga. Para enumerar cada sessão criada contra um pedido, useGET /b2b/v1/checkout-sessions/by-order/:order_id.
Endpoints da API
| Método | Path | Notas |
|---|---|---|
POST | /b2b/v1/checkout-sessions/quick | Cria order + sessão em uma chamada |
POST | /b2b/v1/checkout-sessions | Cria sessão contra um order existente |
GET | /b2b/v1/checkout-sessions/by-order/:order_id | Lista todas as sessões de um pedido (para histórico de retries) |
Veja o Início rápido para o body completo de criação e a assinatura.
Próximos passos
- Conceitos → Pedidos — a entidade Order (a que você trata como fonte da verdade para a entrega).
- Conceitos → Redes e ativos — redes suportadas e premissas de finalidade por rede.
- Webhooks → Visão geral — quais eventos disparam em cada transição de estado da sessão.