Skip to content

Autenticación

La API de Zelta Pay utiliza claves API (API keys) para autenticar todas las solicitudes. Cada solicitud debe incluir tu clave en el header X-API-Key.

Autenticación con API Key

Cómo funciona

Todas las solicitudes a la API deben incluir el header X-API-Key con tu clave:

http
X-API-Key: tu-api-key-aqui

La API valida la clave en cada solicitud. Si la clave es inválida o no se incluye, la solicitud será rechazada con un error de autenticación.

Obtener tu API Key

  1. Inicia sesión en tu
  2. Navega a API Keys
  3. Ingresa un alias descriptivo y haz clic en + Crear
  4. Copia la clave generada y guárdala de forma segura

La API key solo se muestra una vez

La API key solo se muestra una vez al momento de generarla. Si la pierdes, deberás revocarla y crear una nueva.

Rate Limiting

La API aplica un límite de 60 solicitudes por minuto por API key, usando una ventana deslizante de 1 minuto.

Headers de rate limit

Cada respuesta incluye headers con información del estado de tu límite:

HeaderDescripción
RateLimit-LimitNúmero máximo de solicitudes permitidas por ventana (60)
RateLimit-RemainingSolicitudes restantes en la ventana actual
RateLimit-ResetSegundos hasta que se reinicie la ventana

Manejo de rate limits

Cuando superas el límite, la API responde con estado 429 Too Many Requests:

json
{
  "success": false,
  "error": {
    "code": "ERR_RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded"
  },
  "timestamp": "2026-03-13T10:30:00.000Z"
}

Implementa reintentos con backoff exponencial

Implementa backoff exponencial cuando recibas un 429. Usa el header RateLimit-Reset para saber cuánto tiempo esperar antes de reintentar.

Manejo de errores

Errores comunes de autenticación

Código de errorHTTP StatusDescripción
ERR_MISSING_API_KEY401No se incluyó el header X-API-Key en la solicitud
ERR_API_KEY_NOT_FOUND404La API key proporcionada no existe o fue revocada
ERR_ACCOUNT_SUSPENDED403La cuenta asociada a la API key está suspendida
ERR_RATE_LIMIT_EXCEEDED429Se superó el límite de solicitudes por minuto

Formato de respuesta de error

json
{
  "success": false,
  "error": {
    "code": "ERR_MISSING_API_KEY",
    "message": "API key is required"
  },
  "timestamp": "2026-03-13T10:30:00.000Z"
}

Ejemplos de implementación

:: tab Node.js

javascript
const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', {
  method: 'GET',
  headers: {
    'X-API-Key': process.env.ZELTA_API_KEY,
    'Content-Type': 'application/json'
  }
});

const data = await response.json();

if (!data.success) {
  console.error('Error:', data.error.code, data.error.message);
}

::

:: tab Cloudflare Workers

javascript
export default {
  async fetch(request, env, ctx) {
    const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', {
      method: 'GET',
      headers: {
        'X-API-Key': env.ZELTA_API_KEY,
        'Content-Type': 'application/json'
      }
    });

    const data = await response.json();
    return new Response(JSON.stringify(data), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
};

::

:: tab Hono

typescript
import { Hono } from 'hono';

type Bindings = {
  ZELTA_API_KEY: string;
};

const app = new Hono<{ Bindings: Bindings }>();

app.get('/payment-links', async (c) => {
  const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', {
    method: 'GET',
    headers: {
      'X-API-Key': c.env.ZELTA_API_KEY,
      'Content-Type': 'application/json'
    }
  });

  const data = await response.json();
  return c.json(data);
});

export default app;

::

:: tab Python

python
import os
import requests

api_key = os.environ.get('ZELTA_API_KEY')

response = requests.get(
    'https://api-pay.zelta.dev/v1/payment-links',
    headers={
        'X-API-Key': api_key,
        'Content-Type': 'application/json'
    }
)

data = response.json()

if not data.get('success'):
    print(f"Error: {data['error']['code']} - {data['error']['message']}")

::

:: tab PHP

php
<?php

$apiKey = getenv('ZELTA_API_KEY');

$ch = curl_init('https://api-pay.zelta.dev/v1/payment-links');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: ' . $apiKey,
        'Content-Type: application/json'
    ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

if (!$data['success']) {
    echo "Error: {$data['error']['code']} - {$data['error']['message']}";
}

::

Buenas prácticas de seguridad

Variables de entorno

Nunca incluyas API keys directamente en tu código fuente. Usa variables de entorno:

bash
# .env (nunca subir al control de versiones)
ZELTA_API_KEY=tu-api-key-aqui

No subas API keys al control de versiones

Nunca guardes API keys en el control de versiones. Agrega .env a tu archivo .gitignore.

Rotación de claves

  • Rota tus API keys periódicamente
  • Revoca inmediatamente cualquier clave comprometida desde el
  • Usa nombres descriptivos para identificar fácilmente qué clave usa cada servicio

Control de acceso

  • Genera claves diferentes para cada servicio o aplicación
  • Limita el acceso a las API keys solo al personal necesario
  • Almacena las claves en un gestor de secretos en producción

Manejo de errores

  • Nunca expongas tu API key en mensajes de error del lado del cliente
  • Registra los errores de autenticación para detectar intentos de acceso no autorizado
  • Implementa alertas para errores 403 recurrentes

Probar la autenticación

Verifica que tu API key funcione correctamente con esta solicitud:

bash
curl -X GET "https://api-pay.zelta.dev/v1/payment-links?lim=1" \
  -H "X-API-Key: tu-api-key-aqui" \
  -H "Content-Type: application/json"

Una respuesta exitosa confirma que tu clave es válida:

json
{
  "success": true,
  "data": {
    "paymentLinks": [],
    "total": 0
  },
  "message": "Payment links retrieved successfully",
  "timestamp": "2026-03-13T10:30:00.000Z"
}

Solución de problemas

Error 401 — API key faltante o inválida

  • Verifica que estés usando el header X-API-Key (no Authorization)
  • Confirma que la clave no tenga espacios en blanco adicionales
  • Asegúrate de que la clave esté activa en tu

Error 403 — Cuenta suspendida

  • Tu cuenta puede estar suspendida por actividad inusual
  • Contacta a soporte para resolver el problema

Error 429 — Rate limit excedido

  • Estás enviando más de 60 solicitudes por minuto
  • Implementa backoff exponencial en tus reintentos
  • Revisa el header RateLimit-Reset para saber cuándo puedes reintentar
  • Si necesitas mayor capacidad, contacta a soporte

Siguientes pasos

  • — Documentación completa de endpoints y formatos
  • — Crea tu primer link de pago
  • — Guía paso a paso para empezar

Documentación oficial de Zelta