Skip to content

Changelog ​

Historial de cambios de la API de Zelta Pay. Cada versión incluye las nuevas funcionalidades, cambios y correcciones realizadas.

v1.5.0 (Actual) ​

Publicada en 2026.

Las respuestas de la API ya no incluyen campos internos: cada cargo y cada cliente se devuelven con los campos documentados de su objeto. Además, una API key de proyecto solo alcanza los links de pago de su proyecto. Los cargos, clientes y suscripciones se procesan igual que antes.

Cargos ​

  • devuelven los campos del . Las respuestas ya no incluyen campos internos: la respuesta cruda del procesador, la IP y el navegador del pagador, la clave de idempotencia, referencias internas del proveedor y de la orden, datos internos de conciliación ni deletedAt
  • expand acepta customer y product; cualquier otro valor (por ejemplo paymentLink) devuelve 400 con ERR_INVALID_RELATIONS
  • Un fields con un campo que no pertenece al objeto cargo devuelve 400 con ERR_INVALID_FIELDS
  • POST /v1/charges sigue aceptando idempotencyKey y su respuesta mantiene los mismos campos

Clientes y suscripciones ​

  • Todo cliente que devuelve la API usa los campos del : los endpoints /v1/customers, GET /v1/subscriptions/{id}, las respuestas de PATCH /v1/subscriptions/{id}/items y PATCH /v1/subscriptions/{id}/customer, y expand=customer
  • Las respuestas ya no incluyen customerVaultId, cardBin ni cardExp. paymentProvider, cardLast4 y cardBrand se mantienen
  • El BIN y el vencimiento de la tarjeta se siguen entregando en el webhook
  • guarda el id de la bóveda, el BIN y el vencimiento como antes, y responde con el objeto cliente sin esos campos
  • En GET /v1/customers, un fields con un campo que no pertenece al objeto cliente devuelve 400 con ERR_INVALID_FIELDS, y expand devuelve 400 con ERR_INVALID_RELATIONS
  • Con una API key de proyecto, , y solo alcanzan los links del proyecto: los creados con la API key de ese proyecto (POST /v1/payment-links y los links de colección). Regenerar la API key del proyecto no cambia qué links alcanza
  • Los links creados desde el dashboard o con la API key de otro proyecto no aparecen en el listado ni cuentan en total; obtenerlos o cancelarlos devuelve 404 con ERR_PAYMENT_LINK_NOT_FOUND, la misma respuesta que un link que no existe
  • Las API keys de la cuenta siguen alcanzando todos los links de pago de la cuenta. Consulta el

Notas de migración ​

  • Si tu integración leía cardBin o cardExp de una respuesta de la API, tómalos del webhook customer.created. Si adjuntas la tarjeta con POST /v1/customers/{id}/vault, guarda en tu sistema los valores que envías
  • Si leías customerVaultId, ya no lo necesitas para cobrar: los cargos y las suscripciones usan el id del cliente
  • Si usabas expand=paymentLink en GET /v1/charges, usa el campo paymentLinkId del cargo
  • Si tu integración leía un campo de cargo que ya no se devuelve, escríbenos a con el campo y el uso que le das
  • Para listar, obtener o cancelar links creados desde el dashboard o por otro proyecto, usa la API key de la cuenta

v1.4.0 ​

Publicada en 2026.

  • Nuevo campo opcional expiresInDays en : un entero de 1 a 60 que indica cuántos días se puede pagar el link
  • Sin expiresInDays, el link sigue venciendo 3 días después de crearse
  • expiresAt en la respuesta es la fecha de creación más expiresInDays días
  • Un valor menor que 1, mayor que 60, decimal o que no sea un número devuelve 400 con el campo en error.issues
  • Los links de colección y de pago de cliente de la API de Integración mantienen su vigencia fija de 3 días, y los links del dashboard la suya de 7 días

API keys y webhook de la cuenta ​

  • Crear la API key o el webhook de la cuenta ahora requiere un proveedor de pago activo; si no hay uno, la solicitud se rechaza con ERR_NO_ACTIVE_PAYMENT_PROVIDER (el dashboard ya deshabilitaba el botón Crear)

Correcciones de la documentación ​

