Saltar al contenido principal
Un Checkout Link (chk_) es una plantilla de cobro reutilizable. Lo defines una sola vez (ítems, precio, métodos, branding) y publicas la URL cuantas veces quieras — cada acceso de un comprador materializa una CheckoutSession independiente. Ideal para el link en bio de Instagram, páginas de captura o cualquier difusión masiva.
Los ejemplos usan el sandbox: API en https://checkout-api.sandbox.z2pay.com y página en https://pay.sandbox.z2pay.com. En producción, usa https://checkout-api.z2pay.com y https://pay.z2pay.com. Todas las solicitudes usan el header x-api-key — consulta Autenticación.

Endpoints

MétodoRutaDescripción
POST/checkout/linksCrea una plantilla de cobro
GET/checkout/linksLista plantillas (paginado)
GET/checkout/links/{id}Obtiene una plantilla por ID
PUT/checkout/links/{id}Actualiza una plantilla
DELETE/checkout/links/{id}Archiva (soft-delete) una plantilla
name
string
Nombre interno (≤ 255 caracteres), visible para el seller, no para el comprador. Útil para organizar la lista en el panel.
description
string
Descripción interna (≤ 2000 caracteres).
slug
string
Identificador URL-friendly. Regex ^[a-z0-9-]+$, 3–100 caracteres. Reservado para una futura funcionalidad de URL amigable.
mode
string
predeterminado:"payment"
requerido
Por ahora, solo "payment".
currency
string
predeterminado:"BRL"
requerido
Código ISO 4217. Por ahora, solo "BRL".
locale
string
predeterminado:"pt-BR"
requerido
Idioma de la página: "pt-BR", "en-US" o "es-ES".
items
array
requerido
Ítems del cobro (≥ 1). La suma de quantity × unitAmount es el total a cobrar. Ver Item.
paymentMethods
object
requerido
Métodos aceptados. Al menos un método debe estar habilitado. Ver Métodos de pago.
splits
array
Distribución multi-seller. La suma de los percentage debe ser exactamente 100. Ver Split.
branding
object
Color primario, logo y nombre del seller. Ver Branding.
requiredFields
array
Campos del comprador que serán obligatorios además de los siempre-requeridos. Ver Required fields.
customFields
array
Campos personalizados (≤ 20) solicitados al comprador. Ver Custom fields.
successUrl
string
URL de redirección (≤ 2000) tras el pago aprobado.
cancelUrl
string
URL de redirección (≤ 2000) al cancelar.
metadata
object
Mapa string → string con datos arbitrarios del seller (opaco para el servidor; se devuelve en los webhooks).
expirationMinutes
number
predeterminado:"1440"
Tiempo de validez de la Session desde su creación, en minutos. Mínimo 5, máximo 43200 (30 días). Por defecto 1440 (24h).
Centavos, siempre. Todo valor monetario es un entero en centavos. R99,90=9990.Enviar9.90esrechazadoporlavalidacioˊn(integerrequerido);9seaceptarıˊacomo9centavos(R 99,90 = `9990`. Enviar `9.90` es rechazado por la validación (`integer` requerido); `9` se aceptaría como **9 centavos** (R 0,09). Ver Convenciones.

Item (CheckoutItem)

name
string
requerido
Nombre mostrado al comprador (1–255 caracteres).
description
string
Descripción mostrada debajo del nombre (≤ 2000 caracteres).
imageUrl
string
Imagen mostrada junto al ítem. Cualquier URL HTTPS pública (≤ 2000 caracteres).
quantity
number
requerido
Cantidad (entero ≥ 1).
unitAmount
number
requerido
Valor unitario en centavos (entero ≥ 1). R$ 99,90 = 9990.
metadata
object
Mapa string → string con identificadores internos del seller (sku, course_id, etc.).

Métodos de pago (paymentMethods)

card
object
Configuración de tarjeta. card.enabled (boolean) activa/desactiva. card.installments define las cuotas (ver abajo). card.multipleCards (boolean) permite dividir el total entre 2 tarjetas.
card.installments
object
Cuotas. maxInstallments (1–12, obligatorio), freeInstallments (0–12, por defecto 0, cuotas iniciales sin interés), interestRate (0–100, tasa mensual en %, ej. 2.99), interestType ("simple" o "compound", por defecto "compound" = Precio/Tabla).
pix
object
Configuración de PIX. pix.enabled (boolean) activa/desactiva. pix.expiresIn (60–86400) es la expiración del código QR en segundos (60s a 24h).
boleto
object
Configuración de boleto. boleto.enabled (boolean) activa/desactiva. boleto.dueDateDays (1–30) es el número de días hasta el vencimiento.
combined
object
Pago combinado (dividir el total entre métodos/tarjetas). enabled (boolean, obligatorio), minAmountPerPayment (centavos, por defecto 1), maxPaymentsCount (2–8, por defecto 4).
Al menos un método (card, pix o boleto) debe tener enabled: true. De lo contrario, la validación rechaza el body (400).

Split

Distribuye el valor recibido entre múltiples destinatarios (marketplace, socios, plataformas).
recipientId
string
requerido
ID del recipient (rec_*) que recibe la parte correspondiente.
percentage
number
requerido
Porcentaje del valor total (0.01–100). Acepta decimales (ej. 33.33).
liable
boolean
Marca al recipient como responsable de los chargebacks (típicamente el seller principal).
La suma de los percentage de todos los splits debe ser exactamente 100 (tolerancia numérica ±0.01 para redondeos). De lo contrario, la validación devuelve 400 invalid_splits_sum. Para el modelo conceptual de split, consulta también Splits de la Core API.

Branding

primaryColor
string
Color primario en hexadecimal. Regex ^#([0-9a-f]{6}|[0-9a-f]{3})$/i, ej. "#1e3b79" o "#FFF". Las variaciones (hover, contraste de texto) se calculan automáticamente.
logoUrl
string
Logo del seller mostrado en el header de la página (≤ 2000 caracteres).
merchantName
string
Nombre del seller mostrado en la página (≤ 100 caracteres), cuando no hay logo o junto a él.
mobileLayout
string
"single-page" o "step-by-step" — controla el layout del checkout en dispositivos móviles.
faviconUrl
string
Favicon de la página, ícono de la pestaña del navegador (≤ 2000 caracteres).

Required fields

Lista de campos del comprador que serán obligatorios además de los siempre-requeridos.
"requiredFields": ["email", "document", "phone", "address"]
Valores aceptados: "email", "document", "phone", "address".
email, document y phone son siempre obligatorios en el momento del confirm, aunque no los incluyas aquí. Incluir "address" obliga al comprador a completar la dirección completa.

Custom fields

Permite solicitar información adicional al comprador (texto, dropdown, checkbox).
key
string
requerido
Identificador interno del campo. Regex ^[a-z][a-z0-9_]*$/i, ≤ 50 caracteres.
label
string | object
requerido
Label mostrado. String simple ("Empresa") o mapa por idioma ({ "pt-BR": "Empresa", "en-US": "Company" }).
type
string
requerido
"text", "select" o "checkbox".
options
array
Obligatorio si type = "select". Acepta strings ("Opción 1") u objetos { value, label } con label localizable.
required
boolean
Si true, el comprador está obligado a completarlo.

POST /checkout/links
Crea una plantilla persistente. Devuelve 201. Soporta idempotencia mediante el header Idempotency-Key (ver Convenciones).
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" }
  }'
