Ir al contenido

Infraestructura

Webhooks en pagos: cómo evitar eventos duplicados y estados incoherentes

Aprende a autenticar, deduplicar y procesar webhooks de pagos con idempotencia, reintentos, ordenación y observabilidad.

15 min de lecturaPor Gustavo Sanchez Palencia
Ilustración editorial del artículo: Webhooks en pagos: cómo evitar eventos duplicados y estados incoherentes

Los webhooks son una de las partes más importantes de una integración de pagos porque resuelven un problema inevitable: no todo termina en la misma solicitud que inició la transacción.

Un cobro puede crearse ahora y confirmarse después. Un pago puede entrar en revisión. Una captura puede producirse en otro momento. Un reembolso puede procesarse de forma asíncrona. Un timeout puede ocultar un resultado que solo aparecerá unos segundos después.

Sin webhooks, la aplicación debe preguntar repetidamente al proveedor si algo ha cambiado. Con webhooks, el proveedor avisa cuando evoluciona el estado. La idea parece sencilla, pero implementarla correctamente exige cuidado con la autenticación, los duplicados, la ordenación, los reintentos, la idempotencia, el estado y la observabilidad.

El error más habitual es tratar el webhook como una llamada HTTP normal que siempre llega una vez, en el orden correcto y en el momento perfecto. Los sistemas distribuidos no funcionan así.

¿Qué es un webhook en pagos?

Un webhook es una notificación HTTP que un sistema envía a otro cuando ocurre un evento determinado.

En pagos, suele informar de cambios de estado relevantes para cobros, desembolsos, reembolsos, suscripciones u otros objetos financieros.

En lugar de que el comercio consulte al proveedor cada segundo, el proveedor envía una solicitud a una URL configurada en la integración.

La documentación de AZPay permite configurar una webhook_url para recibir cambios de estado de los cobros e incluye referencias específicas para webhooks de charge y payout.

Esta comunicación asíncrona es esencial porque el estado final de una transacción no siempre se conoce al crearla.

¿Un webhook es lo mismo que una respuesta de la API?

No.

La respuesta síncrona de la API representa lo que sabe el sistema en el momento de la solicitud. El webhook representa un evento posterior o una actualización relevante que debe comunicarse al integrador.

Un cobro puede devolverse como creado o pendiente y confirmarse después. Incluso cuando la respuesta inicial parece concluyente, eventos posteriores pueden alterar el ciclo de vida: captura, reversión, cancelación o disputa.

Por ello, las integraciones maduras no utilizan un único canal.

La respuesta síncrona sirve para conducir el recorrido inmediato. Los webhooks mantienen el estado sincronizado a lo largo del tiempo.

¿Por qué puede llegar dos veces un webhook?

Porque la entrega fiable suele depender de los reintentos.

El proveedor envía el evento y espera una respuesta satisfactoria. Si falla la conexión, el servidor tarda demasiado o responde con un error, el remitente puede volver a intentarlo.

También hay escenarios en los que el comercio envió la respuesta, pero esta se perdió en la red. Para el proveedor, la entrega parece haber fallado; para el comercio, el evento ya se procesó.

Resultado: el mismo evento puede llegar de nuevo.

Esto no es necesariamente un error. Es una consecuencia normal de sistemas distribuidos que prefieren repetir un mensaje a perderlo silenciosamente.

La aplicación debe estar preparada para procesar duplicados sin repetir efectos financieros o comerciales.

¿Qué significa procesar un webhook de forma idempotente?

Significa que recibir el mismo evento más de una vez produce el mismo estado final que recibirlo una sola vez.

Si un webhook informa de que un cobro se ha pagado, la primera entrega puede actualizar el pedido, liberar el producto y registrar el evento. La segunda no debería liberar de nuevo el producto, emitir otra factura, sumar saldo dos veces ni activar una segunda entrega.

La implementación suele exigir una identidad estable para el evento o una combinación de datos que permita reconocer que ese cambio ya se procesó.

Idempotencia no significa ignorar ciegamente todas las repeticiones. Significa controlar los efectos.

La aplicación puede registrar que el evento volvió a llegar por motivos de observabilidad, sin repetir una acción de negocio irreversible.

¿Puedo deduplicar solo con el estado?

Generalmente no basta.

Un cobro puede pasar por varios eventos legítimos relacionados con el mismo estado o recibir distintas actualizaciones a lo largo del tiempo. También puede haber varios objetos financieros asociados a una misma intención comercial.

