curl --request POST \
--url https://api.sandbox.z2pay.com/v1/checkout/sessions \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"linkId": "<string>",
"customer": {
"name": "<string>",
"email": "jsmith@example.com",
"document": "<string>",
"phone": "<string>",
"address": {
"zipCode": "<string>",
"street": "<string>",
"number": "<string>",
"complement": "<string>",
"neighborhood": "<string>",
"city": "<string>",
"state": "<string>",
"country": "BR"
}
},
"metadata": {}
}
'const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
linkId: '<string>',
customer: {
name: '<string>',
email: 'jsmith@example.com',
document: '<string>',
phone: '<string>',
address: {
zipCode: '<string>',
street: '<string>',
number: '<string>',
complement: '<string>',
neighborhood: '<string>',
city: '<string>',
state: '<string>',
country: 'BR'
}
},
metadata: {}
})
};
fetch('https://api.sandbox.z2pay.com/v1/checkout/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sandbox.z2pay.com/v1/checkout/sessions"
payload = {
"linkId": "<string>",
"customer": {
"name": "<string>",
"email": "jsmith@example.com",
"document": "<string>",
"phone": "<string>",
"address": {
"zipCode": "<string>",
"street": "<string>",
"number": "<string>",
"complement": "<string>",
"neighborhood": "<string>",
"city": "<string>",
"state": "<string>",
"country": "BR"
}
},
"metadata": {}
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "cs_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"linkId": "chk_byd8p3p79re859jpkmr0j65n3",
"status": "created",
"mode": "payment",
"currency": "BRL",
"locale": "pt-BR",
"config": {
"paymentMethods": {
"card": {
"enabled": true
},
"pix": {
"enabled": true
}
},
"successUrl": "https://academia.com/obrigado"
},
"customer": {
"name": "João Silva",
"email": "joao@example.com"
},
"customFieldValues": null,
"paymentMethodSelected": null,
"subtotal": 49700,
"discountTotal": 0,
"amount": 49700,
"discounts": null,
"paymentAttempts": 0,
"transactionId": null,
"subscriptionId": null,
"invoiceId": null,
"metadata": {
"source": "api"
},
"createdAt": "2025-06-29T13:45:30.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z",
"openedAt": null,
"paidAt": null,
"canceledAt": null,
"expiresAt": "2025-06-30T13:45:30.000Z",
"url": "https://pay.z2pay.com/c/cs_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"issues": [
{
"path": "status",
"message": "Status inválido. Valores aceitos: pending, waiting_payment, paid, refused, canceled, refunded"
},
{
"path": "startDate",
"message": "Data deve ser ISO 8601 com timezone (ex.: 2026-06-24T00:00:00Z)"
}
]
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
}
}{
"error": {
"code": "FORBIDDEN",
"message": "Forbidden — insufficient permissions"
}
}{
"error": "A request with this idempotency key is already being processed"
}{
"error": "Idempotency key already used with a different request body"
}Criar session
Cria uma Session já materializada a partir de um Link — opcionalmente com os dados do comprador pré-preenchidos, para levar seu usuário direto ao pagamento.
curl --request POST \
--url https://api.sandbox.z2pay.com/v1/checkout/sessions \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"linkId": "<string>",
"customer": {
"name": "<string>",
"email": "jsmith@example.com",
"document": "<string>",
"phone": "<string>",
"address": {
"zipCode": "<string>",
"street": "<string>",
"number": "<string>",
"complement": "<string>",
"neighborhood": "<string>",
"city": "<string>",
"state": "<string>",
"country": "BR"
}
},
"metadata": {}
}
'const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
linkId: '<string>',
customer: {
name: '<string>',
email: 'jsmith@example.com',
document: '<string>',
phone: '<string>',
address: {
zipCode: '<string>',
street: '<string>',
number: '<string>',
complement: '<string>',
neighborhood: '<string>',
city: '<string>',
state: '<string>',
country: 'BR'
}
},
metadata: {}
})
};
fetch('https://api.sandbox.z2pay.com/v1/checkout/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sandbox.z2pay.com/v1/checkout/sessions"
payload = {
"linkId": "<string>",
"customer": {
"name": "<string>",
"email": "jsmith@example.com",
"document": "<string>",
"phone": "<string>",
"address": {
"zipCode": "<string>",
"street": "<string>",
"number": "<string>",
"complement": "<string>",
"neighborhood": "<string>",
"city": "<string>",
"state": "<string>",
"country": "BR"
}
},
"metadata": {}
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "cs_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"linkId": "chk_byd8p3p79re859jpkmr0j65n3",
"status": "created",
"mode": "payment",
"currency": "BRL",
"locale": "pt-BR",
"config": {
"paymentMethods": {
"card": {
"enabled": true
},
"pix": {
"enabled": true
}
},
"successUrl": "https://academia.com/obrigado"
},
"customer": {
"name": "João Silva",
"email": "joao@example.com"
},
"customFieldValues": null,
"paymentMethodSelected": null,
"subtotal": 49700,
"discountTotal": 0,
"amount": 49700,
"discounts": null,
"paymentAttempts": 0,
"transactionId": null,
"subscriptionId": null,
"invoiceId": null,
"metadata": {
"source": "api"
},
"createdAt": "2025-06-29T13:45:30.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z",
"openedAt": null,
"paidAt": null,
"canceledAt": null,
"expiresAt": "2025-06-30T13:45:30.000Z",
"url": "https://pay.z2pay.com/c/cs_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"issues": [
{
"path": "status",
"message": "Status inválido. Valores aceitos: pending, waiting_payment, paid, refused, canceled, refunded"
},
{
"path": "startDate",
"message": "Data deve ser ISO 8601 com timezone (ex.: 2026-06-24T00:00:00Z)"
}
]
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
}
}{
"error": {
"code": "FORBIDDEN",
"message": "Forbidden — insufficient permissions"
}
}{
"error": "A request with this idempotency key is already being processed"
}{
"error": "Idempotency key already used with a different request body"
}POST /checkout/sessions
Faz parte do recurso Links — o que é uma Session e os estados dela estão
lá.
Cria uma Session server-to-server, já materializada e pronta para pagar. Diferente do fluxo público — em que a própria página do comprador materializa a Session quando ele abre o Link — aqui você cria a Session pela API e recebe de volta a url da página de pagamento para redirecionar o comprador.
O body aceita duas formas (oneOf):
- A partir de um Link (
linkId): materializa uma Session reusando toda a configuração do Linkchk_*(itens, valor, métodos de pagamento, branding, splits). É a forma recomendada quando você já tem um Link. - Ad-hoc (body completo): cria uma Session sem Link, informando
items+paymentMethodsna própria requisição.
customer é opcional e serve para pré-preencher os dados do comprador.
linkId, o resto do corpo é ignorado — sem erro. A forma a partir do Link aceita
exatamente três campos: linkId, customer e metadata. Mandar items, paymentMethods ou
branding junto não altera nada e não responde 400: a configuração vem toda do Link, e o
excedente é descartado em silêncio.Se você precisa de itens ou métodos diferentes dos do Link, é a forma ad-hoc — sem linkId, com
a configuração inteira no corpo.Idempotency-Key para que um retry por timeout não crie duas Sessions
— sem ele, a segunda chamada gera outra cs_ e outra URL de pagamento. Veja
Convenções.Por que usar: pré-preencher e reduzir atrito
O caso clássico é uma plataforma SaaS com usuário logado — você já conhece os dados dele (nome, e-mail, documento…). Em vez de mandá-lo para o checkout e pedir que digite tudo de novo, você cria a Session com ocustomer preenchido e o redireciona direto para o pagamento. Na prática, é como se o comprador tivesse aberto a página e já tivesse preenchido o formulário — só que essa etapa é pulada.
O usuário clica em 'Pagar' na sua plataforma
Você cria a Session pela API
POST /checkout/sessions com o linkId do Link e o customer pré-preenchido. A resposta traz o id (cs_*) e a url.Redireciona para a `url`
customer é pré-preenchimento, não trava: o comprador ainda pode corrigir os dados na página. Os requiredFields do Link continuam valendo no confirm.Exemplo
curl -X POST https://api.sandbox.z2pay.com/v1/checkout/sessions \
-H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
-H "Content-Type: application/json" \
-d '{
"linkId": "chk_my2vr53qlp0yc7usqztta5ynn",
"customer": {
"name": "João Silva",
"email": "joao@example.com",
"document": "12345678900",
"documentType": "cpf",
"phone": "+5511999999999"
}
}'
{
"id": "cs_50b0abc54b632e7c57de3a73815413ace1d545dcd16da95c",
"linkId": "chk_my2vr53qlp0yc7usqztta5ynn",
"status": "created",
"amount": 8500,
"currency": "BRL",
"customer": {
"name": "João Silva",
"email": "joao@example.com",
"document": "12345678900",
"documentType": "cpf",
"phone": "+5511999999999"
},
"url": "https://pay.sandbox.z2pay.com/c/cs_50b0abc54b632e7c57de3a73815413ace1d545dcd16da95c",
"expiresAt": "2026-07-09T12:00:00.000Z"
}
url. Em produção, troque o host por https://api.z2pay.com/v1.
x-api-key (server-side) — nunca exponha a chave no navegador. É o oposto do fluxo do comprador, que é público e autenticado pela posse do cs_*.Authorizations
API key unificada (z2_{live|test}{sk|pk}...) — secret (sk) para integração backend, publishable (pk) para uso no frontend público
Body
- Option 1
- Option 2
ID do Link (chk_*) a materializar em Session.
1Pré-preenchimento dos dados do comprador.
Show child attributes
Show child attributes
Metadados do seller (string → string); propagados ao additionalInfo da Transaction e dos webhooks.
Show child attributes
Show child attributes
Response
Session criada
Identificador único do registro.
Identificador do link de checkout que originou o registro; nulo em sessões ad-hoc.
Estado atual do registro.
Modo do checkout: 'payment' (pagamento único) ou 'subscription' (assinatura).
Moeda no padrão ISO 4217 (ex.: BRL).
Idioma do checkout (ex.: pt-BR, en-US, es-ES).
Snapshot da configuração do checkout (formas de pagamento, itens e personalização visual).
Dados do comprador (nome, e-mail, documento e demais informações).
Valores preenchidos nos campos personalizados, indexados pela key de cada campo.
Forma de pagamento selecionada pelo comprador na sessão (ex.: credit_card, pix, boleto).
Soma dos itens antes dos descontos, em centavos.
Total de descontos aplicados, em centavos.
Valor total a ser cobrado, em centavos.
Descontos aplicados ao valor da sessão.
Quantidade de tentativas de pagamento realizadas na sessão.
Identificador da transação gerada pelo pagamento da sessão; nulo até haver pagamento.
Identificador da assinatura criada a partir da sessão; nulo até a ativação.
Fatura gerada pela venda com data de cobrança (scheduledAt), criada quando o comprador aceita. Nula em toda outra venda — pagamento no ato não gera fatura.
Metadados livres (pares chave-valor) para uso do integrador; não afeta o processamento.
Data e hora de criação do registro (ISO 8601).
Data e hora da última atualização do registro (ISO 8601).
Data e hora em que a sessão foi aberta pelo comprador (ISO 8601); nula se ainda não aberta.
Data e hora em que o pagamento foi confirmado (ISO 8601); nula se não pago.
Data e hora do cancelamento (ISO 8601); nula se não cancelado.
Data e hora de expiração (ISO 8601).
URL pública do checkout para o comprador finalizar o pagamento.