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 expandaceptacustomeryproduct; cualquier otro valor (por ejemplopaymentLink) devuelve400conERR_INVALID_RELATIONS- Un
fieldscon un campo que no pertenece al objeto cargo devuelve400conERR_INVALID_FIELDS POST /v1/chargessigue aceptandoidempotencyKeyy 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 dePATCH /v1/subscriptions/{id}/itemsyPATCH /v1/subscriptions/{id}/customer, yexpand=customer - Las respuestas ya no incluyen
customerVaultId,cardBinnicardExp.paymentProvider,cardLast4ycardBrandse 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, unfieldscon un campo que no pertenece al objeto cliente devuelve400conERR_INVALID_FIELDS, yexpanddevuelve400conERR_INVALID_RELATIONS
Links de pago con API key de proyecto
- 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-linksy 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 devuelve404conERR_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
cardBinocardExpde una respuesta de la API, tómalos del webhookcustomer.created. Si adjuntas la tarjeta conPOST /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 eliddel cliente - Si usabas
expand=paymentLinkenGET /v1/charges, usa el campopaymentLinkIddel 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.
Vigencia configurable de los links de pago
- Nuevo campo opcional
expiresInDaysen : 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 expiresAten la respuesta es la fecha de creación másexpiresInDaysdías- Un valor menor que 1, mayor que 60, decimal o que no sea un número devuelve
400con el campo enerror.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-Resetindica los segundos que faltan para reiniciar la ventana; las respuestas también traenRateLimit-Policy, y un429traeRetry-After. El429tiene cuerpo en texto plano y no tiene código de error (ERR_RATE_LIMIT_EXCEEDEDnunca existió) - Errores de autenticación: una API key desconocida devuelve
404conERR_ACCOUNT_API_KEY_NOT_FOUND(noERR_ACCOUNT_API_KEY_ALIAS_NOT_FOUND). En todos los errores con código, el texto va enmessage, en la raíz de la respuesta, no dentro deerror - 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
400conerror.issues(un elemento por campo) y sinerror.code. Los códigosERR_VALIDATION_FAILED,ERR_INVALID_AMOUNTyERR_METADATA_VALIDATIONnunca existieron - Monto mínimo: un
amountde 1 a 99 centavos devuelve400conERR_AMOUNT_BELOW_NMI_MINIMUMen el formato de error habitual; con una API key de proyecto también se envía el webhookpayment_link.rejected - Metadata: los valores pueden ser
string(hasta 255 caracteres),number,booleanonull, no solostring; las llaves tienen de 1 a 40 caracteres y el objeto no puede estar vacío requestCustomerEmail: enviarcustomerEmailno lo cambia afalse; si lo omites, la página sigue pidiendo el email (precargado)- Links vencidos: el estado cambia a
expiredla primera vez que un listado devuelve el link, así que un link vencido puede seguir apareciendo comopending; comparaexpiresAtcon la hora actual. No hay webhook de vencimiento - Listado de links:
limva de 1 a 100; la respuesta es{ paymentLinks, total }, sincustomerEmail, y sumessagees"Operation completed successfully"; el parámetropaymentProviderse 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
3xxy los4xxdistintos de408y429se descartan de inmediato; no hay reenvío manual ni selección de eventos, y la cuenta tiene un solo webhook.Zeltapay-Timestampes 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:
eventIdes un UUID. Se corrigieron los payloads de ejemplo y se documentaron los casos depayment.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 desubscription.billing_blockedy el enrutamiento dereceipt.created - API de Integración: los
productCodetienen el formatoprod_+ 10 caracteres; los links de colección vencen a los 3 días;GET /v1/chargesdevuelve los campos del registro de la transacción (paymentStatus,transactionAmount, etc.); un reintento con la mismaidempotencyKeymientras el cargo se liquida devuelve409 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 campopaymentMethodsde : 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-linksy 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 devuelveERR_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
paypalpara el parámetropaymentProviderde (el parámetro se acepta pero se ignora con API key)
Valores de los webhooks
payment.successypayment.failedpueden llevartransaction.paymentProvider: "paypal"transaction.paymentMethodes"paypal"(cuenta de PayPal) o"credit_card"(tarjeta sin cuenta de PayPal)- Con PayPal,
transaction.externalPaymentIdes el ID de la captura de PayPal - Con PayPal,
payment.failedse 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.successtiene ahora uneventId(yZeltapay-Event-Id) estable por transacción: si Zelta Pay vuelve a enviar elpayment.successde un mismo pago, llega con el mismoeventId. Úsalo para
Cancelar mientras un pago se confirma
- Un link queda en
processingmientras su pago se confirma; con PayPal puede durar desde minutos hasta varios días - devuelve
409conERR_PAYMENT_IN_PROGRESSmientras el link está enprocessing
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/productsyGET /v1/products/{productCode}(catálogo de solo lectura; se gestiona desde el dashboard) - —
GET/POST /v1/customers,GET /v1/customers/{id}yPOST /v1/customers/{id}/vault - —
POST /v1/collections/links(captura de tarjeta) yPOST /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/chargesyGET /v1/charges/{id}
Nuevos tipos de link de pago
customer_collection— captura y vaultea la tarjeta sin cobrarcustomer_payment— cobra y vaultea en el mismo checkout (requiereproductCode)- Nuevos filtros
linkTypeysearchen
Monto máximo aumentado
- El monto máximo de un link o pago sube de $2,000.00 a $10,000.00 (
1000000centavos)
Nuevos estados
- Nuevo estado
processingen 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
idempotencyKeyenPOST /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
paymentMethodsen - 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_METHODcuando 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
requestCustomerEmailen - Default:
true(se solicita email al cliente) - No puede ser
truecuando se proporcionacustomerEmail
Parámetro de proveedor de pago
Nuevo parámetro de consulta paymentProvider al listar links.
- Nuevo parámetro
paymentProvideren - 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 ytotalincluyen 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 habilitadosrequestCustomerEmail— 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.isTesten 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
limyoffpara paginación - Campo
totalen 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-signatureyzeltapay-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
200OK,201Created,400Bad Request,401Unauthorized,403Forbidden,404Not Found,409Conflict,429Too 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 .