Lo ideal es disponer de un identificador de evento cuando el proveedor lo ofrezca y conservar también la identidad del recurso afectado.

La combinación ayuda a responder dos preguntas distintas: ¿ya he procesado este evento? ¿Y qué objeto está actualizando?

Cuando no existe un event id explícito, la estrategia de deduplicación debe diseñarse con más cuidado para evitar descartar cambios legítimos.

¿Pueden llegar los webhooks fuera de orden?

Sí.

La red no garantiza que dos solicitudes asíncronas enviadas consecutivamente lleguen en el mismo orden. Los reintentos también pueden hacer reaparecer un evento antiguo después de uno nuevo.

Imagina un cobro que pasa de pending a paid. El webhook de paid llega primero y el sistema actualiza el pedido. Unos segundos después vuelve a llegar un intento retrasado de entrega del evento pending.

Si la aplicación sustituye el estado actual por el contenido del último webhook recibido, puede retroceder de paid a pending.

Este es uno de los errores más peligrosos en las integraciones orientadas a eventos.

¿Cómo evitar que el estado retroceda?

La aplicación debe comprender el ciclo de vida del objeto.

Una estrategia consiste en validar las transiciones permitidas. Otra es comparar la versión, una marca de tiempo fiable o una secuencia cuando el proveedor ofrece estos metadatos. En casos críticos, la aplicación puede consultar el estado actual directamente en la API antes de aplicar una actualización ambigua.

El principio es sencillo: no debe confundirse el orden de llegada con el orden del negocio.

Recibir una solicitud después no significa que represente un estado más reciente.

Modelar explícitamente la máquina de estados ayuda a evitar retrocesos imposibles.

¿Debo responder al webhook antes o después de procesarlo todo?

En la mayoría de las arquitecturas robustas, resulta útil separar recepción y procesamiento.

El endpoint valida la solicitud, registra o encola el evento de forma duradera y responde rápidamente. El trabajo pesado se realiza después.

Esto reduce la probabilidad de que el proveedor considere fallida la entrega solo porque una rutina interna tardó demasiado.

Si el handler intenta actualizar varias bases de datos, llamar a servicios externos, enviar correos y procesar lógica compleja antes de responder, cualquier lentitud aumenta la probabilidad de timeout y duplicados.

Responder rápido no significa aceptar eventos inválidos. Deben verificarse la autenticidad y la integridad antes de confirmar el procesamiento cuando así lo exija el protocolo.

¿Hay que autenticar los webhooks?

Sí.

Un endpoint público que acepta actualizaciones financieras sin verificar su origen crea una superficie evidente de abuso.

El mecanismo concreto varía: firma HMAC, clave compartida, certificado, token, firma asimétrica u otro método definido por el proveedor.

La aplicación debe seguir el mecanismo oficial de la integración y validar también elementos como la marca de tiempo cuando estén disponibles.

Además, los secretos utilizados para la verificación no deben aparecer en logs, código público o mensajes de error.

Autenticar el evento protege la frontera entre internet pública y el estado financiero interno.

¿Una lista de IP permitidas sustituye a la firma?

No necesariamente.

Puede ser una capa adicional, pero las direcciones pueden cambiar, las infraestructuras pueden utilizar redes compartidas y el control operativo puede volverse frágil.

Una firma criptográfica vincula el contenido recibido con una clave o identidad de confianza y puede detectar alteraciones del payload.

Cuando el proveedor ofrece una firma oficial, esta suele ser una base más apropiada para la autenticidad del evento.

Las defensas pueden combinarse, pero no conviene inventar un mecanismo paralelo que dificulte el mantenimiento.

¿Debe el payload ser la fuente final de verdad?

Depende del contrato de la API.

Algunos webhooks envían el objeto completo. Otros solo envían el identificador y el nuevo estado. En determinadas integraciones, el patrón recomendado es recibir la notificación y consultar el recurso actualizado mediante la API.

La documentación de AZPay para charge webhooks describe la estructura del evento y cómo obtener los detalles completos del cobro.

Este diseño puede resultar útil porque reduce el tamaño del evento y permite al comercio confirmar el estado actual del recurso cuando sea necesario.

La integración debe conocer su contrato específico, en lugar de asumir que todos los webhooks contienen todos los datos necesarios.

¿Cuándo combinar polling y webhooks?

Los webhooks y el polling no son necesariamente alternativas excluyentes.