Respuesta (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..."
}
La url devuelta es el link de pago listo para compartir. Cada apertura materializa una Session nueva.

Errores comunes

HTTPCodeCuándo
400validation_failedBody malformado (falta items, valor no entero, etc.)
400no_itemsArray items vacío
400amount_too_lowLa suma de los ítems resulta en 0
400invalid_splits_sumLos splits no suman 100
401unauthenticatedx-api-key ausente, inválido o revocado
409slug_takenYa existe un Link con ese slug
409idempotency_conflictLa misma Idempotency-Key fue usada con un body diferente
Ver Errores para el formato completo.
GET /checkout/links
Lista paginada de plantillas del tenant.
status
string
Filtra por estado (CSV). Ej.: ?status=active o ?status=active,archived.
Búsqueda en name y description (≤ 255 caracteres).
page
number
predeterminado:"1"
Número de página (≥ 1).
limit
number
predeterminado:"20"
Ítems 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
Respuesta (200):
{
  "data": [
    { "id": "chk_...", "name": "...", "url": "https://pay.sandbox.z2pay.com/c/chk_...", "...": "..." }
  ],
  "total": 12,
  "page": 1,
  "limit": 20
}

GET /checkout/links/{id}
Devuelve los datos completos de un Link (mismo formato que el POST).
curl https://checkout-api.sandbox.z2pay.com/checkout/links/chk_abc123 \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"
Estados posibles: 200 (encontrado) · 404 (no encontrado).
PUT /checkout/links/{id}
Actualiza un Link existente. Todos los campos son opcionales — solo los enviados son modificados. Devuelve 200. Soporta idempotencia mediante Idempotency-Key.
Actualizar el Link no afecta las Sessions ya materializadas — estas conservan el snapshot del momento de su creación. Los cambios solo aplican a 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 }]
  }'
