Quibly Pay
API v3

Sessões de checkout

Mande o comprador pagar com PIX ou cartão no checkout hospedado e volte para o seu site.

Uma sessão de checkout é uma página de pagamento hospedada para um pedido, no modelo do Stripe Checkout. O seu servidor cria a sessão e redireciona o comprador para url. O comprador paga com PIX ou cartão em pay.quiblypay.com e volta para o seu success_url. O redirecionamento NÃO prova o pagamento: entregue o pedido só depois do webhook transaction.paid (ele traz sessionId) ou de uma consulta que devolva status: "paid".

EndpointEscopoOperação
POST /v3/checkout/sessionscashinCria uma sessão em produção
POST /v3/checkout/sessions/retrievereadConsulta uma sessão em produção
POST /v3/checkout/sessions/expirecashinCancela uma sessão aberta em produção
POST /v3/sandbox/checkout/sessionscashinCria uma sessão no sandbox
POST /v3/sandbox/checkout/sessions/retrievereadConsulta uma sessão no sandbox
POST /v3/sandbox/checkout/sessions/expirecashinCancela uma sessão aberta no sandbox

Estas rotas aceitam só application/json (o corpo tem objetos aninhados). client_id e client_secret vão no mesmo corpo, como nas outras rotas v3, e valem as mesmas regras de whitelist de IP e de ambiente. A criação aceita até 60 chamadas por minuto por IP e o header Idempotency-Key: a mesma chave com o mesmo corpo devolve a mesma sessão.

Corpo da criação

CampoObrigatórioRegras
amountsimReais com até 2 casas, em texto ("150.00") ou número; maior que zero, pelo menos o mínimo da conta e no máximo 1.000.000.000
titlesim1 a 120 caracteres, mostrado ao comprador
descriptionnãoAté 500 caracteres
external_referencenãoO ID do seu pedido, até 100 caracteres. Volta na consulta e no webhook
customernão{name, email, cpf, phone}: preenche o checkout. A página mostra os dados mascarados (Maria S., ma***@..., ***.***.*47-25); os campos que o comprador não altera valem como você enviou
methodsnão["pix"], ["card"] ou os dois (padrão: os dois). Só cartão exige o cartão habilitado na conta
success_urlsimPara onde o comprador volta depois de pagar (veja URLs de retorno)
cancel_urlnãoPara onde levam "Voltar para a loja" e uma sessão vencida ou cancelada. Sem ele, vale o success_url
expires_innãoSegundos até a sessão vencer: 300 a 86400, padrão 3600
metadatanãoAté 20 chaves de texto (chave até 40 e valor até 500 caracteres). Volta na consulta e no webhook
urlnotynãoURL de webhook das cobranças desta sessão, com as mesmas regras do urlnoty de /v3/pix/qrcode
{
  "statusCode": 200,
  "id": "cs_live_A1b2C3d4E5f6G7h8I9j0K1l2",
  "url": "https://pay.quiblypay.com/s/cs_live_A1b2C3d4E5f6G7h8I9j0K1l2",
  "status": "open",
  "amount": "150.00",
  "currency": "BRL",
  "title": "Pedido #981",
  "description": null,
  "external_reference": "981",
  "metadata": { "pedido": "981" },
  "methods": ["pix", "card"],
  "success_url": "https://loja.example.com/obrigado?pedido=981",
  "cancel_url": "https://loja.example.com/carrinho",
  "expires_at": "2026-10-05T15:00:00.000Z",
  "created_at": "2026-10-05T14:00:00.000Z",
  "paid_at": null,
  "canceled_at": null,
  "transaction_id": null,
  "payment_method": null
}

Aqui amount é um texto decimal (as rotas PIX legadas devolvem número). No sandbox, os ids começam com cs_test_ e a resposta acrescenta mode: "sandbox". O id da sessão na url é a única chave da página: trate a url como um link de pagamento de uso único, não como segredo, e nunca coloque o client_secret nela.

Consulta e cancelamento

As duas rotas recebem {"id": "cs_..."} e devolvem o mesmo objeto. status é open, paid, expired ou canceled. Depois do pagamento, transaction_id e payment_method (pix ou card) identificam a venda; POST /v3/pix/transaction com esse transaction_id devolve o valor e a tarifa. Uma sessão de outra conta ou do outro ambiente devolve 404.

