Una app móvil reintenta un POST de pago tras un timeout. ¿Cómo evitas un cobro doble?
Opciones
- Usar GET en lugar de POST para las peticiones de pago
- Enviar un header
Idempotency-Key; el servidor devuelve el primer resultado (Opción correcta) - Desactivar todos los reintentos de la app tras un timeout
- Devolver un error 500 al cliente en la segunda llamada
Respuesta
Haz que el cliente envíe un header Idempotency-Key; el servidor guarda la clave y devuelve el resultado original en las repeticiones
Por qué
El timeout pudo ocurrir DESPUÉS de que el servidor cobrara la tarjeta, así que el cliente no puede saber si el primer intento funcionó.
El cliente genera una clave única (un UUID) por intento de pago y la envía en cada reintento.
El servidor guarda la clave con el resultado. Si la misma clave llega otra vez, devuelve el resultado guardado en lugar de cobrar de nuevo. La API de Stripe funciona así.
Recuerda
Reintentos de POST → Idempotency-Key.