Introducción
La idempotencia garantiza que múltiples solicitudes idénticas produzcan el mismo resultado. Esto es especialmente crítico en los flujos de pago, donde errores de red o timeouts pueden causar reintentos involuntarios que, sin idempotencia, podrían resultar en cobros duplicados o procesamiento múltiple de transacciones.
Las APIs de Akua implementan idempotencia para:
- Prevenir duplicación: Evitar el procesamiento múltiple de la misma operación
- Garantizar confiabilidad: Permitir reintentos seguros en caso de fallos de red
- Simplificar la gestión de errores: Facilitar el manejo de timeouts y errores de conectividad
- Proteger las transacciones: Asegurar la integridad de los flujos de pago
Cómo funciona la idempotencia
La idempotencia se implementa a través de una clave única que identificas en cada solicitud. Cuando envías una solicitud con una clave de idempotencia:
- Primera solicitud: Akua procesa la solicitud y almacena la respuesta asociada a la clave
- Solicitudes posteriores: Si se recibe la misma clave dentro de las 24 horas, Akua devuelve la respuesta almacenada sin reprocesar la operación
- Protección contra cambios: Si intentas usar la misma clave con un cuerpo de solicitud diferente, recibirás un error
Implementación
Header requerido
Para hacer una solicitud idempotente, incluye el siguiente header en tu petición:
Idempotency-Key: <tu-clave-única>
Nota: Este header es opcional. Si no lo incluyes, la solicitud se procesará normalmente sin garantías de idempotencia.
Ejemplo de implementación
curl --request POST \
--url https://api.akua.la/v1/authorizations \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
--data '
{
"intent": "authorization",
"trace_id": "any-format-34324366",
"merchant_id": "mer-csuvatde7f1jb0qgqjvg"
}'
Generación de claves
Las claves de idempotencia deben ser strings únicos. Recomendamos usar UUIDs o cualquier otro identificador que asegure unicidad:
// Ejemplo con UUID v4
const { v4: uuidv4 } = require('uuid');
const idempotencyKey = uuidv4();
// Ejemplo con timestamp + random
const idempotencyKey = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
Configuración del sistema
Tiempos de retención
Parámetro | Duración | Descripción |
---|---|---|
Expiración | 20 segundos | Tiempo durante el cual se bloquean solicitudes concurrentes con la misma clave |
Expiración de la respuesta | 24 horas | Tiempo durante el cual se almacena la respuesta para su reutilización |
Comportamiento temporal
- Durante los primeros 20 segundos: Si se recibe una solicitud con la misma clave mientras se procesa la primera, se rechazará con un error de conflicto
- Después de procesada (hasta 24 horas): Cualquier solicitud con la misma clave devolverá la respuesta original almacenada
- Después de 24 horas: La clave expira y puede ser reutilizada para una nueva operación
Manejo de errores
Errores específicos de idempotencia
Error | Código HTTP | Código de error | Descripción |
---|---|---|---|
Clave inválida | 400 | invalid_idempotency_key | La longitud o formato de la clave de idempotencia es inválida |
Cuerpo diferente | 409 | idempotency_key_mismatch | Se intentó usar la misma clave con un cuerpo de solicitud diferente |
Solicitud concurrente | 409 | idempotency_conflict | Existe una solicitud en proceso con la misma clave |
Mejores prácticas
1. Generar claves de idempotencia únicas
Utiliza UUIDs o mecanismos similares que garanticen unicidad global. Evita usar valores predecibles o secuenciales.
// ✅ Buena práctica
const idempotencyKey = crypto.randomUUID();
// ❌ Evitar
const idempotencyKey = "payment-123";
2. Reutilizar claves de idempotencia para reintentos
Cuando reintentes una solicitud fallida, usa siempre la misma clave de idempotencia.
const makePayment = async (data, idempotencyKey, retries = 3) => {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch('https://api.akua.la/v1/authorizations', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_live_...',
'Content-Type': 'application/json',
'Idempotency-Key': idempotencyKey // Misma clave en cada reintento
},
body: JSON.stringify(data)
});
if (response.ok) return response.json();
} catch (error) {
if (i === retries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
};
3. Mantener las claves consistentes
Asegura que la misma operación lógica siempre use la misma clave, incluso si la solicitud se origina desde diferentes partes de tu sistema.
// Asocia la clave con la operación desde el inicio
const processOrder = async (orderId) => {
const idempotencyKey = `order-${orderId}-payment`;
// Guarda la clave en tu base de datos junto con el pedido
await saveIdempotencyKey(orderId, idempotencyKey);
// Usa la clave guardada para cualquier intento de pago
return makePayment(orderData, idempotencyKey);
};
4. Mantener la consistencia clave-request
Nunca reutilices claves de idempotencia para diferentes bodies de requests. Cada combinación única de parámetros debe tener su propia clave.
// ❌ Incorrecto: reutilizar la misma clave para diferentes montos
const key = "user-123-payment";
await makePayment({ amount: 1000 }, key);
await makePayment({ amount: 2000 }, key); // Error: idempotency_key_mismatch
// ✅ Correcto: claves únicas para cada operación
await makePayment({ amount: 1000 }, "payment-abc123");
await makePayment({ amount: 2000 }, "payment-def456");
Endpoints compatibles
La idempotencia está disponible exclusivamente para los endpoints de Core Flow de Akua, que incluyen:
- Creación de pagos
- Procesamiento de reembolsos
- Confirmación de transacciones
- Cancelación de operaciones
Para verificar si un endpoint específico soporta idempotencia, consulta su documentación individual en el API Reference.
Preguntas frecuentes
¿Qué sucede si no incluyo una clave de idempotencia?
La solicitud se procesará normalmente, pero sin protección contra duplicados. Esto es aceptable para operaciones de lectura o consulta, pero no recomendado para operaciones que modifican estado.
¿Puedo reutilizar una clave después de 24 horas?
Sí, después de 24 horas la clave expira y puede ser utilizada nuevamente. Sin embargo, recomendamos generar siempre claves nuevas y únicas.
¿Qué longitud debe tener mi clave de idempotencia?
Recomendamos claves entre 16 y 64 caracteres. Las claves fuera de este rango serán rechazadas con un error invalid_idempotency_key
.
¿La idempotencia funciona entre ambientes?
No, las claves de idempotencia son específicas por ambiente. Una clave usada en sandbox no tiene efecto en producción y viceversa.