expire cancela uma sessão aberta (status: "canceled"). Chamar de novo não muda nada, e uma sessão paga devolve 409. Um PIX gerado antes de a sessão vencer ou ser cancelada ainda pode ser pago no banco até o próprio PIX vencer (no máximo uma hora e nunca mais de 5 minutos depois da sessão). Se ele for pago, o dinheiro é creditado, a sessão vira paid e o transaction.paid é enviado. Trate um pagamento que chega depois de você desistir do pedido: estorne ou entregue.

URLs de retorno

Depois do pagamento, a página mostra "Pagamento confirmado" e, cerca de 3 segundos depois, redireciona para o success_url com session_id e status acrescentados à query. Os parâmetros e o fragmento que já existiam são mantidos: https://loja.example.com/obrigado?pedido=981&session_id=cs_live_...&status=paid. Uma sessão vencida ou cancelada leva o comprador ao cancel_url (ou ao success_url) com status=expired ou status=canceled.

O success_url e o cancel_url precisam usar https, não ter usuário nem senha, não apontar para IP privado nem host interno (localhost, .local, .internal) e ter até 2048 caracteres. Uma sessão de sandbox aceita também http://localhost, http://127.0.0.1 e http://[::1] para testes locais.

Domínios de retorno por credencial (opcional). Em Desenvolvedor > Credenciais de API, cada credencial tem "Domínios de retorno" (até 10; salvar exige a verificação em duas etapas). Com a lista vazia, vale qualquer URL https pública, ou seja, quem tem uma credencial válida consegue fazer o checkout redirecionar para qualquer site. Com a lista preenchida, o success_url e o cancel_url precisam bater com ela, comparando o host:

  • compara o host da URL interpretada, nunca o texto (https://loja.example.com@evil.com tem host evil.com e é recusada antes da lista);
  • *.loja.example.com aceita qualquer subdomínio, em qualquer nível (pay.loja.example.com, a.b.loja.example.com), mas NÃO aceita loja.example.com: cadastre o domínio principal separado se precisar dele;
  • a porta não entra na comparação (https://loja.example.com:8443/... bate com loja.example.com);
  • nomes com acento são gravados e comparados em punycode;
  • o curinga sobre sufixo público é recusado ao salvar (*.com.br, *.adv.br, *.co.jp e hospedagem compartilhada como *.vercel.app ou *.github.io): cadastre o host exato (loja.vercel.app);
  • a lista é da credencial e vale no ambiente dela: uma credencial SANDBOX com lista também restringe as sessões de sandbox, e só os hosts locais acima escapam.

Uma URL fora da lista devolve HTTP 400 {"statusCode":400,"error":"RETURN_URL_NOT_ALLOWED","message":"...","details":{"field":"success_url","host":"evil.com"}}. A lista cadastrada nunca volta no erro.

Webhook e entrega do pedido

A venda gera um transaction.paid normal (mesmos destinos, segredo e assinatura descritos em Webhooks) com três campos a mais: sessionId, externalReference e metadata. A cobrança herda o urlnoty e a credencial da sessão, então valem as regras de entrega por cobrança.

Uma sessão é paga uma vez. Numa corrida rara (o comprador paga um PIX e um cartão da mesma sessão ao mesmo tempo), os dois pagamentos são creditados e chegam dois transaction.paid com o mesmo sessionId e transactionId diferentes. Entregue o pedido uma vez por sessionId ou external_reference e trate o segundo pagamento como caso de estorno (a nossa equipe é avisada).

Erros da sessão

HTTPErro
400VALIDATION_ERROR com o campo na mensagem (amount, title, URLs, expires_in, metadata, methods, urlnoty), RETURN_URL_NOT_ALLOWED, valor abaixo do mínimo ou acima do máximo
401 / 403As mesmas regras de credencial, escopo, IP e FEATURE_DISABLED das outras rotas v3
404Sessão inexistente nesta conta e neste ambiente
409expire numa sessão paga, ou IDEMPOTENCY_CONFLICT (a mesma Idempotency-Key com outro corpo)

Sandbox

Crie com uma credencial qp_test_ em /v3/sandbox/checkout/sessions e abra a url: a página mostra "Modo de teste". Pague com os cartões de teste do checkout hospedado. O PIX do sandbox não pode ser pago em banco: depois de gerá-lo na página, abra a transação de teste no painel (Transações) e use Marcar como pago. A consulta só devolve transaction_id depois do pagamento.

On this page