
Event Sourcing en pagos: la única prueba que aguanta un audit
Event Sourcing en sistemas de pagos no es una preferencia de arquitectura sino el único mecanismo que garantiza trazabilidad matemática de cada transacción.
En IberianHub realizamos auditorías donde la "auditabilidad" no es una palabra de marketing, sino un requisito legal. Hace unos meses, trabajando con una fintech española, vivimos una situación que resume por qué los sistemas críticos no pueden permitirse ser cajas negras: un regulador pidió demostrar exactamente qué había ocurrido con una transacción de 2.400 € que había fallado de forma parcial.
Al investigar, el equipo técnico se encontró con un muro de cristal. La base de datos solo mostraba el estado final: status = failed. Los logs de aplicación confirmaban el fallo, pero no explicaban la secuencia de decisiones. No había rastro de cuántas veces se intentó el cobro, en qué orden respondieron los proveedores externos, ni en qué milisegundo exacto el sistema decidió que ya no había vuelta atrás.
Se necesitaron dos días de ingeniería forense cruzando logs de Datadog, trazas de OpenTelemetry y conversaciones de Slack para reconstruir la historia. El problema no era un bug puntual; era una debilidad arquitectónica: el sistema guardaba el resultado, pero desechaba la decisión.
El dinero requiere una "Auditabilidad Matemática" Un sistema de pagos no es un e-commerce. Si un inventario falla, se corrige manualmente y el daño es reversible. En pagos, un estado inconsistente es dinero en el limbo. La pregunta que debe responder un sistema robusto no es "¿cuál es el estado actual?", sino "¿qué pasó, en qué orden y quién autorizó cada paso?".
La mayoría de los sistemas que auditamos operan bajo una arquitectura de estado mutable:
[Estado A] → mutación → [Estado B] → mutación → [Estado C]
Los estados existen. Las mutaciones, si no se guardaron explícitamente, desaparecen.
Si la mutación no se registra explícitamente como un dato de primera clase, la historia desaparece. Event Sourcing propone invertir este modelo:
[Evento 1] → [Evento 2] → [Evento 3] → Estado (reconstruido por replay)
Al convertir los eventos en el dato primario, el sistema gana propiedades que son críticas ante un regulador o un incidente a las 3:00 AM:
-
Trazabilidad total: ¿Qué estado tenía este pago hace exactamente 73 horas?
-
Análisis de causa raíz: ¿Cuántas veces intentó procesarse antes de quedar bloqueado?
-
Temporal Querying: ¿Qué habría ocurrido si el sistema de fraude hubiera respondido de forma distinta?
Los logs operacionales no son un Event Store
Existe la creencia común de que tener Datadog o volcar datos en Kafka es equivalente a tener Event Sourcing. En nuestras auditorías vemos que la diferencia es estructural. Un log es texto optimizado para debugging humano. Un evento de dominio es un hecho de negocio estructurado, tipado y vinculante.
Diferencia de estructura:
-
Un log dice:
2026-03-15T02:43:17Z INFO payment_id=abc123 status=processed -
El evento de dominio dice:
{
type: 'PaymentAuthorized',
paymentId: 'abc123',
amount: 2400.00,
currency: 'EUR',
merchantId: 'merchant_xyz',
fraudScore: 0.12,
processorResponse: 'APPROVED',
aggregateVersion: 47,
timestamp: '2026-03-15T02:43:17.483Z'
}
LLa brecha crítica es la garantía transaccional. En un sistema tradicional, el log de aplicación y el estado de la base de datos pueden contradecirse si uno falla y el otro no. Event Sourcing colapsa esta brecha por diseño: el evento es el estado. Si no se guarda el evento, no hay cambio de negocio. No hay divergencia posible.
Implementación estratégica por Bounded Contexts
En IberianHub no recomendamos reescribir un sistema entero bajo este patrón; la complejidad y la curva de aprendizaje son altas. El enfoque correcto es identificar el Bounded Context donde la trazabilidad tiene mayor valor.
1. Modelado de hechos inmutables
Antes de tocar la infraestructura, definimos los hechos que pueden ocurrir en el ciclo de vida del dinero:
type PaymentEvent =
| { type: 'PaymentInitiated'; paymentId: string; amount: number }
| { type: 'FraudCheckPassed'; fraudScore: number }
| { type: 'AuthorizationApproved'; authCode: string }
| { type: 'CaptureCompleted'; settledAmount: number };
2. Estado como función pura de eventos
El estado se convierte en un derivado determinista de los eventos. Esto permite reconstruir la realidad en cualquier punto del tiempo sin depender de fotos fijas en la base de datos.
3. Persistencia y concurrencia optimista
Para evitar condiciones de carrera, utilizamos mecanismos de la propia base de datos (como una tabla de eventos en PostgreSQL con restricciones de unicidad en version) que garantizan el orden de los hechos incluso bajo alta concurrencia.
Más complejidad de código, menos riesgo operacional
Implementar Event Sourcing añade capas de complejidad: el modelo mental del equipo debe cambiar, las proyecciones requieren gestión y el despliegue es más exigente. Sin embargo, en sistemas de alta criticidad, esta complejidad es una inversión en predecibilidad.
Los incidentes se vuelven reproducibles de forma exacta, los bugs no corrompen datos de forma silenciosa y, lo más importante, el sistema se vuelve explicable.
En la auditoría fintech que mencionamos al inicio, el coste real no fue la sanción, sino el tiempo de ingeniería desperdiciado en reconstruir lo que una arquitectura de eventos habría entregado en segundos.
¿Es tu sistema de pagos capaz de explicar sus propias decisiones ante un regulador en menos de una hora? Si la respuesta es "depende de los logs", el riesgo operacional sigue presente.