Autenticación
La API de Zelta Pay utiliza claves API (API keys) para autenticación. Genera claves desde el panel de administración y úsalas para interactuar con todos los endpoints.
URL base
https://api.zelta.dev/pay/v1Todas las peticiones a la API deben usar esta URL como base.
Entornos
Zelta Pay proporciona dos entornos separados para desarrollo y producción:
| Entorno | URL base | Descripción |
|---|---|---|
| Sandbox | https://sandbox.api.zelta.dev/pay/v1 | Pruebas sin transacciones reales ni cargos |
| Producción | https://api.zelta.dev/pay/v1 | Transacciones reales con dinero real |
WARNING
Nunca uses claves de producción en tu entorno de desarrollo. Usa siempre el entorno Sandbox para pruebas.
Obtener una clave API
- Ve a Configuración > API en el panel de Zelta Pay.
- Haz clic en Generar Clave API.
- Selecciona el entorno: Sandbox o Producción.
- Asigna un nombre descriptivo (ej:
backend-produccion,app-movil). - Selecciona los permisos (scopes) de la clave.
- Copia la clave generada inmediatamente.
WARNING
La clave API solo se muestra una vez al momento de generarla. Si la pierdes, deberás revocarla y generar una nueva.
Formato de las claves
Las claves siguen un formato con prefijo que indica el entorno:
zp_live_abc123def456 → Clave de producción
zp_test_abc123def456 → Clave de sandboxUsar la clave API
Incluye la clave en el header Authorization con el esquema Bearer en todas tus peticiones:
curl -H "Authorization: Bearer zp_live_abc123def456" \
https://api.zelta.dev/pay/v1/payment-linksEjemplo en diferentes lenguajes
JavaScript (fetch):
const response = await fetch('https://api.zelta.dev/pay/v1/payment-links', {
headers: {
'Authorization': 'Bearer zp_live_abc123def456',
'Content-Type': 'application/json'
}
});
const data = await response.json();Python (requests):
import requests
headers = {
'Authorization': 'Bearer zp_live_abc123def456',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.zelta.dev/pay/v1/payment-links',
headers=headers
)
data = response.json()cURL con POST:
curl -X POST https://api.zelta.dev/pay/v1/payment-links \
-H "Authorization: Bearer zp_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "USD",
"description": "Consultoría de marketing"
}'Permisos (Scopes)
Cada clave API puede tener permisos granulares:
| Scope | Descripción |
|---|---|
pay:links:read | Consultar links de pago |
pay:links:write | Crear y desactivar links de pago |
pay:transactions:read | Consultar transacciones y sus estados |
pay:transactions:write | Procesar reembolsos |
pay:reports:read | Consultar reportes y métricas |
pay:webhooks | Gestionar webhooks |
pay:admin | Acceso completo a todas las operaciones |
TIP
Aplica el principio de mínimo privilegio: si tu integración solo necesita crear links de pago, otórgale únicamente pay:links:write. Evita usar pay:admin en producción.
Tarjetas de prueba
Usa estas tarjetas en el entorno Sandbox para probar la integración sin procesar pagos reales:
Pagos exitosos
| Número | Red | Resultado |
|---|---|---|
4242 4242 4242 4242 | Visa | Pago aprobado |
5555 5555 5555 4444 | Mastercard | Pago aprobado |
3782 822463 10005 | Amex | Pago aprobado |
Pagos con error
| Número | Resultado |
|---|---|
4000 0000 0000 0002 | Pago declinado |
4000 0000 0000 9995 | Fondos insuficientes |
4000 0000 0000 3220 | Requiere autenticación 3D Secure |
INFO
Las tarjetas de prueba solo funcionan en el entorno Sandbox. En producción, se procesan tarjetas reales.
Límites de tasa (Rate Limiting)
La API aplica límites de tasa por clave API:
| Entorno | Límite |
|---|---|
| Sandbox | 50 peticiones/minuto |
| Producción | 500 peticiones/minuto |
Cuando superas el límite, la API responde con estado 429 Too Many Requests:
{
"error": "rate_limit_exceeded",
"message": "Has superado el límite de peticiones. Intenta de nuevo en 30 segundos.",
"retry_after": 30
}Los headers de respuesta incluyen información del límite:
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1741700430Webhooks
Recibe notificaciones en tiempo real sobre eventos de pago:
| Evento | Descripción |
|---|---|
payment.completed | Un pago fue completado exitosamente |
payment.failed | Un intento de pago falló |
payment.refunded | Un pago fue reembolsado |
link.created | Un nuevo link de pago fue creado |
link.paid | Un link de pago fue pagado |
link.expired | Un link de pago expiró sin pago |
settlement.completed | Una liquidación fue depositada en tu cuenta |
Configurar un webhook
curl -X POST https://api.zelta.dev/pay/v1/webhooks \
-H "Authorization: Bearer zp_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"url": "https://tu-servidor.com/webhooks/zelta-pay",
"events": ["payment.completed", "payment.refunded", "settlement.completed"],
"secret": "whsec_tu_secreto_de_firma"
}'Verificar firma del webhook
Cada notificación incluye un header X-Zelta-Signature con la firma HMAC-SHA256 del cuerpo:
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)WARNING
Verifica siempre la firma de los webhooks para asegurar que las notificaciones provienen de Zelta Pay y no de un tercero.