curl --request PATCH \
--url https://api.sandbox.z2pay.com/v1/checkout/links/{id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "<string>",
"description": "<string>",
"slug": "<string>",
"mode": "payment",
"currency": "BRL",
"locale": "pt-BR",
"items": [],
"paymentMethods": {},
"splits": [
{
"recipientId": "<string>",
"percentage": 50.005,
"liable": true,
"processingFee": true
}
],
"branding": {
"primaryColor": "<string>",
"logoUrl": "<string>",
"merchantName": "<string>",
"faviconUrl": "<string>",
"coverUrl": "<string>"
},
"subscription": {
"planId": "<string>",
"currency": "BRL",
"trialDays": 182,
"maxCycles": 1,
"collectionTiming": "prepaid",
"metadata": {},
"itemCovers": {},
"maxEnrollmentInstallments": 1
},
"requiredFields": [],
"customFields": [
{
"key": "<string>",
"label": "<string>",
"options": [
"<string>"
],
"required": true
}
],
"successUrl": "<string>",
"cancelUrl": "<string>",
"metadata": {},
"expirationMinutes": 21602
}
'const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
slug: '<string>',
mode: 'payment',
currency: 'BRL',
locale: 'pt-BR',
items: [],
paymentMethods: {},
splits: [
{recipientId: '<string>', percentage: 50.005, liable: true, processingFee: true}
],
branding: {
primaryColor: '<string>',
logoUrl: '<string>',
merchantName: '<string>',
faviconUrl: '<string>',
coverUrl: '<string>'
},
subscription: {
planId: '<string>',
currency: 'BRL',
trialDays: 182,
maxCycles: 1,
collectionTiming: 'prepaid',
metadata: {},
itemCovers: {},
maxEnrollmentInstallments: 1
},
requiredFields: [],
customFields: [{key: '<string>', label: '<string>', options: ['<string>'], required: true}],
successUrl: '<string>',
cancelUrl: '<string>',
metadata: {},
expirationMinutes: 21602
})
};
fetch('https://api.sandbox.z2pay.com/v1/checkout/links/{id}', 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/links/{id}"
payload = {
"name": "<string>",
"description": "<string>",
"slug": "<string>",
"mode": "payment",
"currency": "BRL",
"locale": "pt-BR",
"items": [],
"paymentMethods": {},
"splits": [
{
"recipientId": "<string>",
"percentage": 50.005,
"liable": True,
"processingFee": True
}
],
"branding": {
"primaryColor": "<string>",
"logoUrl": "<string>",
"merchantName": "<string>",
"faviconUrl": "<string>",
"coverUrl": "<string>"
},
"subscription": {
"planId": "<string>",
"currency": "BRL",
"trialDays": 182,
"maxCycles": 1,
"collectionTiming": "prepaid",
"metadata": {},
"itemCovers": {},
"maxEnrollmentInstallments": 1
},
"requiredFields": [],
"customFields": [
{
"key": "<string>",
"label": "<string>",
"options": ["<string>"],
"required": True
}
],
"successUrl": "<string>",
"cancelUrl": "<string>",
"metadata": {},
"expirationMinutes": 21602
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"id": "chk_byd8p3p79re859jpkmr0j65n3",
"slug": "plano-pro-mensal",
"status": "active",
"mode": "subscription",
"currency": "BRL",
"locale": "pt-BR",
"name": "Plano Pro Mensal",
"description": "Assinatura mensal do plano Pro",
"sellable": true,
"config": {
"items": [
{
"name": "Plano Pro",
"quantity": 1,
"unitAmount": 9900,
"chargeType": "recurring"
}
],
"paymentMethods": {
"card": {
"enabled": true
},
"pix": {
"enabled": true
}
},
"subscription": {
"planId": "plan_edz8m3vbxbvobrom0qlxbq68h",
"recurrence": {
"interval": 1,
"unit": "month"
},
"currency": "BRL",
"trialDays": 7,
"collectionTiming": "prepaid"
}
},
"requiredFields": [
"email",
"document",
"phone"
],
"customFields": null,
"successUrl": "https://app.com/welcome",
"cancelUrl": null,
"metadata": null,
"expirationMinutes": 1440,
"createdAt": "2025-06-20T09:00:00.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z",
"url": "https://pay.z2pay.com/c/plano-pro-mensal"
}{
"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": {
"code": "NOT_FOUND",
"message": "Checkout link not found"
}
}{
"error": "A request with this idempotency key is already being processed"
}{
"error": "Idempotency key already used with a different request body"
}Atualizar checkout link
Altera um template existente. Só os campos enviados mudam, e a mudança não alcança Sessions já criadas.
curl --request PATCH \
--url https://api.sandbox.z2pay.com/v1/checkout/links/{id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "<string>",
"description": "<string>",
"slug": "<string>",
"mode": "payment",
"currency": "BRL",
"locale": "pt-BR",
"items": [],
"paymentMethods": {},
"splits": [
{
"recipientId": "<string>",
"percentage": 50.005,
"liable": true,
"processingFee": true
}
],
"branding": {
"primaryColor": "<string>",
"logoUrl": "<string>",
"merchantName": "<string>",
"faviconUrl": "<string>",
"coverUrl": "<string>"
},
"subscription": {
"planId": "<string>",
"currency": "BRL",
"trialDays": 182,
"maxCycles": 1,
"collectionTiming": "prepaid",
"metadata": {},
"itemCovers": {},
"maxEnrollmentInstallments": 1
},
"requiredFields": [],
"customFields": [
{
"key": "<string>",
"label": "<string>",
"options": [
"<string>"
],
"required": true
}
],
"successUrl": "<string>",
"cancelUrl": "<string>",
"metadata": {},
"expirationMinutes": 21602
}
'const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
slug: '<string>',
mode: 'payment',
currency: 'BRL',
locale: 'pt-BR',
items: [],
paymentMethods: {},
splits: [
{recipientId: '<string>', percentage: 50.005, liable: true, processingFee: true}
],
branding: {
primaryColor: '<string>',
logoUrl: '<string>',
merchantName: '<string>',
faviconUrl: '<string>',
coverUrl: '<string>'
},
subscription: {
planId: '<string>',
currency: 'BRL',
trialDays: 182,
maxCycles: 1,
collectionTiming: 'prepaid',
metadata: {},
itemCovers: {},
maxEnrollmentInstallments: 1
},
requiredFields: [],
customFields: [{key: '<string>', label: '<string>', options: ['<string>'], required: true}],
successUrl: '<string>',
cancelUrl: '<string>',
metadata: {},
expirationMinutes: 21602
})
};
fetch('https://api.sandbox.z2pay.com/v1/checkout/links/{id}', 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/links/{id}"
payload = {
"name": "<string>",
"description": "<string>",
"slug": "<string>",
"mode": "payment",
"currency": "BRL",
"locale": "pt-BR",
"items": [],
"paymentMethods": {},
"splits": [
{
"recipientId": "<string>",
"percentage": 50.005,
"liable": True,
"processingFee": True
}
],
"branding": {
"primaryColor": "<string>",
"logoUrl": "<string>",
"merchantName": "<string>",
"faviconUrl": "<string>",
"coverUrl": "<string>"
},
"subscription": {
"planId": "<string>",
"currency": "BRL",
"trialDays": 182,
"maxCycles": 1,
"collectionTiming": "prepaid",
"metadata": {},
"itemCovers": {},
"maxEnrollmentInstallments": 1
},
"requiredFields": [],
"customFields": [
{
"key": "<string>",
"label": "<string>",
"options": ["<string>"],
"required": True
}
],
"successUrl": "<string>",
"cancelUrl": "<string>",
"metadata": {},
"expirationMinutes": 21602
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"id": "chk_byd8p3p79re859jpkmr0j65n3",
"slug": "plano-pro-mensal",
"status": "active",
"mode": "subscription",
"currency": "BRL",
"locale": "pt-BR",
"name": "Plano Pro Mensal",
"description": "Assinatura mensal do plano Pro",
"sellable": true,
"config": {
"items": [
{
"name": "Plano Pro",
"quantity": 1,
"unitAmount": 9900,
"chargeType": "recurring"
}
],
"paymentMethods": {
"card": {
"enabled": true
},
"pix": {
"enabled": true
}
},
"subscription": {
"planId": "plan_edz8m3vbxbvobrom0qlxbq68h",
"recurrence": {
"interval": 1,
"unit": "month"
},
"currency": "BRL",
"trialDays": 7,
"collectionTiming": "prepaid"
}
},
"requiredFields": [
"email",
"document",
"phone"
],
"customFields": null,
"successUrl": "https://app.com/welcome",
"cancelUrl": null,
"metadata": null,
"expirationMinutes": 1440,
"createdAt": "2025-06-20T09:00:00.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z",
"url": "https://pay.z2pay.com/c/plano-pro-mensal"
}{
"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": {
"code": "NOT_FOUND",
"message": "Checkout link not found"
}
}{
"error": "A request with this idempotency key is already being processed"
}{
"error": "Idempotency key already used with a different request body"
}PATCH /checkout/links/{id}
Faz parte do recurso Links — o conceito e os estados estão lá.
Todos os campos são opcionais: só o que você envia muda. A resposta é 200 com o Link inteiro,
já atualizado.
status; pelo painel dá,
pela integração não. Veja Arquivar.null são coisas diferentes. Campo ausente fica como está; null explícito
apaga. É a única forma de remover um slug, um successUrl ou uma description já gravados.
Vale para name, description, slug, successUrl, cancelUrl, metadata, requiredFields,
customFields e expirationMinutes.slug revalida a unicidade global. Se o novo já pertence a outro Link — de qualquer
conta —, a resposta é 409 com key: "errors.checkout.slug_taken". Reenviar o mesmo slug não
dispara a checagem.Exemplo
curl -X PATCH https://api.sandbox.z2pay.com/v1/checkout/links/chk_byd8p3p79re859jpkmr0j65n3 \
-H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
-H "Content-Type: application/json" \
-d '{
"items": [{ "name": "Curso de Backend — vitalício", "quantity": 1, "unitAmount": 39900 }]
}'
{
"id": "chk_byd8p3p79re859jpkmr0j65n3",
"name": "Curso de Backend",
"status": "active",
"sellable": true,
"config": {
"items": [
{ "name": "Curso de Backend — vitalício", "quantity": 1, "unitAmount": 39900 }
],
"...": "..."
},
"updatedAt": "2026-06-25T09:14:00.000Z",
"url": "https://pay.sandbox.z2pay.com/c/chk_byd8p3p79re859jpkmr0j65n3"
}
Authorizations
API key unificada (z2_{live|test}{sk|pk}...) — secret (sk) para integração backend, publishable (pk) para uso no frontend público
Path Parameters
ID do CheckoutLink
Body
Nome do link de checkout.
255Descrição exibida no checkout.
2000Slug único global usado na URL pública /c/{slug} (a-z, 0-9 e hífen).
3 - 100^[a-z0-9-]+$'payment' (default) para pagamento único; 'subscription' exige o objeto subscription populado.
payment, subscription Moeda da cobrança. Só BRL — os gateways liquidam em real.
BRL Idioma do checkout (default 'pt-BR').
pt-BR, en-US, es-ES Itens do carrinho (unitAmount em centavos); ao menos 1 quando mode=payment.
Show child attributes
Show child attributes
Métodos de pagamento habilitados (card/pix/boleto/combined); ao menos um enabled.
Show child attributes
Show child attributes
Divisão de receita por percentual; a soma deve ser exatamente 100.
Show child attributes
Show child attributes
Customização visual do checkout.
Show child attributes
Show child attributes
Configuração de recorrência; obrigatória (e exclusiva) quando mode=subscription. Sem startAt: um Link é template reutilizável, então não há como adiar "o início" de algo que cada comprador ativa em um momento diferente — disponível apenas na venda rápida.
Show child attributes
Show child attributes
Campos do comprador exigidos no checkout (email, document, phone, address).
email, document, phone, address Campos customizados do formulário (máx. 20).
20Show child attributes
Show child attributes
URL de redirecionamento após pagamento aprovado.
2000URL de redirecionamento quando o comprador cancela.
2000Metadados do seller (string → string), consultáveis no próprio link. Não são propagados à Transaction; para correlacionar vendas ao link nos webhooks, use o additionalInfo.checkoutLinkId da Transaction.
Show child attributes
Show child attributes
Expiração da sessão em minutos (5 a 43200 = 30 dias).
5 <= x <= 43200Response
Link atualizado
Identificador único do registro.
Slug único global usado na URL pública /c/{slug}.
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).
Nome de exibição do registro.
Descrição exibida no checkout.
Se o Link pode vender agora. É false quando um recebedor do splits, ou o dono da conta, não está ativo no PSP — o comprador vê uma página de indisponível. Independente do status.
Snapshot da configuração do checkout (formas de pagamento, itens e personalização visual).
Campos do comprador exigidos no checkout (ex.: email, document, phone, address).
Definições dos campos personalizados solicitados no checkout.
URL de redirecionamento após o pagamento ser concluído com sucesso.
URL de redirecionamento quando o comprador cancela o checkout.
Metadados livres (pares chave-valor) para uso do integrador; não afeta o processamento.
Tempo de validade da sessão de checkout, em minutos.
Data e hora de criação do registro (ISO 8601).
Data e hora da última atualização do registro (ISO 8601).
URL pública do checkout para o comprador finalizar o pagamento.