Idempotencia
Reintentá sin miedo: la misma key nunca cobra dos veces.
Toda operación mutante (crear un pago, crear un reembolso) requiere el header Idempotency-Key. Es lo que hace que reintentar ante un timeout o un corte de red sea seguro.
BASH
curl https://api.cauril.com/v1/payments \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: a1b2c3d4-0000-4000-8000-000000000000" \
-H "Content-Type: application/json" \
-d '{ "amount": 5000, "currency": "USD", "payment_method": { "type": "card", "token": "tok_visa" } }'Usá un valor único por operación: un UUID v4 va perfecto.
Cómo se comporta
Misma key, mismo body
Devuelve la misma respuesta del primer intento. Un solo cobro.
Misma key, body distinto
Devuelve 409 idempotency_key_reuse. No reinterpretamos la operación.
Request en vuelo
Un reintento concurrente espera al primero y replica su resultado.
409: reuso con otro body
{
"error": {
"type": "idempotency_error",
"code": "idempotency_key_reuse",
"message": "An Idempotency-Key was reused with a different request body.",
"doc_url": "https://docs.cauril.com/errors/idempotency_key_reuse"
}
}Falta la key
Una mutación sin Idempotency-Key se rechaza con 400:
400: falta la key
{
"error": {
"type": "invalid_request_error",
"code": "idempotency_key_required",
"message": "An Idempotency-Key header is required for this request.",
"doc_url": "https://docs.cauril.com/errors/idempotency_key_required"
}
}La garantía es en capas: un lock serializa reintentos concurrentes, un registro durable replica la respuesta aunque el servicio se reinicie, una constraint única en la base es la última línea de defensa, y se pasa la idempotencia nativa al PSP. Los errores transitorios (5xx, timeouts) no se cachean: podés reintentar con la misma key y la operación se reintenta de verdad.
Recomendación
Generá la key antes del primer intento y reusala en todos los reintentos de esa misma operación lógica. No generes una nueva por reintento, perderías la protección.
