
Cómo programar con plata

Antes de los sistemas digitales, si tenías un comercio, tus clientes te pagaban en efectivo. Si eras ordenado, llevabas un registro manual. Y si algo no cuadraba, te dabas cuenta rápido, porque el flujo era manejable.
Hoy, los pagos son digitales y el flujo es enorme. Hay terceros —como nosotros en Fintoc— que procesamos miles de transacciones por segundo, moviendo plata que no es nuestra. Y cuando estás en esa posición, no puedes darte el lujo de perder ni un solo peso.
Ahí es donde entra la ingeniería. Porque programar con plata no es como programar cualquier otra cosa. Puedes ver la charla o si estás con poco tiempo acá te cuento cómo lo hacemos en Fintoc en menos de 5 minutos.
Contexto
En Fintoc conectamos personas con comercios. Para eso ofrecemos una API que permite que las personas paguen haciendo una transferencia desde su cuenta a una de Fintoc (payments) y después Fintoc se encarga de mover todo lo que tiene en sus cuentas a cada comercio (payouts).
Esto pasa todos los días, con miles de pagos y cientos de comercios distintos. Hay personas pagando a muchos comercios al mismo tiempo y muchos comercios recibiendo pagos de muchas personas. Y todo tiene que cuadrar.

Mover plata no es trivial
Por lo mismo, tenemos que estar seguros de dos cosas:
- Que no se pierda ni un solo peso.
- Que nunca “inventemos” plata.
Cada peso tiene que estar justificado: quién lo hizo, cuánto le debemos al comercio y cuándo hay que transferirlo.
La solución más intuitiva sería: sumar todos los pagos del día y transferir.
%20(1).jpg)
Pero esta simplificación de su balance tiene algunas limitantes:
- No considera devoluciones, comisiones ni errores.
- Es difícil de auditar si algo no cuadra con el banco.
- Responder preguntas para un momento específico del pasado es mucho más complejo y pesado de calcular. ¿Qué balance tenía un cliente el martes pasado a las 17:00?
Para considerar el monto necesario para realizar devoluciones en el balance este debe ser considerado en nuestra ecuación.
%20(1).jpg)
Y si queremos descontar nuestras comisiones de su balance también debe ser considerado. Empezamos a notar un patrón. Cada vez que queremos agregar un nuevo comportamiento, esta ecuación empieza a crecer. Esto pasa porque estamos acoplando nuestra contabilidad con nuestro producto.

Esto se complica aún más en el minuto que queramos contrastar la realidad de nuestro negocio con la del banco. Si por alguna razón algo no calza, encontrar dónde está esa inconsistencia es muy complicado porque la verdad de lo que debía suceder en la cuenta de Fintoc está distribuida por muchos lados.
%20(1).jpg)
El problema no era técnico, era contable.
La solución: contabilidad de doble entrada
La forma de resolver esto ya existe hace más de 500 años: la contabilidad de doble entrada o ledger de doble entrada.
¿Qué es este ledger? Es un sistema que permite registrar movimientos de plata. Con este nos aseguramos de que no vamos a inventar plata porque cada movimiento que se registra tiene una explicación de por qué esta ahí.
En Fintoc implementamos un ledger de doble entrada donde cada movimiento afecta a dos cuentas:

¿Cómo lo usamos? Registrando cada movimiento de plata en distintas cuentas. Cuentas que indican cuánto tenemos de un tipo específico de activo o pasivo. Cada movimiento de plata que cause un aumento o disminución de un activo o pasivo, hace que el balance de su cuenta cambie.
%20(1).jpg)
Y así cuando comparamos nuestras cuentas de activos y pasivos, podemos ver que el equilibrio entre ellos se mantiene. Todos los movimientos que ocurren en Fintoc se escriben de esta forma y cada operación que se escribe en el ledger a partir de un movimiento se agrupa en lo que llamamos una transacción.
%20(1).jpg)
Por diseño cada transacción debe mantener el equilibrio entre activos y pasivos, y así, el sistema no puede inventar ni perder plata, porque cada transacción tiene que cuadrar. Si activos y pasivos no se equilibran, el sistema simplemente no permite esa transacción.
Con esta forma de registrar nuestros movimientos, saber el balance de cada cliente se vuelve trivial y nuestras operaciones mucho más simples.
Veamos esto en un ejemplo:
Concurrencia: cuando mucho pasa al mismo tiempo
Esta forma de programar con plata funciona muy bien mientras el flujo es bajo. Para actualizar el balance de una cuenta, primero hay que conocer el balance previo. Y eso está bien, hasta que todo empieza a pasar al mismo tiempo.
%20(1).jpg)
Cuando tienes miles de pagos ocurriendo en paralelo, puede pasar que dos operaciones intenten escribir sobre una misma cuenta al mismo tiempo. Las dos leen el mismo estado previo y calculan un nuevo balance sin saber lo que está escribiendo la otra.
Para evitar lo anterior y no perder información, necesitamos que los pagos se escriban en orden: el primero actualiza el balance y el segundo lo hace tomando en cuenta ese resultado. Para eso realizamos locks en nuestra base de datos.
¿El problema? Si 1000 pagos quieren actualizar la misma cuenta en paralelo, el último en escribir tiene que esperar que los 999 anteriores terminen. Cuando esto pasa, tu base de datos estará al límite y tu sistema empieza a degradarse: jobs más lentos y colas que crecen sin parar. Todo se vuelve más lento y todo empieza a fallar.

Esto nos pasó hace 1 año cuando nuestro flujo empezó a aumentar y nos dimos cuenta de que no habíamos considerado una alternativa: No todos los registros necesitan escribirse de inmediato en el ledger. Podemos esperar un poco y evitar pedir locks de forma innecesaria. Para esto podemos hacer uso de una cola y permitir que los eventos se procesen en orden, evitando carga innecesaria en el sistema.

¿Eso era todo?
Si los eventos llegan más rápido de lo que los podemos procesar, el Ledger se atrasa. Y cuando nuestras decisiones se basan en un estado desactualizado, podemos tomar decisiones equivocadas.
Si llegas a ese punto es importante notar que muchos de estos eventos ya ocurrieron y tienen que ser registrados eventualmente, por lo que puedes usar una estrategia que permita acelerar las escrituras sin tener que procesar cada evento de forma independiente. El detalle de cómo coordinamos esto es materia para otro blog.
Programar con plata o escalar sistemas, son algunos de los temas que se hablan en Tech Talks by Fintoc. Si te gustaría ir al próximo, inscríbete a nuestro newsletter o síguenos en LinkedIn e Instagram para estar atento.