Pular para o conteúdo principal
Um Checkout Link (chk_) é um template de cobrança reutilizável. Você define uma vez (itens, preço, métodos, branding) e divulga a URL quantas vezes quiser — cada acesso de comprador materializa uma CheckoutSession independente. Ideal para link na bio do Instagram, página de captura ou qualquer divulgação em massa.
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. Todas as requisições usam o header x-api-key — veja Autenticação.

Endpoints

MétodoRotaDescrição
POST/checkout/linksCria um template de cobrança
GET/checkout/linksLista templates (paginado)
GET/checkout/links/{id}Busca um template pelo ID
PUT/checkout/links/{id}Atualiza um template
DELETE/checkout/links/{id}Arquiva (soft-delete) um template
name
string
Nome interno (≤ 255 chars), visível ao seller, não ao comprador. Útil para organizar a lista do painel.
description
string
Descrição interna (≤ 2000 chars).
slug
string
Identificador URL-friendly. Regex ^[a-z0-9-]+$, 3–100 chars. Reservado para feature futura de URL amigável.
mode
string
padrão:"payment"
obrigatório
Hoje apenas "payment".
currency
string
padrão:"BRL"
obrigatório
Código ISO 4217. Hoje apenas "BRL".
locale
string
padrão:"pt-BR"
obrigatório
Idioma da página: "pt-BR", "en-US" ou "es-ES".
items
array
obrigatório
Itens da cobrança (≥ 1). A soma de quantity × unitAmount é o total a cobrar. Veja Item.
paymentMethods
object
obrigatório
Métodos aceitos. Pelo menos um método deve estar habilitado. Veja Métodos de pagamento.
splits
array
Distribuição multi-seller. A soma das percentage deve ser exatamente 100. Veja Split.
branding
object
Cor primária, logo e nome do seller. Veja Branding.
requiredFields
array
Campos do comprador obrigatórios além dos sempre-obrigatórios. Veja Required fields.
customFields
array
Campos customizados (≤ 20) pedidos ao comprador. Veja Custom fields.
successUrl
string
URL de redirect (≤ 2000) após pagamento aprovado.
cancelUrl
string
URL de redirect (≤ 2000) ao cancelar.
metadata
object
Mapa string → string com dados arbitrários do seller (opaco ao servidor; retorna nos webhooks).
expirationMinutes
number
padrão:"1440"
Tempo de validade da Session a partir da criação, em minutos. Mínimo 5, máximo 43200 (30 dias). Default 1440 (24h).
Centavos, sempre. Todo valor monetário é inteiro em centavos. R99,90=9990.Enviar9.90eˊrejeitadopelavalidac\ca~o(integerrequerido);9seriaaceitocomo9centavos(R 99,90 = `9990`. Enviar `9.90` é rejeitado pela validação (`integer` requerido); `9` seria aceito como **9 centavos** (R 0,09). Veja Convenções.

Item (CheckoutItem)

name
string
obrigatório
Nome exibido ao comprador (1–255 chars).
description
string
Descrição mostrada abaixo do nome (≤ 2000 chars).
imageUrl
string
Imagem exibida ao lado do item. Qualquer URL HTTPS pública (≤ 2000 chars).
quantity
number
obrigatório
Quantidade (inteiro ≥ 1).
unitAmount
number
obrigatório
Valor unitário em centavos (inteiro ≥ 1). R$ 99,90 = 9990.
metadata
object
Mapa string → string com identificadores internos do seller (sku, course_id, etc.).

Métodos de pagamento (paymentMethods)

card
object
Configuração de cartão. card.enabled (boolean) liga/desliga. card.installments define o parcelamento (veja abaixo). card.multipleCards (boolean) permite dividir o total entre 2 cartões.
card.installments
object
Parcelamento. maxInstallments (1–12, obrigatório), freeInstallments (0–12, default 0, parcelas iniciais sem juros), interestRate (0–100, taxa mensal em %, ex. 2.99), interestType ("simple" ou "compound", default "compound" = Price/Tabela).
pix
object
Configuração de PIX. pix.enabled (boolean) liga/desliga. pix.expiresIn (60–86400) é a expiração do QR code em segundos (60s a 24h).
boleto
object
Configuração de boleto. boleto.enabled (boolean) liga/desliga. boleto.dueDateDays (1–30) é o número de dias até o vencimento.
combined
object
Pagamento combinado (dividir o total entre métodos/cartões). enabled (boolean, obrigatório), minAmountPerPayment (centavos, default 1), maxPaymentsCount (2–8, default 4).
Pelo menos um método (card, pix ou boleto) deve ter enabled: true. Caso contrário, a validação rejeita o body (400).

Split

Distribui o valor recebido entre múltiplos recipients (marketplace, parceiros, plataformas).
recipientId
string
obrigatório
ID do recipient (rec_*) que recebe a parcela.
percentage
number
obrigatório
Porcentagem do valor total (0.01–100). Aceita decimais (ex. 33.33).
liable
boolean
Marca o recipient como responsável por chargebacks (tipicamente o seller principal).
A soma das percentage de todos os splits deve ser exatamente 100 (tolerância numérica ±0.01 para arredondamento). Caso contrário, a validação retorna 400 invalid_splits_sum. Para o modelo conceitual de split, veja também Splits da Core API.

Branding

primaryColor
string
Cor primária em hex. Regex ^#([0-9a-f]{6}|[0-9a-f]{3})$/i, ex. "#1e3b79" ou "#FFF". Derivações (hover, contraste de texto) são calculadas automaticamente.
logoUrl
string
Logo do seller exibido no header da página (≤ 2000 chars).
merchantName
string
Nome do seller exibido na página (≤ 100 chars), caso não tenha logo ou ao lado dele.
mobileLayout
string
"single-page" ou "step-by-step" — controla o layout do checkout em mobile.
faviconUrl
string
Favicon da página, ícone da aba do navegador (≤ 2000 chars).

Required fields

Lista de campos do comprador que serão obrigatórios além dos sempre-obrigatórios.
"requiredFields": ["email", "document", "phone", "address"]
Valores aceitos: "email", "document", "phone", "address".
email, document e phone são sempre obrigatórios no momento do confirm, mesmo que você não os liste aqui. Listar "address" força o comprador a preencher o endereço completo.

Custom fields

Permite pedir informações adicionais ao comprador (texto, dropdown, checkbox).
key
string
obrigatório
Identificador interno do campo. Regex ^[a-z][a-z0-9_]*$/i, ≤ 50 chars.
label
string | object
obrigatório
Label exibido. String simples ("Empresa") ou map por idioma ({ "pt-BR": "Empresa", "en-US": "Company" }).
type
string
obrigatório
"text", "select" ou "checkbox".
options
array
Obrigatório se type = "select". Aceita strings ("Opção 1") ou objetos { value, label } com label localizável.
required
boolean
Se true, o comprador é obrigado a preencher.

POST /checkout/links
Cria um template persistente. Retorna 201. Suporta idempotência via header Idempotency-Key (veja Convenções).
curl -X POST https://checkout-api.sandbox.z2pay.com/checkout/links \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
  -d '{
    "name": "Curso de Backend",
    "description": "Link para divulgação no Instagram",
    "items": [
      { "name": "Curso de Backend — vitalício", "quantity": 1, "unitAmount": 49900 }
    ],
    "paymentMethods": {
      "card": { "enabled": true, "installments": { "maxInstallments": 12, "freeInstallments": 3 } },
      "pix":  { "enabled": true, "expiresIn": 3600 }
    },
    "branding": { "primaryColor": "#1e3b79", "merchantName": "Henrique Cursos" },
    "metadata": { "campaign": "instagram-bio-2026-05" }
  }'
