Blog
Sobres de papel de colores vuelan hacia un buzón abierto.

31 de agosto de 20266 min de lecturaАдминистратор

El webhook llegó dos veces. Por qué el pedido debe cumplirse una sola vez

Un esquema práctico para recibir eventos de pago: verificación de autenticidad, protección contra repeticiones, conciliación de estados y recuperación de operaciones omitidas.

Ya se envió un HTTP 200, pero el abono no aparece en el saldo. El log dice «éxito», el cliente espera su producto y el proveedor ya no está obligado a reenviar de inmediato; con webhooks duplicados ocurre lo contrario, y ambos casos nacen en el mismo punto. Esta falla aparece en la frontera entre dos hechos: el mensaje se recibió, pero la acción de negocio no se completó. Conviene analizar los webhooks justamente desde esa frontera, y no desde escribir un procesador de diez líneas.

Primero defina en qué sistema confiar

Una integración de pagos tiene varias preguntas distintas. El proveedor informa el estado de su operación. El registro interno muestra qué acciones ya ejecutó la plataforma. El reporte de liquidación ayuda a verificar el movimiento real del dinero. Asigne una fuente de verdad a cada pregunta: el estado del pago se verifica con el mecanismo previsto por el proveedor, el despacho se confirma con un registro interno y el ingreso en la liquidación se verifica mediante la conciliación. Ni siquiera una notificación de pago correcta debe convertirse en prueba universal de los tres hechos.

Para cada adaptador, redacte un contrato breve: qué identificadores son estables, qué eventos pueden repetirse, dónde está disponible el estado actual y qué cambios se consideran válidos. Por ejemplo, Stripe admite entregas repetidas y no garantiza el orden de los eventos. Ordenar por hora no basta para demostrar que una transición de estado es válida. Ese matiz importa más que un esquema general elegante e idéntico para cualquier proveedor.

Separe la recepción del evento de la ejecución de la acción

El esquema propuesto empieza por verificar la autenticidad según las reglas de la API concreta. Luego el evento se registra en un log de entrada y el procesamiento de negocio se ejecuta por separado. Envíe el acuse de recibo dentro del plazo previsto en el contrato, después de guardar el mensaje de forma confiable. Si el registro falló, el sistema no debe fingir que el evento ya se recibió. El despacho prolongado, el correo al comprador o la actualización del reporte no deberían formar parte de ese camino corto.

La verificación de autenticidad también depende del proveedor. PayPal describe la verificación de la firma de la notificación; si la verifica usted mismo, importan los bytes originales del cuerpo. Por eso, compruebe de antemano que ningún middleware de la aplicación modifique los datos originales antes de la verificación. No traslade los requisitos de un servicio a otro sin leer la documentación correspondiente.

En el log de entrada conviene guardar el proveedor, el contexto de la cuenta, el identificador del evento, el identificador de la operación, la hora de recepción, el resultado de la verificación y el estado del procesamiento. Guarde el cuerpo completo solo cuando haya una necesidad justificada, con acceso restringido y un plazo de conservación. Soporte normalmente necesita referencias y estados, no una copia de los datos personales de cada mensaje.

Repetir la entrega y repetir la acción de negocio no son lo mismo

Verificar el identificador del evento detendrá la repetición de la misma entrega. Proteja además la acción en sí: para el par «operación de pago + abono» debe existir un único registro de ejecución permitido. Es un nivel de protección aparte, porque mensajes distintos pueden describir el mismo resultado de negocio. Diseñe el registro de la acción ejecutada y el cambio del saldo interno como una operación consistente; de lo contrario, una falla entre ambos dejará abierta la posibilidad de un abono duplicado.

No elija la clave de deduplicación al azar. Adyen describe repeticiones con los mismos eventCode y pspReference, aunque otros campos puedan variar. Por lo tanto, un hash universal de todo el JSON no reemplaza las reglas del formato concreto. Al mismo tiempo, una clave demasiado amplia puede ocultar un evento posterior legítimo, como un reembolso parcial independiente.

Siga un pago hasta el final

En el ejemplo hipotético, el pedido M-418 cuesta 72 euros. El evento de pago confirmado se guarda primero. El proceso de trabajo encuentra el pedido, verifica el monto, la moneda y la cuenta, actualiza el pago y crea una única tarea de despacho. Una notificación tardía de «en proceso» queda en el historial, pero no hace retroceder el pedido. Una segunda confirmación de pago no crea otro despacho. El evento de reembolso se procesa con su propio identificador y sus propias reglas, en lugar de descartarse porque el pedido ya está pagado.

Si los mensajes se contradicen, envíe la operación a revisión y solicite los datos actuales por un medio permitido. Para un método sin una consulta en línea adecuada, use los reportes previstos y el escalamiento al proveedor. La ausencia de una notificación nueva no prueba por sí sola un rechazo.

La cola roja debe tener salida

Una cola de errores separada es útil mientras se pueda devolver un evento al flujo de forma segura. En el proceso propuesto, el registro contiene el motivo de la detención: pedido desconocido, conflicto de monto, tipo no soportado o error técnico. Los tres primeros motivos requieren una decisión; el último puede resolverse con un reintento. Un solo botón de «reprocesar todo» borra esa diferencia y convierte la recuperación en un nuevo incidente.

Antes de reprocesar, muestre al operador lo que ya se ejecutó: abono, despacho, reembolso, aviso al cliente. Solo hay que repetir el paso permitido que falta. Si se vuelve a ejecutar todo el escenario de negocio tras corregir el parser, una recepción idempotente del evento todavía no garantiza un envío idempotente del correo ni la creación idempotente del envío. Pruebe los efectos secundarios por separado, también después de actualizar el código.

La antigüedad importa más que un buen porcentaje

Una cola hipotética contiene 900 eventos recientes y un mensaje atascado desde ayer. El tiempo promedio de procesamiento puede verse aceptable mientras un comprador sigue sin resultado. Monitoree la antigüedad del evento sin procesar más antiguo por tipo de operación y la cantidad de eventos sin responsable. Los retrasos admisibles pueden variar entre reembolsos, entrega de productos y avisos informativos.

Para probar la recuperación, elija un evento concreto y llévelo desde la recepción inicial hasta el efecto financiero. Registre no solo el resultado, sino también la versión del procesador. Cuando cambie el formato de los datos, quedará claro qué eventos antiguos pueden reproducirse con el código nuevo y cuáles requerirán un análisis compatible. No guarde el payload completo de forma indefinida por una hipotética depuración: basta un conjunto justificado de datos y un plazo aprobado.

Elija un evento de ayer de la cola de errores. Si un empleado puede completar de forma segura justo la acción que falta y demostrar por qué las demás no se repetirán, el camino de recuperación realmente existe. Si se ve obligado a cambiar a mano el estado del pedido, el procesador de webhooks todavía deja el trabajo a un sistema de conjeturas.

Fuentes

  1. 1.docs.stripe.com/webhooks
  2. 2.docs.adyen.com/development-resources/webhooks/handle-webhook-events
  3. 3.developer.paypal.com/api/rest/webhooks/rest

Comentarios · 0

Aún no hay comentarios — sé el primero.

Entrar · inicia sesión para comentar.