Pular para o conteúdo principal
Estes endpoints são consumidos pela página de pagamento hospedada (o navegador do comprador). Você normalmente não os chama — quem chama é a página do Z2Pay. Estão documentados aqui para fins de transparência, ou caso você queira construir um checkout custom em cima da nossa API.
Autenticação: nenhuma x-api-key. A autenticação é a posse do ID cs_* (48 chars hex = 192 bits de entropia). Os endpoints públicos têm rate-limit por IP.
Os exemplos usam o sandbox: API em https://checkout-api.sandbox.z2pay.com e página em https://pay.sandbox.z2pay.com. Em produção, use https://checkout-api.z2pay.com e https://pay.z2pay.com.

Endpoints

MétodoRotaO que fazRate-limit
GET/public/checkout/{id}Obtém a config pública para renderizar a página60 req/min/IP
POST/public/checkout/{id}/openedMarca a Session como “aberta pelo comprador”60 req/min/IP
POST/public/checkout/{id}/confirmConfirma o pagamento (tokenId + dados do comprador)10 req/min/IP
O {id} pode ser uma Session (cs_*), um Link (chk_*) ou um slug. Quando recebe Link ou slug, o endpoint materializa uma Session nova e a retorna.

Obter config pública

GET /public/checkout/{id}
Retorna os dados necessários para renderizar a página de pagamento. Aceita Session (cs_*) ou Link (chk_*). Quando recebe Link, materializa uma Session nova e retorna ela.
sessionId
string
Apenas quando {id} é Link (chk_*). O cliente envia um ID candidato (cs_[a-f0-9]{48}, gerado localmente com 192 bits) para que a Session seja materializada idempotentemente — um refresh com o mesmo sessionId reaproveita a Session existente. Para cs_* direto, o parâmetro é ignorado.
curl https://checkout-api.sandbox.z2pay.com/public/checkout/cs_a1b2c3d4...
Resposta (200):
{
  "session": {
    "id": "cs_...",
    "status": "created",
    "config": { "...": "branding, paymentMethods, customFields, requiredFields" },
    "amount": 8500,
    "currency": "BRL",
    "locale": "pt-BR",
    "expiresAt": "2026-06-25T12:00:00.000Z"
  },
  "url": "https://pay.sandbox.z2pay.com/c/cs_...",
  "items": [
    { "name": "...", "quantity": 1, "unitAmount": 8500, "imageUrl": null, "description": null }
  ]
}
A Session retornada é uma view pública mascarada — não inclui metadata, tenantId nem transactionId. Só o necessário para renderizar a página.
Status possíveis: 200 · 404 (ID inválido ou expirado).

Marcar como aberta

POST /public/checkout/{id}/opened
Idempotente — transita o status created → opened apenas na primeira chamada. Dispara o evento checkout.session.opened.
sessionId
string
Obrigatório apenas quando {id} é Link (chk_*). Mesmo sessionId do GET; permite materializar idempotentemente a Session.
curl -X POST https://checkout-api.sandbox.z2pay.com/public/checkout/cs_a1b2c3d4.../opened \
  -H "Content-Type: application/json" \
  -d '{}'
Resposta (200):
{ "session": { "id": "cs_...", "status": "opened", "openedAt": "2026-06-24T12:01:00.000Z" } }

Confirmar pagamento

POST /public/checkout/{id}/confirm
Submete os dados do comprador + token(s) de cartão para finalizar o pagamento. Aceita Session (cs_*) ou Link (chk_*). É idempotente via header Idempotency-Key: requisições repetidas retornam a resposta original e uma chamada concorrente aguarda a primeira terminar — defesa primária contra cobrança dupla.
O amount e os items não são aceitos no body — valem os da Session (imutável, padrão PaymentIntent do Stripe). Para mudar o valor, crie uma nova Session.
Link arquivado: o confirm revalida o status do Link pai. Se o seller arquivou o Link depois que a Session foi materializada, o confirm retorna 409 link_not_active — mesmo que a Session já existisse. Garante que nenhum pagamento é processado contra um Link descontinuado.