Resposta (201):
{
  "id": "chk_abc123...",
  "tenantId": "ten_xyz...",
  "name": "Curso de Backend",
  "description": "Link para divulgação no Instagram",
  "slug": null,
  "status": "active",
  "mode": "payment",
  "currency": "BRL",
  "locale": "pt-BR",
  "items": [
    {
      "id": "ci_...",
      "name": "Curso de Backend — vitalício",
      "quantity": 1,
      "unitAmount": 49900
    }
  ],
  "paymentMethods": { "...": "..." },
  "splits": null,
  "branding": { "...": "..." },
  "requiredFields": null,
  "customFields": null,
  "successUrl": null,
  "cancelUrl": null,
  "metadata": { "campaign": "instagram-bio-2026-05" },
  "expirationMinutes": 1440,
  "createdAt": "2026-06-24T12:00:00.000Z",
  "updatedAt": "2026-06-24T12:00:00.000Z",
  "deletedAt": null,
  "version": 0,
  "url": "https://pay.sandbox.z2pay.com/c/chk_abc123..."
}
A url retornada é o link de pagamento pronto para compartilhar. Cada abertura materializa uma Session nova.

Erros comuns

HTTPCodeQuando
400validation_failedBody malformado (falta items, valor não-inteiro, etc.)
400no_itemsArray items vazio
400amount_too_lowSoma dos itens resulta em 0
400invalid_splits_sumSplits não somam 100
401unauthenticatedx-api-key ausente, inválido ou revogado
409slug_takenJá existe um Link com esse slug
409idempotency_conflictMesma Idempotency-Key usada com body diferente
Veja Erros para o formato completo.
GET /checkout/links
Lista paginada de templates do tenant.
status
string
Filtra por status (CSV). Ex.: ?status=active ou ?status=active,archived.
Busca em name e description (≤ 255 chars).
page
number
padrão:"1"
Número da página (≥ 1).
limit
number
padrão:"20"
Itens por página (1–100).
curl -G https://checkout-api.sandbox.z2pay.com/checkout/links \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -d status=active \
  -d search=curso \
  -d page=1 \
  -d limit=20