Revisamos toda la documentación de Zelta Pay contra el comportamiento real del producto. Las correcciones principales:

  • Rate limiting: el límite es de 60 solicitudes por ventana fija de 60 segundos por API key, compartida por todos los endpoints /v1. RateLimit-Reset indica los segundos que faltan para reiniciar la ventana; las respuestas también traen RateLimit-Policy, y un 429 trae Retry-After. El 429 tiene cuerpo en texto plano y no tiene código de error (ERR_RATE_LIMIT_EXCEEDED nunca existió)
  • Errores de autenticación: una API key desconocida devuelve 404 con ERR_ACCOUNT_API_KEY_NOT_FOUND (no ERR_ACCOUNT_API_KEY_ALIAS_NOT_FOUND). En todos los errores con código, el texto va en message, en la raíz de la respuesta, no dentro de error
  • API keys: la API key de la cuenta se puede volver a ver en cualquier momento con Ver llave; no se muestra "una sola vez"
  • Errores de validación: los datos inválidos devuelven 400 con error.issues (un elemento por campo) y sin error.code. Los códigos ERR_VALIDATION_FAILED, ERR_INVALID_AMOUNT y ERR_METADATA_VALIDATION nunca existieron
  • Monto mínimo: un amount de 1 a 99 centavos devuelve 400 con ERR_AMOUNT_BELOW_NMI_MINIMUM en el formato de error habitual; con una API key de proyecto también se envía el webhook payment_link.rejected
  • Metadata: los valores pueden ser string (hasta 255 caracteres), number, boolean o null, no solo string; las llaves tienen de 1 a 40 caracteres y el objeto no puede estar vacío
  • requestCustomerEmail: enviar customerEmail no lo cambia a false; si lo omites, la página sigue pidiendo el email (precargado)
  • Links vencidos: el estado cambia a expired la primera vez que un listado devuelve el link, así que un link vencido puede seguir apareciendo como pending; compara expiresAt con la hora actual. No hay webhook de vencimiento
  • Listado de links: lim va de 1 a 100; la respuesta es { paymentLinks, total }, sin customerEmail, y su message es "Operation completed successfully"; el parámetro paymentProvider se acepta pero se ignora con API key
  • Respuestas: los campos opcionales se omiten cuando no tienen valor (nunca son null); los IDs son cadenas numéricas sin prefijo
  • Webhooks: cada webhook se reintenta hasta 6 veces con 15 segundos fijos entre intentos y 60 segundos de timeout; las respuestas 3xx y los 4xx distintos de 408 y 429 se descartan de inmediato; no hay reenvío manual ni selección de eventos, y la cuenta tiene un solo webhook. Zeltapay-Timestamp es el momento en que se firma cada intento. El secreto se puede ver en cualquier momento con Ver secreto, y editar la URL genera uno nuevo
  • Eventos: eventId es un UUID. Se corrigieron los payloads de ejemplo y se documentaron los casos de payment.failed, customer.created (también en links de pago de cliente), subscription.resumed (también al quitar una cancelación programada), los códigos reales de subscription.billing_blocked y el enrutamiento de receipt.created
  • API de Integración: los productCode tienen el formato prod_ + 10 caracteres; los links de colección vencen a los 3 días; GET /v1/charges devuelve los campos del registro de la transacción (paymentStatus, transactionAmount, etc.); un reintento con la misma idempotencyKey mientras el cargo se liquida devuelve 409 ERR_CHARGE_IN_PROGRESS; cambiar los items de una suscripción aplica desde el próximo cobro recurrente
  • Dashboard: los links se anulan (no se eliminan) y quedan en el historial; los links del dashboard vencen a los 7 días; se actualizaron el registro, la configuración de métodos de pago, la gestión de miembros y la página de pago

v1.3.0 ​

Publicada en 2026.

PayPal (cuenta de PayPal o tarjeta sin cuenta) ​

  • Nuevo método de pago "paypal" en el campo paymentMethods de : el cliente paga con su cuenta de PayPal o con tarjeta de débito o crédito sin cuenta de PayPal
  • Disponible solo en links de pago únicos (los de POST /v1/payment-links y los del dashboard); los links de colección y de pago de cliente siguen siendo solo tarjeta
  • Como con los demás métodos, "paypal" debe estar activo en la cuenta para el entorno del link; si no, se devuelve ERR_INACTIVE_PAYMENT_METHOD
  • Los comercios configuran el Client ID y el Client Secret de su app REST de PayPal para cada entorno en Métodos de pago. Consulta
  • Nuevo valor paypal para el parámetro paymentProvider de (el parámetro se acepta pero se ignora con API key)

Valores de los webhooks ​

  • payment.success y payment.failed pueden llevar transaction.paymentProvider: "paypal"
  • transaction.paymentMethod es "paypal" (cuenta de PayPal) o "credit_card" (tarjeta sin cuenta de PayPal)
  • Con PayPal, transaction.externalPaymentId es el ID de la captura de PayPal
  • Con PayPal, payment.failed se envía solo cuando PayPal rechaza el pago; cerrar la ventana de PayPal o abandonar el pago no envía ningún evento

eventId estable en payment.success ​

  • payment.success tiene ahora un eventId (y Zeltapay-Event-Id) estable por transacción: si Zelta Pay vuelve a enviar el payment.success de un mismo pago, llega con el mismo eventId. Úsalo para

Cancelar mientras un pago se confirma ​

  • Un link queda en processing mientras su pago se confirma; con PayPal puede durar desde minutos hasta varios días
  • devuelve 409 con ERR_PAYMENT_IN_PROGRESS mientras el link está en processing

v1.2.0 ​

Publicada en 2026.

API de Integración (proyectos) ​