Body

payments
array
obrigatório
Entradas de pagamento (1–8). 1 entrada = fluxo single-method; 2+ entradas = pagamento combinado (exige paymentMethods.combined.enabled na Session). A soma dos amount deve bater exatamente com session.amount.
customer
object
obrigatório
Dados completos do comprador. Devem satisfazer os requiredFields da Session (email, document e phone são sempre obrigatórios; address se listado). Veja Customer.
customFieldsValues
object
Valores dos customFields da Session. As keys batem com customFields[].key; valores são strings ("true"/"false" para checkbox); cada valor ≤ 2000 chars.
Cada entrada de payments é discriminada por paymentMethod:
{
  "paymentMethod": "credit_card",
  "amount": 8500,
  "card": {
    "tokenId": "tok_...",
    "holderName": "JOAO SILVA",
    "installments": 3
  }
}
tokenId é obrigatório; holderName opcional; installments de 1 a 12. Tokenize o cartão pelo Tokenizer antes do confirm.
{ "paymentMethod": "pix", "amount": 5000 }
{ "paymentMethod": "boleto", "amount": 12000 }

Exemplo completo

curl -X POST https://checkout-api.sandbox.z2pay.com/public/checkout/cs_a1b2c3d4.../confirm \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
  -d '{
    "payments": [
      {
        "paymentMethod": "credit_card",
        "amount": 8500,
        "card": { "tokenId": "tok_abc...", "holderName": "JOAO SILVA", "installments": 3 }
      }
    ],
    "customer": {
      "name": "João Silva",
      "email": "joao@example.com",
      "document": "12345678900",
      "documentType": "cpf",
      "phone": "+5511999999999"
    },
    "customFieldsValues": { "company_name": "Acme Inc" }
  }'
Resposta (200):
{
  "session": { "id": "cs_...", "status": "paid", "paidAt": "..." },
  "payments": [
    {
      "id": "pay_...",
      "status": "paid",
      "paymentMethod": "credit_card",
      "amount": 8500,
      "installments": 3,
      "boletoUrl": null,
      "boletoDigitableLine": null,
      "boletoBarcode": null,
      "pixUrl": null,
      "expiresAt": null,
      "errorMessage": null,
      "declineCode": null
    }
  ]
}
  • Em PIX, pixUrl traz o payload BR-Code para o app bancário; expiresAt indica o vencimento.
  • Em boleto, boletoUrl / boletoDigitableLine / boletoBarcode trazem os dados do boleto.
  • Se recusado, session.status volta a opened (retry permitido) e payments[].errorMessage / declineCode explicam o motivo.
Status possíveis: 200 (resultado do pagamento, sucesso ou recusa) · 409 (Session em estado inválido — já paga, expirada, cancelada — ou Link pai arquivado → link_not_active).
Para testar aprovação e recusa, use os cartões de teste do sandbox.

Ciclo do comprador (resumo)

1

Abre a URL

O comprador acessa https://pay.sandbox.z2pay.com/c/{id}. A página chama GET /public/checkout/{id} para carregar a config.
2

Página marca como aberta

A página chama POST /public/checkout/{id}/opened — Session vai de createdopened e dispara checkout.session.opened.
3

Comprador confirma

Ao clicar em “Pagar”, a página tokeniza o cartão (se aplicável) e chama POST /public/checkout/{id}/confirm. A Session passa por paying e termina em paid (ou volta a opened se recusado).
4

Você recebe o webhook

checkout.session.payment_succeeded (ou payment_failed) chega na sua URL de webhook. Reconcilie pelo metadata da Session.

Veja também

Checkout Sessions

Estados da Session e o objeto Customer.

Visão geral do Checkout

Conceitos e mapa de endpoints.

Tokenizer

Como gerar o tokenId do cartão antes do confirm.

Cartões de teste

Cenários de aprovação e recusa no sandbox.

Webhooks

Eventos disparados ao longo do ciclo do comprador.

Erros

Códigos de domínio do confirm (amount_mismatch, combined_disabled, etc.).