El webhook es eficiente para las actualizaciones asíncronas. El polling puede ser útil como mecanismo de recuperación, conciliación o confirmación en escenarios concretos.

Imagina que el comercio estuvo indisponible varias horas y perdió eventos al agotarse la ventana de reintentos del proveedor. Un proceso de conciliación puede consultar las transacciones recientes y corregir las diferencias.

También puede tener sentido consultar un recurso cuando un timeout deja un resultado ambiguo.

La arquitectura más resiliente suele tratar los webhooks como canal principal de cambios y disponer de algún mecanismo de recuperación de incoherencias.

¿Qué hacer cuando el endpoint está caído?

El remitente debería tener una política de reintentos, pero el comercio no debe depender solo de ella.

Supervisar la disponibilidad y la tasa de entrega es esencial. Una caída silenciosa del endpoint puede dejar pedidos atrapados en un estado incorrecto aunque el procesamiento financiero funcione normalmente.

La operación necesita alertas cuando el volumen de webhooks cae inesperadamente, aumentan las respuestas 5xx o crece la cola de procesamiento.

La documentación de puesta en producción de AZPay incluye precisamente la supervisión de la entrega de webhooks y las alertas entre las cuestiones operativas.

¿Cómo funcionan los reintentos de webhooks?

La política depende del proveedor.

En general, los fallos temporales generan nuevos intentos a lo largo del tiempo. El backoff evita sobrecargar un endpoint que ya está indisponible.

El comercio debe saber qué códigos HTTP se interpretan como éxito, durante cuánto tiempo reintenta el proveedor y si existe un mecanismo para reprocesar eventos manualmente.

Este conocimiento debería formar parte del manual operativo de producción.

Cuando ocurre un incidente, el equipo debe saber si los eventos seguirán llegando automáticamente o si habrá que conciliar manualmente.

¿Qué es un replay de webhook?

Replay es el reenvío de un mensaje previamente válido.

Puede ocurrir legítimamente por un reintento o de forma maliciosa si alguien captura una solicitud e intenta repetirla.

Por eso, los mecanismos de firma suelen incluir una marca de tiempo u otro elemento temporal.

La aplicación puede rechazar mensajes demasiado antiguos cuando esté previsto en el protocolo y mantener además la deduplicación por event id.

La autenticidad sin protección temporal puede no ser suficiente para todos los modelos de amenaza.

¿Webhook e idempotency key resuelven el mismo problema?

No.

Una clave de idempotencia suele proteger una operación iniciada por el cliente o el comercio, como crear un cobro. Ayuda al servidor a reconocer repeticiones de la misma intención.

El procesamiento idempotente de webhooks protege el tratamiento de eventos que llegan del proveedor.

Ambos mecanismos actúan en sentidos opuestos de la comunicación y son complementarios.

Una arquitectura de pagos puede necesitar idempotencia al crear la charge y deduplicación al recibir los eventos relacionados con esa misma charge.

¿Qué ocurre en un timeout de pago?

El timeout es uno de los escenarios que muestran por qué los webhooks son tan importantes.

La aplicación envía un cobro, pero no recibe respuesta. Esto no demuestra que el proveedor no haya procesado la solicitud.

Si la operación crea otro cobro sin más, puede generar una duplicidad.

El camino seguro depende del contrato de la integración: consultar el estado, reutilizar la clave de idempotencia, esperar un evento asíncrono o combinar estas estrategias.

Un webhook tardío puede revelar que el primer intento se completó aunque fallara la respuesta síncrona.

¿Cómo se relacionan los webhooks con el failover?

El failover entre proveedores aumenta la complejidad del estado.

Si un intento en el PSP A sufre un timeout y la infraestructura envía otro al PSP B, el resultado del PSP A todavía puede llegar después por webhook.

La capa de orquestación debe saber que ambos eventos pertenecen a la misma intención comercial y decidir cómo representar el resultado.

Sin esa correlación, una ruta alternativa puede crear estados contradictorios o cobros duplicados.

Por eso, un failover seguro exige identidad del intento, idempotencia y un procesamiento asíncrono bien modelado.

¿Debe un webhook modificar directamente el pedido?

Puede activar la transición, pero conviene conservar las fronteras entre dominios.

El evento financiero informa de algo sobre el pago. El sistema de pedidos decide qué significa ese resultado para la preparación y entrega, el inventario o el acceso.

Separar estos dominios evita acoplar toda la operación al formato específico del PSP.