Nueva familia de endpoints con alcance de proyecto (cada proyecto tiene una API key y un webhook) que permite usar Zelta Pay como motor de pagos de tu software: guarda la tarjeta del cliente una vez y luego mueve el dinero por API.

  • — modelo de proyectos, tipos de producto y flujo de captura → cargo/suscripción
  • — GET /v1/products y GET /v1/products/{productCode} (catálogo de solo lectura; se gestiona desde el dashboard)
  • — GET/POST /v1/customers, GET /v1/customers/{id} y POST /v1/customers/{id}/vault
  • — POST /v1/collections/links (captura de tarjeta) y POST /v1/collections/payment-links (cobra y captura)
  • — crear, listar, actualizar items, cambiar de cliente, cancelar, reactivar y listar facturas
  • — POST /v1/charges (cobro único a un cliente vaulteado, con proración e idempotencia), GET /v1/charges y GET /v1/charges/{id}
  • customer_collection — captura y vaultea la tarjeta sin cobrar
  • customer_payment — cobra y vaultea en el mismo checkout (requiere productCode)
  • Nuevos filtros linkType y search en

Monto máximo aumentado ​

  • El monto máximo de un link o pago sube de $2,000.00 a $10,000.00 (1000000 centavos)

Nuevos estados ​

  • Nuevo estado processing en los links de pago
  • Estados de transacción: pending, processing, paid, failed, unknown, deferred

Nuevos eventos de webhook ​

La documenta ahora los 19 tipos de evento. Se agregan, entre otros: payment.failed, payment_link.rejected, charge.succeeded, charge.failed, charge.deferred, charge.unknown, la familia subscription.*, invoice.paid, invoice.payment_failed, customer.created y receipt.created.

Idempotencia en la API ​

  • Nuevo campo idempotencyKey en POST /v1/charges: los reintentos con la misma clave nunca cobran dos veces

v1.1.0 ​

Publicada en 2026.

Selección de métodos de pago ​

Nuevo campo paymentMethods para controlar qué métodos de pago están disponibles en cada link.

  • Nuevo campo paymentMethods en
  • Valores permitidos: "yappy" y "card"
  • Sin duplicados, al menos 1 elemento cuando se especifica
  • Si no se incluye, se habilitan todos los métodos activos de la cuenta
  • Nuevo código de error ERR_INACTIVE_PAYMENT_METHOD cuando se solicita un método de pago que no está activo en la cuenta

Solicitud de email al cliente ​

Nuevo campo requestCustomerEmail para controlar si se solicita el email al cliente en la página de pago.

  • Nuevo campo requestCustomerEmail en
  • Default: true (se solicita email al cliente)
  • No puede ser true cuando se proporciona customerEmail

Parámetro de proveedor de pago ​

Nuevo parámetro de consulta paymentProvider al listar links.

  • Nuevo parámetro paymentProvider en
  • Valores permitidos: nmi, emetec, yappy
  • El parámetro se valida (un valor desconocido devuelve 400), pero no filtra las solicitudes con API key: la lista y total incluyen links de todos los proveedores

Campos actualizados en las respuestas ​

Los siguientes campos se incluyen ahora en las respuestas de los endpoints de links de pago:

  • paymentMethods — Array de métodos de pago habilitados
  • requestCustomerEmail — Si se solicita email al cliente en la página de pago

La respuesta de ahora devuelve un formato compacto con los campos esenciales: hashUrl, customerName, concept, amount, status, createdAt y cancelledAt.

Actualizaciones del payload de webhooks ​

  • Nuevo campo transaction.isTest en el payload de , indicando si la transacción es de prueba

v1.0.0 ​

Publicada en 2025.

Lanzamiento inicial ​

Primera versión de la API de Zelta Pay con todas las funcionalidades base.

Endpoints ​

  • — Listar links de pago con paginación y filtros
  • — Crear un link de pago
  • — Obtener un link de pago específico
  • — Cancelar un link de pago

Autenticación ​

  • Autenticación mediante header X-API-Key
  • Gestión de API keys desde el

Paginación ​

  • Parámetros lim y off para paginación
  • Campo total en las respuestas de listas

Validación ​

  • Montos en centavos: rango de 100 a 200000 ($1.00 a $2,000.00)
  • Campos requeridos: concept, amount, customerName, isTest
  • Metadata: máximo 20 llaves, máximo 8192 bytes
  • URL de redirección: máximo 2048 caracteres

Rate Limiting ​

  • 60 solicitudes por ventana fija de 60 segundos por API key
  • Headers de respuesta: RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

Webhooks ​

  • Notificaciones en tiempo real de eventos de pago
  • Verificación de firmas con zeltapay-signature y zeltapay-timestamp
  • Soporte para

Formato de respuesta ​

  • Respuestas JSON con campo success (boolean)
  • Timestamps en formato ISO 8601
  • Códigos de error descriptivos con prefijo ERR_

Códigos de estado HTTP ​

  • 200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 429 Too Many Requests

Problemas conocidos ​

Ninguno.

Versiones futuras ​

Los próximos cambios de la API se documentarán aquí. Los cambios que rompan compatibilidad se publicarán bajo una nueva versión de ruta (por ejemplo, /v2/payment-links). Si tienes sugerencias, escríbenos a .

Documentación oficial de Zelta