Saltar al contenido principal
Estos endpoints son consumidos por la página de pago hospedada (el navegador del comprador). Normalmente no los llamas directamente — quien los llama es la página de Z2Pay. Están documentados aquí por transparencia, o en caso de que quieras construir un checkout personalizado sobre nuestra API.
Autenticación: no se usa x-api-key. La autenticación es la posesión del ID cs_* (48 chars hex = 192 bits de entropía). Los endpoints públicos tienen rate-limit por IP.
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.

Endpoints

MétodoRutaQué haceRate-limit
GET/public/checkout/{id}Obtiene la configuración pública para renderizar la página60 req/min/IP
POST/public/checkout/{id}/openedMarca la Session como “abierta por el comprador”60 req/min/IP
POST/public/checkout/{id}/confirmConfirma el pago (tokenId + datos del comprador)10 req/min/IP
El {id} puede ser una Session (cs_*), un Link (chk_*) o un slug. Cuando recibe Link o slug, el endpoint materializa una Session nueva y la retorna.

Obtener configuración pública

GET /public/checkout/{id}
Devuelve los datos necesarios para renderizar la página de pago. Acepta Session (cs_*) o Link (chk_*). Cuando recibe un Link, materializa una Session nueva y la retorna.
sessionId
string
Solo cuando {id} es Link (chk_*). El cliente envía un ID candidato (cs_[a-f0-9]{48}, generado localmente con 192 bits) para que la Session sea materializada idempotentemente — un refresh con el mismo sessionId reutiliza la Session existente. Para cs_* directo, el parámetro es ignorado.
curl https://checkout-api.sandbox.z2pay.com/public/checkout/cs_a1b2c3d4...
Respuesta (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 }
  ]
}
La Session retornada es una vista pública enmascarada — no incluye metadata, tenantId ni transactionId. Solo lo necesario para renderizar la página.
Estados posibles: 200 · 404 (ID inválido o expirado).

Marcar como abierta

POST /public/checkout/{id}/opened
Idempotente — transita el estado created → opened solo en la primera llamada. Dispara el evento checkout.session.opened.
sessionId
string
Requerido solo cuando {id} es Link (chk_*). El mismo sessionId del GET; permite materializar idempotentemente la Session.
curl -X POST https://checkout-api.sandbox.z2pay.com/public/checkout/cs_a1b2c3d4.../opened \
  -H "Content-Type: application/json" \
  -d '{}'
Respuesta (200):
{ "session": { "id": "cs_...", "status": "opened", "openedAt": "2026-06-24T12:01:00.000Z" } }

Confirmar pago

POST /public/checkout/{id}/confirm
Envía los datos del comprador + token(s) de tarjeta para finalizar el pago. Acepta Session (cs_*) o Link (chk_*). Es idempotente mediante el header Idempotency-Key: las solicitudes repetidas devuelven la respuesta original y una llamada concurrente espera a que la primera termine — defensa primaria contra cobros duplicados.
El amount y los items no se aceptan en el body — se usan los de la Session (inmutable, patrón PaymentIntent de Stripe). Para cambiar el monto, crea una nueva Session.
Link archivado: el confirm revalida el estado del Link padre. Si el vendedor archivó el Link después de que la Session fue materializada, el confirm retorna 409 link_not_active — incluso si la Session ya existía. Garantiza que ningún pago sea procesado contra un Link discontinuado.

Body

payments
array
requerido
Entradas de pago (1–8). 1 entrada = flujo single-method; 2+ entradas = pago combinado (requiere paymentMethods.combined.enabled en la Session). La suma de los amount debe coincidir exactamente con session.amount.
customer
object
requerido
Datos completos del comprador. Deben satisfacer los requiredFields de la Session (email, document y phone son siempre obligatorios; address si está listado). Ver Customer.
customFieldsValues
object
Valores de los customFields de la Session. Las keys coinciden con customFields[].key; los valores son strings ("true"/"false" para checkbox); cada valor ≤ 2000 chars.
Cada entrada de payments se discrimina por paymentMethod:
{
  "paymentMethod": "credit_card",
  "amount": 8500,
  "card": {
    "tokenId": "tok_...",
    "holderName": "JOAO SILVA",
    "installments": 3
  }
}
tokenId es obligatorio; holderName opcional; installments de 1 a 12. Tokeniza la tarjeta mediante el Tokenizer antes del confirm.
{ "paymentMethod": "pix", "amount": 5000 }
{ "paymentMethod": "boleto", "amount": 12000 }

Ejemplo 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" }
  }'
Respuesta (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
    }
  ]
}
  • En PIX, pixUrl trae el payload BR-Code para la app bancaria; expiresAt indica el vencimiento.
  • En boleto, boletoUrl / boletoDigitableLine / boletoBarcode traen los datos del boleto.
  • Si es rechazado, session.status vuelve a opened (se permite reintento) y payments[].errorMessage / declineCode explican el motivo.
Estados posibles: 200 (resultado del pago, exitoso o rechazado) · 409 (Session en estado inválido — ya pagada, expirada, cancelada — o Link padre archivado → link_not_active).
Para probar aprobación y rechazo, usa las tarjetas de prueba del sandbox.

Ciclo del comprador (resumen)

1

Abre la URL

El comprador accede a https://pay.sandbox.z2pay.com/c/{id}. La página llama a GET /public/checkout/{id} para cargar la configuración.
2

La página marca como abierta

La página llama a POST /public/checkout/{id}/opened — la Session pasa de createdopened y dispara checkout.session.opened.
3

El comprador confirma

Al hacer clic en “Pagar”, la página tokeniza la tarjeta (si aplica) y llama a POST /public/checkout/{id}/confirm. La Session pasa por paying y termina en paid (o vuelve a opened si es rechazada).
4

Recibes el webhook

checkout.session.payment_succeeded (o payment_failed) llega a tu URL de webhook. Reconcilia mediante el metadata de la Session.

Ver también

Checkout Sessions

Estados de la Session y el objeto Customer.

Visión general del Checkout

Conceptos y mapa de endpoints.

Tokenizer

Cómo generar el tokenId de la tarjeta antes del confirm.

Tarjetas de prueba

Escenarios de aprobación y rechazo en el sandbox.

Webhooks

Eventos disparados a lo largo del ciclo del comprador.

Errores

Códigos de dominio del confirm (amount_mismatch, combined_disabled, etc.).