Saltar al contenido principal
Volver a noticias
6 min de lecturaEquipo Cifrago

Idempotencia en pagos: cómo evitar cobros duplicados por reintentos y webhooks repetidos

Un fallo de red puntual o un webhook duplicado pueden provocar cobros dobles si el sistema no está protegido. Analizamos cómo funciona la idempotencia y qué pasos técnicos evitan duplicidades.

En el comercio digital, las conexiones de red fallan de manera inevitable. Un cliente pulsa el botón de pago en el checkout, el navegador envía la orden y la pasarela procesa el cargo con éxito, pero la conexión se corta un milisegundo antes de que la respuesta llegue al navegador. Ante la incertidumbre, el usuario vuelve a hacer clic o el backend reintenta la llamada de forma automática. Si el sistema no cuenta con mecanismos de protección, esa segunda llamada creará una segunda transacción idéntica.

El problema se multiplica en la recepción de notificaciones asíncronas. Los proveedores de pago utilizan sistemas de reintentos para garantizar la entrega de eventos. Si el servidor del comercio tarda en responder con un código HTTP de éxito, la pasarela volverá a enviar la notificación minutos después. Diseñar una integración robusta exige comprender qué es la idempotencia y cómo aplicarla tanto en las peticiones salientes como en la gestión de eventos entrantes.

Qué es la idempotencia y por qué resulta crítica en pagos

En matemáticas y ciencias de la computación, una operación es idempotente si produce el mismo resultado sin importar cuántas veces consecutivas se ejecute con los mismos parámetros. En el contexto de los cobros en línea, significa que enviar diez veces la misma instrucción de cobro debe resultar en una única transacción económica y diez respuestas idénticas.

Sin idempotencia, los fallos de comunicación generan fricción inmediata. El impacto no se limita al malestar del comprador: un cobro duplicado suele desembocar en comisiones bancarias imprevistas para el comercio, gestiones manuales de soporte y, con frecuencia, devoluciones y contracargos que perjudican la reputación del negocio ante las redes de tarjetas.

Claves de idempotencia en peticiones salientes

Cuando el servidor del comercio se comunica mediante una API con la pasarela de pago para procesar un cobro, la técnica habitual consiste en enviar un encabezado HTTP específico con un identificador único, conocido habitualmente como clave de idempotencia (`Idempotency-Key`).

El flujo de trabajo estándar sigue estos pasos:

  • Generación en el origen: antes de lanzar la petición de cobro, el comercio genera un identificador único (comúnmente un UUID versión 4) vinculado a la intención de compra o al identificador interno del carrito.
  • Registro en la pasarela: al recibir la petición, la pasarela comprueba si ya ha procesado una solicitud con esa misma clave en una ventana de tiempo predefinida (habitualmente entre 24 y 48 horas).
  • Respuesta almacenada si hay repetición: si la clave ya existe y la operación original concluyó, la pasarela no ejecuta un nuevo cargo en la tarjeta. En su lugar, devuelve la respuesta exacta que generó la primera vez, manteniendo el mismo estado y el mismo identificador de transacción.
  • Control de concurrencia: si la clave ya está registrada pero la operación previa sigue en curso, la pasarela devuelve un error temporal o un bloqueo de concurrencia para evitar condiciones de carrera, indicando al cliente que espere.

Este mecanismo traslada la responsabilidad de evitar duplicados a la capa de procesamiento, garantizando que los reintentos automáticos de la infraestructura ante errores de red o tiempos de espera no generen cargos dobles.

Gestión de webhooks duplicados en el servidor del comercio

La idempotencia no opera en una sola dirección. Mientras que las peticiones salientes protegen la creación del cobro, el procesamiento interno en el backend del comercio requiere salvaguardas idénticas al recibir notificaciones de eventos mediante webhooks.

Un error habitual consiste en asumir que cada webhook recibido representa un evento único. En la práctica, las redes distribuidas aplican semánticas de entrega al menos una vez (*at-least-once delivery*). Esto significa que un evento puede entregarse dos o tres veces debido a problemas de latencia o reintentos del emisor. Tal como ocurre al procesar webhooks firmados y datos de tarjeta, el receptor debe validar tanto la autenticidad como la unicidad del mensaje.

Para asegurar la idempotencia al recibir eventos, conviene aplicar este patrón en la base de datos:

  • Identificador de evento como clave única: cada evento emitido por la pasarela incluye un identificador único inmutable. El comercio debe guardar este identificador en una tabla de eventos procesados con una restricción de clave primaria o índice único.
  • Transacciones de base de datos: la inserción del identificador de evento y la actualización del pedido (por ejemplo, marcarlo como pagado y liberar el stock) deben ocurrir dentro de la misma transacción atómica de base de datos.
  • Ignorar duplicados sin devolver error: si la base de datos rechaza la inserción por duplicidad de clave, el servidor debe descartar las acciones comerciales posteriores (evitando duplicar envíos o créditos en cuenta) y responder a la pasarela con un código HTTP 200 inmediatamente. Si se devolviese un código de error, la pasarela interpretaría un fallo en la entrega y continuaría reintentando el envío.

Bloqueos optimistas y estados de la orden

En entornos de alta concurrencia, puede ocurrir que la respuesta síncrona del checkout y el webhook asíncrono lleguen prácticamente al mismo tiempo al backend. Para evitar que ambos procesos ejecuten de forma simultánea la entrega del producto o la generación de la factura, la arquitectura de pagos online debe incorporar máquinas de estados estrictas.

Si el pedido ya se encuentra en estado «procesado» o «pagado», cualquier proceso posterior que intente cambiar el estado a partir del mismo cobro debe detenerse de forma limpia. El uso de bloqueos optimistas (comprobando un número de versión del registro antes de actualizar) o bloqueos pesimistas a nivel de base de datos impide que dos hilos paralelos ejecuten la lógica de cumplimiento al mismo tiempo.

Buenas prácticas para un diseño a prueba de fallos

Garantizar la coherencia transaccional requiere constancia en todas las capas del sistema. Conviene fijar identificadores deterministas derivados del pedido para evitar que un refresco accidental del navegador genere un nuevo UUID antes de contactar con el backend. Asimismo, resulta esencial aislar las operaciones críticas dentro de colas de trabajo con procesamiento secuencial por pedido.

La idempotencia no es una optimización prescindible, sino el cimiento indispensable para que la facturación y la operativa de cobro mantengan su exactitud ante los inevitables fallos de las redes informáticas.

¿Estás montando suscripciones?

Mira las tarifas y prueba el panel con datos de ejemplo antes de integrar nada.

Seguir leyendo

2 min de lectura

Modernización del enrutamiento de tarjetas, banca abierta en Reino Unido y expectativas del BCE

Bank Pekao renueva su plataforma de pagos con NCR Atleos, mientras se debate la arquitectura de banca abierta británica y el BCE publica su encuesta de consumo.

5 min de lectura

Apple Pay y Google Pay sin artificios: qué es un token de red y por qué reduce el fraude

Lejos de ser simples monederos digitales, Apple Pay y Google Pay operan mediante tokens de red y criptogramas dinámicos. Analizamos su mecanismo técnico y su impacto en la seguridad del cobro.