
Banco Digital Público
Introducción
El Banco Digital Público (BDP) era un proyecto para el gobierno de Colombia que buscaba entregar los subsidios del Estado de una forma más eficiente. En vez de dinero, el beneficiario recibía tokens en una billetera digital y podía canjearlos en los comercios asociados, con descuentos.
Nosotros hicimos la app mobile, para Android y iOS. El core de tokenización y los servicios bancarios los proveían otros equipos, con los que nos integramos por API.

Qué hacía la app
- Registro de personas y empresas. Las personas se registraban con su teléfono y validaban su identidad con la cédula, a través del SDK de KYC de VU. Las empresas se registraban con su NIT y cargaban a sus accionistas.
- Subsidios. Cada subsidio tenía su saldo en tokens y sus movimientos, y los tokens se podían convertir en pesos y pasar a la cuenta bancaria.
- Pagos con QR. El comercio generaba un QR con el monto a cobrar y el usuario lo escaneaba para pagar. La app le mostraba solo las cuentas que ese comercio aceptaba, ya fuera un subsidio o la cuenta bancaria. El comercio podía devolver un pago.
- Transferencias a otros usuarios por número de teléfono y a cuentas de cualquier banco, con contactos recientes y comprobantes para compartir.
- Cuenta bancaria. Desde la app se abría una cuenta de bajo monto en el banco Coopcentral. Para pasar a una cuenta ordinaria, sin los topes de la de bajo monto, el usuario completaba el formulario de análisis de riesgo que pedía el banco: datos personales, laborales y financieros, información tributaria, bienes, operaciones internacionales, referencias, declaraciones de prevención de lavado de activos y documentación. Las empresas abrían su cuenta con un formulario equivalente, con los datos de la empresa. Al final se generaba el PDF de la solicitud.
- Gestión de la cuenta. Límites de transacciones, bloqueo de la cuenta o de parte del saldo y cancelación.
- Comercios. Los comercios se registraban con su foto y su actividad comercial, y tenían su QR de cobro. Los usuarios podían buscarlos por departamento y ciudad.
- Tarjetas. Tarjeta virtual emitida con Pomelo, que se podía consultar, bloquear y reemplazar, y pedido de la tarjeta física.
Enfoque técnico
Lideré el proyecto técnicamente: definí la arquitectura, lideré al equipo y programé casi toda la app.
La app estaba hecha en React Native con Expo y TypeScript, sobre
mis librerías open source (react-presenter, cqbus-lite, money, validator, entre otras).
Arquitectura
Usé la misma arquitectura que en el frontend de Culti: una versión liviana de Clean Architecture. En una app así hay poca lógica de negocio propia, pero mucha lógica de vista (formularios largos, validaciones, reglas sobre qué cuenta se puede usar en cada operación) y la tecnología de mobile cambia rápido. Separar las capas permite cambiar una sin tocar las otras.


- React solo dibujaba. Las pantallas no tenían lógica: mostraban lo que decía el ViewModel y le avisaban al Presenter cuando el usuario hacía algo. Casi no uso hooks ni librerías de manejo de estado.
- Presenters. La lógica de vista vivía en Presenters: clases de TypeScript puras, sin ninguna dependencia de React. El Presenter ejecutaba los casos de uso, validaba, formateaba los datos y exponía un ViewModel listo para mostrar. Por ejemplo, el Presenter del pago buscaba el comercio, consultaba qué cuentas aceptaba, armaba la lista con los saldos ya formateados y decidía a qué pantalla ir si algo falla.
- Casos de uso. Cada operación era un comando o una query que pasaba por un bus (
cqbus-lite) hasta su handler. Los Presenters no sabían si la operación era local o iba a la API. - App Services. Sesión, autenticación, navegación, biometría, KYC y analytics estaban detrás de interfaces. Sus implementaciones (Expo, Firebase, el SDK de VU) vivían en la capa de infraestructura.
Así, cambiar de librería de navegación o de proveedor de analytics era cambiar una implementación, y la lógica de cada pantalla se podía leer y probar sin levantar la UI.
Otras decisiones
- La API la desarrollaba otro equipo en paralelo. Para no depender de sus tiempos trabajamos contra el contrato: publicamos la especificación en Swagger y un servidor de mocks, y la app se podía probar completa antes de que cada endpoint existiera.
- El SDK de KYC de VU es nativo. Para integrarlo sin dejar Expo escribí un config plugin que agrega sus dependencias al build de Android.
- Por seguridad, la app se desbloqueaba con huella o rostro, no corría en dispositivos rooteados, permitía una sola sesión activa por usuario y obligaba a actualizar cuando salía una versión nueva.
- Un pipeline en GitHub Actions corría los tests y generaba los builds para los ambientes de QA, preproducción y producción.