Las API distribuidas fallan de formas incómodas. La conexión puede cortarse después de que el servidor procese la solicitud. Un gateway puede devolver un timeout mientras el proveedor sigue trabajando. El cliente puede repetir la llamada porque no ha recibido respuesta. Una cola puede reenviar el mismo mensaje. Un usuario puede pulsar dos veces el botón de pagar.
En operaciones habituales, repetir puede generar solo trabajo duplicado. En pagos, puede generar dos efectos financieros.
La idempotencia permite presentar la misma intención más de una vez sin producir un nuevo efecto con cada repetición. Es una de las herramientas más importantes para construir API financieras resilientes, pero también una de las peor comprendidas.
¿Qué significa que una operación sea idempotente?
Una operación idempotente puede repetirse sin alterar el resultado más allá del efecto de la primera ejecución válida.
Si la intención es crear un cobro de R$ 100, repetir la misma solicitud con la misma identidad no debería crear dos cobros independientes.
La repetición debe reconocerse como la misma operación lógica.
¿Idempotencia significa que la API siempre responde igual?
No necesariamente en todos los detalles, pero el efecto de negocio debe seguir siendo único.
Algunos proveedores almacenan la respuesta original y la devuelven de nuevo. Otros devuelven el recurso creado. Otros solo garantizan que no se produzca un segundo efecto.
El contrato exacto debe consultarse en la documentación de la API.
¿Qué es una clave de idempotencia?
Es un identificador proporcionado por el cliente para representar una intención específica.
La primera vez que el servidor recibe la clave, ejecuta la operación y asocia el resultado con ella. En una repetición, reconoce que esa intención ya se ha procesado y evita ejecutarla de nuevo.
La clave no debería representar «este usuario». Debería representar «esta operación lógica».
¿Quién debe generar la clave?
Normalmente, el sistema que conoce la intención de negocio.
Si el backend crea un intento de pago, puede generar una clave única para ese intento antes de llamar al PSP.
Lo importante es que la misma intención reutilice la misma clave y una nueva intención utilice otra.
¿Puedo utilizar order_id como clave de idempotencia?
Depende.
Si un pedido solo puede tener una operación de ese tipo, quizá funcione.
Pero un pedido puede tener varios intentos, capturas, reembolsos o cambios. En ese caso, utilizar solo order_id puede bloquear operaciones legítimas diferentes.
La clave debe incorporar la granularidad correcta del comando.
¿Es suficiente un UUID aleatorio?
Resuelve el riesgo de colisión, pero no la semántica.
Si el sistema genera un UUID nuevo en cada reintento, pierde el beneficio de la idempotencia.
La clave debe persistirse junto con la intención antes de la primera llamada para poder reutilizarla.
¿Cuándo debo crear la clave?
Antes de realizar la operación externa.
Si la clave solo se persiste después de que responda el PSP, una caída intermedia puede impedir que la aplicación sepa qué clave se utilizó.
Persistir primero la intención y la clave facilita la recuperación.
¿La idempotencia es lo mismo que la deduplicación?
Son conceptos relacionados, pero no idénticos.
La deduplicación identifica eventos repetidos y evita procesarlos más de una vez.
La idempotencia garantiza que repetir una operación no produzca efectos adicionales.
Un sistema puede deduplicar por event_id y seguir necesitando idempotencia para las llamadas externas.
¿Y la entrega exactamente una vez?
En la práctica, los sistemas distribuidos rara vez pueden depender de una entrega física exactamente una vez de extremo a extremo.
Las colas y las redes suelen favorecer la entrega al menos una vez con reintentos.
Por eso son tan importantes los consumidores idempotentes.
El objetivo es obtener el efecto de negocio exactamente una vez aunque el mensaje llegue varias veces.
¿HTTP GET ya es idempotente?
Según la semántica de HTTP, GET debería ser una operación de lectura sin un efecto de negocio significativo.
Pero una API mal diseñada puede incumplirlo.
La idempotencia en pagos es más relevante en comandos como creación, captura, cancelación y reembolso.
¿PUT es idempotente?
La semántica HTTP de PUT es idempotente cuando sustituye o establece el estado de un recurso conocido.
Aun así, el comportamiento real depende de la implementación.
No debe suponerse la seguridad financiera únicamente por el verbo HTTP.
¿Puede POST ser idempotente?
Sí.
Muchas API de pagos utilizan POST con una clave de idempotencia para que la creación y los comandos puedan repetirse de forma segura.
El verbo por sí solo no define la garantía.
¿Debe el servidor comparar los parámetros?
Idealmente, sí.
Si aparece la misma clave con un importe o payload diferente, probablemente hay un error del cliente.
Algunas API rechazan la reutilización de la clave cuando los parámetros no coinciden con los de la primera solicitud.
Esto evita utilizar una clave como identificador genérico para intenciones distintas.
¿Durante cuánto tiempo debe recordarse la clave?
Depende del contrato del proveedor y de tu sistema.
Algunos servicios conservan el resultado durante un periodo definido. Después, reutilizar la clave puede tratarse como una nueva operación.
La aplicación debe conocer ese plazo y no depender de una garantía permanente si no existe.
¿Debe durar más la idempotencia local que la del PSP?
Puede ser una buena estrategia.
Aunque el proveedor olvide una clave después de cierto tiempo, tu sistema puede mantener la intención y bloquear reintentos tardíos que resultarían peligrosos.
La regla interna no tiene por qué limitarse a la conservación externa.
¿Qué ocurre ante un timeout?
El timeout es el caso clásico.
La aplicación ha enviado la solicitud, pero no sabe si el PSP la ha procesado. En lugar de generar una clave nueva, debe repetir la misma intención con la misma clave cuando el contrato lo permita.
Así, si la primera llamada ya tuvo efecto, el servidor reconoce la repetición.
¿La idempotencia elimina los resultados desconocidos?
No siempre.
Reduce el riesgo de duplicación, pero la aplicación puede seguir necesitando consultar el recurso para conocer el resultado definitivo.
Una clave de idempotencia es un mecanismo para repetir con seguridad, no un sustituto de la máquina de estados.
¿La idempotencia impide el doble cobro entre PSP diferentes?
No automáticamente.
La clave de un PSP normalmente no tiene significado para otro.
Si sufres un timeout en el PSP A y envías un nuevo intento al PSP B, puedes crear dos efectos.
La plataforma debe controlarlo a nivel de pago e intento.
¿Cómo modelar la idempotencia en multi-PSP?
Utiliza una identidad interna para la intención y una identidad externa por intento.
El payment puede representar la compra. La attempt representa una llamada a un PSP. Cada comando de la attempt tiene su clave de idempotencia en el proveedor correspondiente.
La máquina de estados decide cuándo puede crearse una nueva attempt.
¿Sirve la misma clave para autorización y captura?
Generalmente, no.
Son comandos diferentes y pueden tener payloads, endpoints y efectos distintos.
Cada intención financiera debería tener su propia identidad.
¿Y para un reembolso parcial?
Cada reembolso debería tener identidad propia.
Si una compra recibe dos devoluciones legítimas de R$ 50 en momentos diferentes, no pueden compartir la misma clave de idempotencia.
Pero un reintento del primer reembolso debe reutilizar la clave de ese reembolso concreto.
¿Cómo evitar el doble clic en el frontend?
Deshabilitar el botón ayuda a la UX, pero no es una garantía.
El usuario puede abrir dos pestañas, la red puede repetir solicitudes o un atacante puede llamar directamente a la API.
La protección real debe estar en el backend.
¿Puedo generar la clave en el navegador?
Sí, siempre que el backend la valide y la asocie correctamente con la sesión o la intención.
Muchas arquitecturas prefieren generar o confirmar la clave en el servidor para controlar el alcance.
Lo importante es no confiar únicamente en el comportamiento de la interfaz.
¿Cómo persistir una intención idempotente?
Crea un registro con la clave, el tipo de operación, el payload relevante, el estado, el resultado y las marcas temporales.
Al recibir la misma clave, la aplicación consulta ese registro.
Si la operación ha terminado, devuelve el resultado correspondiente. Si se está procesando, puede esperar o devolver un estado intermedio.
¿Qué hacer si llegan simultáneamente dos solicitudes con la misma clave?
Esta es una prueba importante.
El sistema debe garantizar la exclusión mutua o una restricción única para que solo una ejecución gane.
Sin control de concurrencia, dos hilos pueden comprobar «no existe» al mismo tiempo y ejecutar dos cobros.
¿Una restricción única lo resuelve?
Ayuda mucho.
Una restricción única en la base de datos sobre el alcance de la clave evita dos filas para la misma intención.
Pero sigue siendo necesario coordinar cuándo se realiza la llamada externa y cómo recuperarse de una caída.
¿Cuál es el problema de check-then-act?
Es el patrón «comprueba si existe; si no, créalo».
Con concurrencia, dos procesos pueden superar la comprobación antes de que uno cree el registro.
La decisión debe ser atómica o estar protegida por una restricción o un bloqueo.
¿Cómo ayuda el patrón outbox?
La aplicación puede persistir el cambio de estado y un mensaje de salida en la misma transacción.
Después, un worker entrega el mensaje al PSP o a otro servicio.
Así se evita que la base de datos confirme la intención, pero el proceso termine antes de publicar el comando.
¿Y el patrón inbox?
Los consumidores almacenan los identificadores de los mensajes procesados para deduplicar las entregas.
Esto resulta útil en webhooks y colas.
Outbox e inbox resuelven partes diferentes del flujo y se complementan bien con la idempotencia de la API.
¿La idempotencia debe devolver un error o el resultado anterior?
Depende del contrato.
Cuando la repetición tiene exactamente la misma intención, resulta conveniente devolver el resultado anterior.
Cuando la misma clave llega con parámetros diferentes, es más seguro rechazarla.
¿Debo almacenar la respuesta completa?
Puede ser útil, pero hay que considerar el tamaño, los datos sensibles y la evolución del esquema.
Otra opción es almacenar una referencia al recurso creado y reconstruir la respuesta actual.
La elección depende del contrato que quieras ofrecer.
¿Puedo almacenar un error como resultado idempotente?
Algunos proveedores lo hacen para errores producidos después del inicio de la ejecución.
La lógica tiene sentido: si la operación realmente comenzó y terminó con un error específico, repetirla no debería crear silenciosamente una nueva ejecución.
Pero los errores de validación previos a la ejecución pueden tratarse de otra forma.
¿Cómo distinguir errores reintentables de los que no lo son?
La clasificación debe considerar la semántica.
Los timeouts y los errores 5xx pueden admitir reintentos cuando la operación es idempotente. Un error de validación normalmente exige corregir el payload. Un rechazo de tarjeta no debería repetirse a ciegas.
El estado HTTP es solo una parte de la decisión.
¿Debe reintentarse una respuesta 500?
No automáticamente.
Primero, comprueba el contrato del PSP, la idempotencia y si hay un resultado desconocido.
Algunos proveedores almacenan el resultado idempotente incluso cuando es un 500.
La aplicación debe seguir la documentación específica.
¿Y 429?
El límite de peticiones normalmente requiere reintentar con backoff.
Pero el comando debe seguir siendo idempotente.
Si el proveedor lo rechazó antes de procesarlo, repetir puede ser seguro; si el comportamiento no está claro, utiliza la garantía documentada.
¿Qué es el backoff exponencial?
Consiste en aumentar progresivamente el intervalo entre reintentos.
Reduce la presión durante los incidentes.
El jitter añade variación para evitar que miles de clientes repitan al mismo tiempo.
¿El backoff sustituye a la idempotencia?
No.
Solo espacia las repeticiones.
Si cada repetición crea un nuevo efecto, tendrás duplicados más despacio.
¿Es necesaria la idempotencia en los webhooks?
El consumidor debe ser idempotente.
El mismo webhook puede llegar varias veces.
Procesar de nuevo el mismo event_id no debe duplicar cambios de estado, saldo ni entrega de pedidos.
¿Cómo deduplicar los webhooks?
Almacena el identificador único del evento o una clave derivada fiable y utiliza una restricción única.
Después, procesa la transición de forma segura.
Si el proveedor no proporciona event_id, puede ser necesario utilizar identificadores del objeto y su versión o estado, con cuidado.
¿El orden de los eventos y la idempotencia son el mismo problema?
No.
La idempotencia evita duplicados. La ordenación evita regresiones de estado.
Un evento antiguo puede ser único y, aun así, llegar después de uno nuevo.
La máquina de estados debe validar las transiciones.
¿Cómo se relaciona la idempotencia con el ledger?
Cada evento financiero debe generar un journal una sola vez.
Si el webhook de captura llega dos veces, la restricción del ledger impide dos créditos.
La clave de origen del apunte es una forma de idempotencia.
¿Cómo se relaciona la idempotencia con la conciliación?
La conciliación detecta cuándo ha fallado la protección o cuándo los eventos externos no coinciden con lo esperado.
Incluso con idempotencia, pueden producirse errores.
La conciliación es la segunda línea de defensa.
¿Qué es la idempotencia por recurso?
En lugar de una clave arbitraria, la operación utiliza un recurso conocido.
Por ejemplo, «establecer el estado del cobro X como cancelado» puede ser naturalmente repetible si el resultado final es el mismo.
Pero los comandos financieros que crean objetos nuevos suelen necesitar una clave explícita.
¿Cómo elegir el alcance de la clave?
La clave puede ser global, por comercio, por endpoint o por recurso.
El alcance debe evitar colisiones entre operaciones legítimas.
Una clave «123» utilizada por dos comercios diferentes puede permitirse si el alcance incluye merchant_id.
¿Qué es una colisión de claves de idempotencia?
Ocurre cuando dos intenciones distintas reciben la misma clave.
Si el servidor no compara los parámetros, una operación puede recibir el resultado de otra.
Los generadores aleatorios de alta entropía reducen el riesgo accidental, pero la aplicación también debe controlar la reutilización lógica.
¿Cómo auditar los reintentos?
Registra attempt_id, la clave de idempotencia, el número de intento HTTP, las marcas temporales, el resultado y el identificador de solicitud del proveedor cuando esté disponible.
Esto permite saber cuántas llamadas se realizaron sin confundirlas con el número de efectos financieros producidos.
¿Debe soporte ver el número de reintentos?
Puede resultar útil para investigar incidentes.
Soporte no necesita ver detalles del protocolo, pero saber que hubo un timeout y una recuperación idempotente ayuda a explicar retrasos sin indicar al cliente que pague de nuevo.
¿Cómo probar la idempotencia?
Envía la misma solicitud simultáneamente varias veces.
Fuerza una caída después de persistir la intención y antes de la llamada externa. Fuerza un timeout después de que el PSP procese la operación. Reenvía un webhook. Reprocesa una cola.
El sistema debe converger hacia un único efecto.
¿Cómo probar un cambio de payload?
Utiliza la misma clave con un importe diferente y comprueba si la API lo rechaza.
Este caso detecta errores de clientes que reutilizan claves incorrectamente.
¿Cómo probar la caducidad de la clave?
Simula una repetición después del periodo documentado por el proveedor.
La aplicación interna debe decidir si sigue bloqueando la operación o crea una nueva intención explícita.
¿Debe ser visible la idempotencia en la API pública?
Sí, cuando los clientes externos ejecutan operaciones con efectos.
Una API de pagos debería ofrecer un mecanismo claro para realizar reintentos seguros.
Ocultar la idempotencia únicamente en el SDK no resuelve las integraciones directas.
¿Cabecera o campo en el cuerpo?
Ambos pueden funcionar.
Las cabeceras son habituales porque la clave pertenece a la semántica de la solicitud, no al recurso de negocio.
Lo más importante es la coherencia del contrato.
¿Cómo documentar la idempotencia?
Explica qué endpoints la admiten, el alcance de la clave, el tiempo de conservación, el comportamiento con un payload diferente, la concurrencia y los tipos de error.
Una documentación vaga lleva a los clientes a formular suposiciones peligrosas.
¿La idempotencia garantiza exactamente un cobro?
Garantiza la repetición segura dentro del alcance en el que está implementada.
Si la aplicación crea dos intenciones con claves distintas, habrá dos cobros legítimos desde el punto de vista técnico.
Por eso, también es necesario controlar la identidad de negocio.
¿Cuál es la diferencia entre payment_id e idempotency_key?
Payment_id identifica un objeto.
La clave de idempotencia identifica una intención de comando.
Un mismo payment puede recibir varios comandos idempotentes a lo largo de su ciclo de vida.
¿Puedo reutilizar una clave en otro endpoint?
Normalmente, no es una buena idea.
Los alcances varían según el proveedor y reutilizarla puede causar conflictos.
La clave debe representar una operación específica.
¿Cómo ayuda la idempotencia a los agentes de IA?
Los agentes pueden replantear y repetir acciones ante un fallo.
Sin idempotencia, una automatización puede ejecutar el mismo pago más de una vez porque no ha recibido confirmación.
Cualquier capa autónoma que dé órdenes sobre dinero necesita operaciones repetibles de forma segura.
¿Cómo ayuda la idempotencia a las automatizaciones tradicionales?
Los planificadores, las colas y las tareas también repiten.
La regla es la misma: la infraestructura debe asumir que los mensajes pueden llegar más de una vez.
¿Qué ocurre si la base de datos falla después de responder el PSP?
Es un escenario difícil.
El PSP ha creado el efecto, pero la aplicación no ha podido persistir el resultado.
Si la clave de idempotencia se persistió antes, la recuperación puede repetir la llamada y obtener el mismo efecto o recurso en lugar de crear otro.
¿Y si la clave no se persistió?
La aplicación puede perder la capacidad de reconocer la operación.
Por eso, generar y guardar la clave antes de la llamada externa es una práctica sólida.
¿Cómo conciliar operaciones idempotentes?
Incluso con la garantía, mantén rutinas de consulta y conciliación.
Confirman que el recurso externo corresponde al registro interno.
La defensa en profundidad importa cuando hay dinero de por medio.
¿Qué no resuelve la idempotencia?
No resuelve el fraude, el orden de los eventos, las transiciones inválidas, los importes erróneos, el enrutamiento incorrecto ni la falta de disponibilidad.
Resuelve un problema específico: repetir la misma intención sin duplicar su efecto.
¿Cuál es la diferencia entre un reintento seguro y un nuevo intento?
Un reintento seguro repite la misma intención con la misma identidad.
Un nuevo intento crea una nueva ejecución porque la anterior terminó con un resultado conocido o la política decidió avanzar.
Confundir ambas cosas es una fuente habitual de duplicados.
La idempotencia forma parte del contrato financiero de la API
Una API de pagos no puede asumir una red perfecta.
Las conexiones fallan, los clientes repiten, las colas reenvían y los procesos se reinician.
El diseño correcto convierte la repetición en un comportamiento previsto.
Cuando las claves de idempotencia, las máquinas de estados, las restricciones y la conciliación trabajan juntas, la plataforma puede recuperarse de fallos sin convertir la resiliencia en cobros duplicados.