Un adaptador puede traducir el webhook del proveedor a un evento interno normalizado, como payment_paid o payment_failed. Los servicios de negocio consumen ese lenguaje común.

Esto resulta especialmente útil en operaciones multi-PSP.

¿Cómo normalizar webhooks de varios PSP?

Cada proveedor puede utilizar nombres de eventos, estructuras y códigos diferentes.

Una capa de integración puede validar y traducir esos eventos a un modelo interno coherente.

El objetivo no es borrar todas las diferencias, sino evitar que los sistemas de pedidos, suscripciones o soporte tengan que conocer cada payload externo.

La normalización puede representar entidades como pago, intento, autorización, captura y reembolso con estados propios del dominio.

Los detalles específicos siguen disponibles para investigar cuando hagan falta.

¿Cómo almacenar los eventos de webhook?

Resulta útil conservar un registro técnico suficiente para auditar sin exponer datos sensibles innecesarios.

Ese registro puede incluir event id, tipo, recurso, hora de recepción, resultado de la validación, estado del procesamiento y referencias de correlación.

Guardar el payload en bruto indefinidamente no siempre es necesario y puede aumentar el riesgo de seguridad o privacidad.

La estrategia debe considerar qué campos son realmente útiles para el soporte, la conciliación y la auditoría.

La seguridad editorial y la operativa siguen el mismo principio: almacenar solo lo necesario.

¿Qué supervisar en los webhooks?

La disponibilidad del endpoint es solo el principio.

También conviene seguir el volumen de eventos, la tasa de 2xx, la latencia de respuesta, la tasa de reintentos, los duplicados, los eventos pendientes en la cola, el tiempo hasta el procesamiento y los fallos por tipo de evento.

Otra señal importante es la diferencia entre el volumen esperado de transacciones y el volumen de eventos recibidos.

Si los pagos continúan y los webhooks caen bruscamente, existe un problema aunque el endpoint responda al health check.

La observabilidad debe mirar el comportamiento del flujo, no solo la infraestructura.

¿Cómo probar webhooks antes de producción?

El entorno de prueba debe cubrir algo más que el camino correcto.

Es importante simular duplicados, retrasos, orden inverso, respuestas 500, timeouts del endpoint e indisponibilidad temporal.

También conviene comprobar qué ocurre cuando llega un evento después de que la aplicación haya consultado y actualizado el estado por otro camino.

Las herramientas de inspección de webhooks pueden ayudar durante el desarrollo, y la documentación de AZPay recomienda recursos de este tipo junto con el sandbox.

El objetivo de la prueba es demostrar que la integración sigue siendo coherente cuando la red no se comporta perfectamente.

¿Qué documenta AZPay sobre webhooks?

La documentación de AZPay incluye una visión general de webhooks, una referencia de eventos de cobro, webhooks de payout y el uso de webhook_url en las solicitudes.

Esto permite a los comercios recibir actualizaciones del ciclo de vida y sincronizar sus sistemas sin depender únicamente de consultas periódicas.

La integración debe seguir los contratos y mecanismos de seguridad documentados para cada flujo.

Para una empresa que ya trabaja con orquestación, observabilidad y varios métodos, los webhooks forman parte del sistema nervioso de la operación.

Lista mental para una integración robusta

Una implementación debería poder responder claramente: ¿cómo verificamos la autenticidad? ¿Cómo identificamos el evento? ¿Cómo deduplicamos? ¿Qué transiciones de estado están permitidas? ¿Qué ocurre si se invierte el orden? ¿Cuánto tardamos en responder? ¿El procesamiento utiliza una cola duradera? ¿Cómo recuperamos los eventos perdidos? ¿Cómo supervisamos los fallos? ¿Cómo correlacionamos el evento con el pago, el intento y el pedido?

Si algunas de estas preguntas no tienen respuesta, la integración puede funcionar en pruebas y aun así fallar de una forma difícil de diagnosticar en producción.

Un webhook es una frontera de coherencia

El valor de un webhook no está solo en avisar de que algo cambió.

Conecta sistemas que tienen sus propios estados y deben seguir siendo coherentes pese a fallos de red, reintentos y procesamiento asíncrono.

Por ello, el endpoint debería ser pequeño, rápido y predecible. El procesamiento debería ser idempotente. El dominio debería rechazar retrocesos imposibles. La operación debería supervisar el flujo completo.

Cuando estos principios están presentes, los webhooks dejan de ser callbacks frágiles y se convierten en piezas fiables de la infraestructura de pagos.