Resposta (200):
{
  "data": [
    { "id": "chk_...", "name": "...", "url": "https://pay.sandbox.z2pay.com/c/chk_...", "...": "..." }
  ],
  "total": 12,
  "page": 1,
  "limit": 20
}

GET /checkout/links/{id}
Retorna os dados completos de um Link (mesmo formato do POST).
curl https://checkout-api.sandbox.z2pay.com/checkout/links/chk_abc123 \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"
Status possíveis: 200 (encontrado) · 404 (não encontrado).
PUT /checkout/links/{id}
Atualiza um Link existente. Todos os campos são opcionais — apenas os enviados são modificados. Retorna 200. Suporta idempotência via Idempotency-Key.
Atualizar o Link não afeta Sessions já materializadas — elas mantêm o snapshot do momento da criação. As mudanças só valem para Sessions futuras.
curl -X PUT https://checkout-api.sandbox.z2pay.com/checkout/links/chk_abc123 \
  -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 }]
  }'
Status possíveis: 200 (atualizado) · 404 (não encontrado) · 400 (validação).
DELETE /checkout/links/{id}
Soft-delete. A URL pública (/c/chk_...) passa a retornar 404 e novas Sessions não podem mais ser criadas a partir dele. Sessions já criadas continuam funcionando normalmente. Retorna 200 com a entidade contendo deletedAt preenchido. Suporta idempotência.
curl -X DELETE https://checkout-api.sandbox.z2pay.com/checkout/links/chk_abc123 \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"
Resposta (200):
{
  "id": "chk_abc123...",
  "status": "archived",
  "deletedAt": "2026-06-24T13:00:00.000Z",
  "...": "..."
}
Status possíveis: 200 (arquivado) · 404 (não encontrado).

Galeria de exemplos

