Manejo de Errores

Aprende a manejar los errores de la API de forma efectiva y proporcionar una buena experiencia a tus usuarios.

Formato de errores

Cuando ocurre un error, la API retorna una respuesta JSON con la siguiente estructura:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Descripción legible del error",
    "details": {}
  }
}
Campo Tipo Descripción
success boolean Siempre false en errores
error.code string Código de error único para identificar el tipo de error
error.message string Mensaje descriptivo del error
error.details object Información adicional específica del error (opcional)

Códigos HTTP

La API usa códigos de estado HTTP estándar:

Código Significado Cuándo ocurre
200 OK Solicitud exitosa (GET)
201 Created Recurso creado exitosamente (POST)
400 Bad Request Parámetros inválidos o faltantes
401 Unauthorized Credenciales inválidas o faltantes
404 Not Found Orden no encontrada
429 Too Many Requests Límite de solicitudes excedido
500 Internal Server Error Error interno del servidor

Errores de Autenticación (401)

Código Descripción Solución
MISSING_CREDENTIALS Faltan los headers X-Api-Key o X-Api-Secret Incluye ambos headers en la solicitud
INVALID_CREDENTIALS API Key o Secret inválidos Verifica que las credenciales sean correctas
MERCHANT_NOT_ACTIVE La cuenta del merchant no está activa Contacta a soporte para verificar el estado de tu cuenta

Ejemplo

{
  "success": false,
  "error": {
    "code": "INVALID_CREDENTIALS",
    "message": "Invalid API credentials",
    "details": {}
  }
}

Errores de Validación (400)

Código Descripción Solución
INVALID_AMOUNT El monto es inválido o menor al mínimo El monto debe ser un número mayor o igual a 1,000 COP
INVALID_REFERENCE La referencia es inválida o muy larga Usa una referencia string de máximo 100 caracteres
INVALID_EMAIL El email del cliente no es válido Verifica el formato del email
INVALID_DOC_TYPE Tipo de documento no válido Usa: CC, CE, NIT, o PP
MISSING_REQUIRED_FIELD Falta un campo requerido Revisa que incluyas todos los campos requeridos
NO_VALID_PAYMENT_METHODS No hay métodos de pago válidos Verifica que tu cuenta tenga métodos de pago habilitados

Ejemplo

{
  "success": false,
  "error": {
    "code": "INVALID_AMOUNT",
    "message": "Amount must be at least 1000 COP",
    "details": {
      "field": "amount",
      "value": 500,
      "minimum": 1000
    }
  }
}

Errores de Orden (400, 404)

Código HTTP Descripción
ORDER_NOT_FOUND 404 La orden no existe o no pertenece a tu cuenta
ORDER_EXPIRED 400 La orden ya expiró
INVALID_ORDER_STATUS 400 La orden no está en un estado válido para esta operación

Ejemplo

{
  "success": false,
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "Collect order not found",
    "details": {}
  }
}

Errores de Rate Limit (429)

Si excedes el límite de solicitudes, recibirás este error:

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests. Please try again later.",
    "details": {
      "retryAfter": 60
    }
  }
}

Los headers de respuesta incluyen información sobre el límite:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705323600

Manejo de Errores en tu Código

Recomendamos implementar un manejo de errores robusto:

async function createCollectOrder(orderData) {
  try {
    const response = await fetch('https://api.prod.niiopay.com/api/v1/collect', {
      method: 'POST',
      headers: {
        'X-Api-Key': process.env.NIIO_API_KEY,
        'X-Api-Secret': process.env.NIIO_API_SECRET,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(orderData),
    });

    const data = await response.json();

    if (!data.success) {
      // Manejar error según el código
      switch (data.error.code) {
        case 'INVALID_CREDENTIALS':
          console.error('Error de autenticación');
          throw new Error('Error de configuración');

        case 'RATE_LIMIT_EXCEEDED':
          // Esperar y reintentar
          const retryAfter = data.error.details?.retryAfter || 60;
          await new Promise(r => setTimeout(r, retryAfter * 1000));
          return createCollectOrder(orderData);

        default:
          throw new Error(data.error.message);
      }
    }

    return data.data;
  } catch (error) {
    console.error('Error al crear orden:', error);
    throw error;
  }
}
import requests
import time
import os

def create_collect_order(order_data):
    try:
        response = requests.post(
            'https://api.prod.niiopay.com/api/v1/collect',
            headers={
                'X-Api-Key': os.environ['NIIO_API_KEY'],
                'X-Api-Secret': os.environ['NIIO_API_SECRET'],
                'Content-Type': 'application/json',
            },
            json=order_data,
            timeout=30
        )

        data = response.json()

        if not data.get('success'):
            error_code = data.get('error', {}).get('code')

            if error_code == 'INVALID_CREDENTIALS':
                raise Exception('Error de configuración')

            elif error_code == 'RATE_LIMIT_EXCEEDED':
                retry_after = data['error'].get('details', {}).get('retryAfter', 60)
                time.sleep(retry_after)
                return create_collect_order(order_data)

            else:
                raise Exception(data['error']['message'])

        return data['data']

    except requests.exceptions.RequestException as e:
        print(f'Error de conexión: {e}')
        raise

Mensajes para el Usuario

Muestra mensajes amigables a tus usuarios según el tipo de error:

Tipo de Error Mensaje Sugerido
Validación (400) "Por favor verifica los datos ingresados"
No encontrado (404) "La orden de pago no existe o ya expiró"
Rate limit (429) "Demasiados intentos. Espera un momento"
Error servidor (500) "Error temporal. Intenta de nuevo en unos minutos"
No expongas detalles técnicos
Nunca muestres códigos de error o detalles técnicos a los usuarios finales. Loguéalos internamente para debugging.