Estados posibles: 200 (actualizado) · 404 (no encontrado) · 400 (validación).
DELETE /checkout/links/{id}
Soft-delete. La URL pública (/c/chk_...) comenzará a devolver 404 y no podrán crearse nuevas Sessions a partir de ella. Las Sessions ya creadas continúan funcionando con normalidad. Devuelve 200 con la entidad que contiene deletedAt completado. Soporta idempotencia.
curl -X DELETE https://checkout-api.sandbox.z2pay.com/checkout/links/chk_abc123 \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX"
Respuesta (200):
{
  "id": "chk_abc123...",
  "status": "archived",
  "deletedAt": "2026-06-24T13:00:00.000Z",
  "...": "..."
}
Estados posibles: 200 (archivado) · 404 (no encontrado).

Galería de ejemplos

Payloads listos para POST /checkout/links. Abre la url devuelta para verificar visualmente.
{
  "name": "Apenas cartão",
  "items": [{ "name": "Produto Teste", "quantity": 1, "unitAmount": 19900 }],
  "paymentMethods": {
    "card": { "enabled": true, "installments": { "maxInstallments": 6, "freeInstallments": 1 } }
  }
}
Una sola pestaña “Tarjeta”. El selector muestra 1× sin interés, 2–6× con interés.
{
  "name": "Apenas PIX",
  "items": [{ "name": "Doação", "quantity": 1, "unitAmount": 5000 }],
  "paymentMethods": { "pix": { "enabled": true, "expiresIn": 3600 } }
}
Pestaña PIX única; el código QR expira en 1h.
{
  "name": "Apenas boleto",
  "items": [{ "name": "Mensalidade", "quantity": 1, "unitAmount": 12000 }],
  "paymentMethods": { "boleto": { "enabled": true, "dueDateDays": 5 } }
}
Pestaña boleto única; vencimiento en 5 días.
{
  "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 pestañas; tarjeta hasta 12× sin interés; PIX 30min; boleto 3 días.
{
  "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 líneas de ítem; 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 } }
}
Miniatura a la izquierda; descripción debajo del nombre; cantidad 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"
  }
}
Botones/acciones en verde; logo en el header; nombre “Loja Verde” visible.
{
  "name": "Inglês",
  "locale": "en-US",
  "items": [{ "name": "Online Course", "quantity": 1, "unitAmount": 29900 }],
  "paymentMethods": { "card": { "enabled": true } }
}
Usa "locale": "es-ES" para la página en español. Toda la página sigue el idioma seleccionado.
{
  "name": "Endereço obrigatório",
  "items": [{ "name": "Produto físico", "quantity": 1, "unitAmount": 8900 }],
  "paymentMethods": { "card": { "enabled": true } },
  "requiredFields": ["email", "document", "phone", "address"]
}
El formulario de dirección completa aparece antes del pago.
{
  "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 adicionales; select con 3 opciones; checkbox opcional. Bloquea el confirm sin 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 }
  ]
}
El comprador ve el total R100,00;traselpago,R 100,00; tras el pago, R 70 van al seller principal y R$ 30 a la 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× sin interés; 4–10× con 2,99% mensual (Precio/Tabla). El comprador ve el valor de la cuota y el 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"
}
Tras la aprobación, el comprador es redirigido a successUrl. Puedes usar {CHECKOUT_SESSION_ID} como marcador de posición — lo reemplazamos por el cs_* antes de redirigir.
{
  "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 ítems, 3 métodos, combined hasta 3 entradas, split 80/20, branding completo, dirección obligatoria, 2 custom fields, redirects, expira en 3 días.

Ver también

Visión general del Checkout

Conceptos, casos de uso y mapa de endpoints.

Checkout Sessions

Materializa Sessions a partir de un Link.

Webhooks

Eventos checkout.link.* y checkout.session.*.

Errores

Formato de los errores y cómo manejar 400 / 404 / 409.