Payloads prontos para POST /checkout/links. Abra a url retornada para conferir visualmente.
{
  "name": "Apenas cartão",
  "items": [{ "name": "Produto Teste", "quantity": 1, "unitAmount": 19900 }],
  "paymentMethods": {
    "card": { "enabled": true, "installments": { "maxInstallments": 6, "freeInstallments": 1 } }
  }
}
Uma única aba “Cartão”. Seletor mostra 1× sem juros, 2–6× com juros.
{
  "name": "Apenas PIX",
  "items": [{ "name": "Doação", "quantity": 1, "unitAmount": 5000 }],
  "paymentMethods": { "pix": { "enabled": true, "expiresIn": 3600 } }
}
Aba PIX única, QR code expira em 1h.
{
  "name": "Apenas boleto",
  "items": [{ "name": "Mensalidade", "quantity": 1, "unitAmount": 12000 }],
  "paymentMethods": { "boleto": { "enabled": true, "dueDateDays": 5 } }
}
Aba boleto única, vencimento em 5 dias.
{
  "name": "Todos os métodos",
  "items": [{ "name": "E-book Premium", "quantity": 1, "unitAmount": 9900 }],
  "paymentMethods": {
    "card":   { "enabled": true, "installments": { "maxInstallments": 12, "freeInstallments": 12 } },
    "pix":    { "enabled": true, "expiresIn": 1800 },
    "boleto": { "enabled": true, "dueDateDays": 3 }
  }
}
3 abas; cartão até 12× sem juros; PIX 30min; boleto 3 dias.
{
  "name": "Múltiplos itens",
  "items": [
    { "name": "Curso Backend", "quantity": 1, "unitAmount": 49900 },
    { "name": "Material PDF", "quantity": 1, "unitAmount": 4900 },
    { "name": "Mentoria (3x)", "quantity": 3, "unitAmount": 15000 }
  ],
  "paymentMethods": { "card": { "enabled": true } }
}
3 linhas de item, total R$ 998,00 (49900 + 4900 + 3 × 15000).
{
  "name": "Item com imagem",
  "items": [{
    "name": "Camiseta Tech — Tamanho M",
    "description": "100% algodão, estampa em silk",
    "imageUrl": "https://exemplo.com/camiseta-m.jpg",
    "quantity": 2,
    "unitAmount": 7900
  }],
  "paymentMethods": { "card": { "enabled": true }, "pix": { "enabled": true } }
}
Thumbnail à esquerda; descrição abaixo do nome; quantidade 2; total R$ 158,00.
{
  "name": "Branding completo",
  "items": [{ "name": "Produto", "quantity": 1, "unitAmount": 5000 }],
  "paymentMethods": { "pix": { "enabled": true } },
  "branding": {
    "primaryColor": "#16a34a",
    "merchantName": "Loja Verde",
    "logoUrl": "https://exemplo.com/logo-verde.png"
  }
}
Botões/ações em verde; logo no header; nome “Loja Verde” exibido.
{
  "name": "Inglês",
  "locale": "en-US",
  "items": [{ "name": "Online Course", "quantity": 1, "unitAmount": 29900 }],
  "paymentMethods": { "card": { "enabled": true } }
}
Use "locale": "es-ES" para a página em espanhol. A página inteira segue o idioma escolhido.
{
  "name": "Endereço obrigatório",
  "items": [{ "name": "Produto físico", "quantity": 1, "unitAmount": 8900 }],
  "paymentMethods": { "card": { "enabled": true } },
  "requiredFields": ["email", "document", "phone", "address"]
}
O form de endereço completo aparece antes do pagamento.
{
  "name": "Custom fields",
  "items": [{ "name": "Workshop", "quantity": 1, "unitAmount": 19900 }],
  "paymentMethods": { "pix": { "enabled": true } },
  "customFields": [
    { "key": "company_name", "label": "Nome da empresa", "type": "text", "required": false },
    {
      "key": "experience_level",
      "label": { "pt-BR": "Nível de experiência", "en-US": "Experience level" },
      "type": "select",
      "options": [
        { "value": "junior", "label": "Júnior" },
        { "value": "pleno",  "label": "Pleno" },
        { "value": "senior", "label": "Sênior" }
      ],
      "required": true
    },
    { "key": "newsletter", "label": "Quero receber novidades por e-mail", "type": "checkbox" }
  ]
}
3 campos extras; select com 3 opções; checkbox opcional. Bloqueia o confirm sem experience_level.
{
  "name": "Marketplace 70/30",
  "items": [{ "name": "Pedido marketplace", "quantity": 1, "unitAmount": 10000 }],
  "paymentMethods": { "card": { "enabled": true }, "pix": { "enabled": true } },
  "splits": [
    { "recipientId": "rec_seller_principal", "percentage": 70, "liable": true },
    { "recipientId": "rec_plataforma",       "percentage": 30 }
  ]
}
Comprador vê total R100,00;apoˊspagar,R 100,00; após pagar, R 70 vão para o seller principal e R$ 30 para a plataforma.
{
  "name": "Juros compostos",
  "items": [{ "name": "Notebook", "quantity": 1, "unitAmount": 350000 }],
  "paymentMethods": {
    "card": {
      "enabled": true,
      "installments": {
        "maxInstallments": 10,
        "freeInstallments": 3,
        "interestRate": 2.99,
        "interestType": "compound"
      }
    }
  }
}
1×/2×/3× sem juros; 4–10× com 2,99% ao mês (Price/Tabela). Comprador vê o valor da parcela e o total final.
{
  "name": "Com redirects",
  "items": [{ "name": "Produto", "quantity": 1, "unitAmount": 5000 }],
  "paymentMethods": { "card": { "enabled": true } },
  "successUrl": "https://meu-site.com/pedido/obrigado?session={CHECKOUT_SESSION_ID}",
  "cancelUrl":  "https://meu-site.com/carrinho"
}
Após aprovação, o comprador é redirecionado para successUrl. Você pode usar {CHECKOUT_SESSION_ID} como placeholder — substituímos pelo cs_* antes de redirecionar.
{
  "name": "Kitchen-sink",
  "description": "Link com tudo configurado",
  "mode": "payment",
  "currency": "BRL",
  "locale": "pt-BR",
  "items": [
    { "name": "Produto A", "description": "...", "imageUrl": "https://...", "quantity": 2, "unitAmount": 9900 },
    { "name": "Produto B", "quantity": 1, "unitAmount": 4900 }
  ],
  "paymentMethods": {
    "card":   { "enabled": true, "installments": { "maxInstallments": 12, "freeInstallments": 6, "interestRate": 1.99 } },
    "pix":    { "enabled": true, "expiresIn": 3600 },
    "boleto": { "enabled": true, "dueDateDays": 3 },
    "combined": { "enabled": true, "maxPaymentsCount": 3, "minAmountPerPayment": 1000 }
  },
  "splits": [
    { "recipientId": "rec_principal", "percentage": 80, "liable": true },
    { "recipientId": "rec_afiliado",  "percentage": 20 }
  ],
  "branding": {
    "primaryColor": "#1e3b79",
    "merchantName": "Empresa X",
    "logoUrl": "https://...",
    "mobileLayout": "step-by-step"
  },
  "requiredFields": ["email", "document", "phone", "address"],
  "customFields": [
    { "key": "company", "label": "Empresa", "type": "text", "required": false },
    { "key": "newsletter", "label": "Quero novidades", "type": "checkbox" }
  ],
  "successUrl": "https://meu-site.com/obrigado",
  "cancelUrl":  "https://meu-site.com/cancelado",
  "metadata": { "campaign": "lancamento-2026" },
  "expirationMinutes": 4320
}
2 itens, 3 métodos, combined até 3 entradas, split 80/20, branding completo, endereço obrigatório, 2 custom fields, redirects, expira em 3 dias.

Veja também

Visão geral do Checkout

Conceitos, casos de uso e mapa de endpoints.

Checkout Sessions

Materialize Sessions a partir de um Link.

Webhooks

Eventos checkout.link.* e checkout.session.*.

Erros

Formato dos erros e como tratar 400 / 404 / 409.