@agustinespildora/open-banking-chile
v2.0.2
Published
Scrapers open source para bancos chilenos. Obtén tus movimientos y saldo como JSON. Open source scrapers for Chilean banks.
Maintainers
Readme
Open Banking Chile
Scrapers open source para bancos chilenos. Obtén tus movimientos bancarios y saldo como JSON limpio.
Disclaimer: Este proyecto no está afiliado con ningún banco. Úsalo bajo tu propia responsabilidad y solo con tus propias credenciales.
Migración v2 → v3
v3.0.0 introduce un cambio breaking en ScrapeResult:
Los movimientos ya no están en un array plano result.movements — ahora viven dentro de cada cuenta/tarjeta:
| Antes (v2) | Ahora (v3) |
| ------------------------ | ------------------------------------------- |
| result.movements | result.accounts[i].movements |
| result.balance | result.accounts[i].balance |
| (no existía) | result.creditCards[i].movements |
// v2 (ya no válido)
console.log(result.balance);
for (const m of result.movements) { ... }
// v3
const cuenta = result.accounts?.[0];
console.log(cuenta?.balance);
for (const m of cuenta?.movements ?? []) { ... }
// Movimientos de una tarjeta específica
for (const card of result.creditCards ?? []) {
console.log(card.label, card.movements?.length);
}Los campos movements y balance en ScrapeResult se mantienen como @deprecated para compatibilidad temporal.
Migración v1 → v2
v2.0.0 introduce un cambio breaking en la interfaz BankMovement:
El campo source ahora es obligatorio e indica el origen del movimiento. Si construyes objetos BankMovement manualmente, agrega source: "account". Si solo consumes resultados del scraper, no hay cambios necesarios.
También en esta versión: utilidades compartidas (parseChileanAmount, normalizeDate, deduplicateMovements, etc.) disponibles como exports desde open-banking-chile/utils.
Bancos soportados
| Banco | ID | Estado |
| --------------------------------- | ------------ | ------------ |
| Banco Falabella (cuenta + CMR TC) | falabella | ✅ Funcional |
| Banco BICE | bice | ✅ Funcional |
| Banco Santander | santander | ✅ Funcional |
| Banco Edwards | edwards | ✅ Funcional |
| Scotiabank | scotiabank | ✅ Funcional |
| Banco de Chile | bchile | ✅ Funcional |
| BCI | bci | ✅ Funcional |
| Itaú | itau | ✅ Funcional |
| Banco Estado (CuentaRUT) | bestado | ✅ Funcional |
| Tarjeta Cencosud | cencosud | ✅ Funcional |
¿Tu banco no está? → Contribuir
Requisitos
- Node.js >= 18
- Google Chrome o Chromium
# Instalar Chrome — Ubuntu/Debian
sudo apt update && sudo apt install -y google-chrome-stable
# macOS
brew install --cask google-chromeInstalación
# Desde GitHub
npm install github:kaihv/open-banking-chile
# O clonar el repo
git clone https://github.com/kaihv/open-banking-chile.git
cd open-banking-chile
npm install
npm run buildUso
CLI
Configura tu archivo .env con tus credenciales:
# Banco Falabella
FALABELLA_RUT=12345678-9
FALABELLA_PASS=tu_clave
# Banco BICE
BICE_RUT=12345678-9
BICE_PASS=tu_clave
## Opcional:
BICE_MONTHS=1
# Banco Santander
SANTANDER_RUT=12345678-9
SANTANDER_PASS=tu_clave
# Banco de Chile
BANCOCHILE_RUT=12345678-9
BANCOCHILE_PASS=tu_clave
# Banco Edwards
EDWARDS_RUT=12345678-9
EDWARDS_PASS=tu_clave
# Itaú
ITAU_RUT=12345678-9
ITAU_PASS=tu_clave
# Banco Estado
BESTADO_RUT=12345678-9
BESTADO_PASS=tu_clave
# Tarjeta Cencosud
CENCOSUD_RUT=12345678-9
CENCOSUD_PASS=tu_claveEjecuta la librería con el comando npx, dotenv incluirá automáticamente las variables de entorno.
# Consultar banco
npx open-banking-chile --bank falabella --pretty
npx open-banking-chile --bank santander --pretty
npx open-banking-chile --bank bchile --pretty
npx open-banking-chile --bank edwards --pretty
npx open-banking-chile --bank itau --pretty
npx open-banking-chile --bank bestado --pretty
npx open-banking-chile --bank cencosud --pretty
# Solo movimientos
npx open-banking-chile --bank falabella --movements | jq .
# Listar bancos disponibles
npx open-banking-chile --list
# Con screenshots para debugging
npx open-banking-chile --bank falabella --screenshots --prettyOpciones CLI:
| Flag | Descripción |
| ------------------- | --------------------------------------------------------------- |
| --bank <id> | Banco a consultar (requerido) |
| --list | Listar bancos disponibles |
| --pretty | JSON formateado |
| --movements | Solo array de movimientos |
| --screenshots | Guardar screenshots locales en ./screenshots/ |
| --headful | Chrome visible (debugging). BancoEstado siempre usa headful |
| --owner <T\|A\|B> | Filtro Titular/Adicional para TC (default: B = todos) |
| --statement-months <N> | Estados de cuenta de TC a leer, del más reciente hacia atrás (default: 1). Solo Banco de Chile |
Como librería
import { banks, getBank } from "open-banking-chile";
// Opción 1: por ID
const falabella = getBank("falabella");
const result = await falabella!.scrape({
rut: "12345678-9",
password: "mi_clave",
});
// Opción 2: import directo
import { falabella } from "open-banking-chile";
const result = await falabella.scrape({
rut: "12345678-9",
password: "mi_clave",
});
if (result.success) {
console.log(`Banco: ${result.bank}`);
// Cuenta corriente
for (const account of result.accounts ?? []) {
console.log(`Saldo: $${account.balance?.toLocaleString("es-CL")}`);
for (const m of account.movements) {
const sign = m.amount > 0 ? "+" : "";
console.log(`${m.date} | ${m.description.padEnd(40)} | ${sign}$${m.amount.toLocaleString("es-CL")}`);
}
}
// Tarjetas de crédito
for (const card of result.creditCards ?? []) {
console.log(`\nTarjeta: ${card.label}`);
for (const m of card.movements ?? []) {
const sign = m.amount > 0 ? "+" : "";
console.log(`${m.date} | ${m.description.padEnd(40)} | ${sign}$${m.amount.toLocaleString("es-CL")} [${m.source}]`);
}
}
}Meses anteriores de tarjeta de crédito (statementMonths)
Un movimiento de TC sale del feed de no facturados en cuanto se factura, y desde
ahí el banco solo lo expone dentro del estado de cuenta de su período. Por
defecto se lee un solo estado de cuenta, el más reciente, así que todo lo
facturado en períodos anteriores queda fuera. statementMonths decide cuántos
leer, del más nuevo hacia atrás:
const result = await getBank("bchile")!.scrape({
rut: "12345678-9",
password: "mi_clave",
statementMonths: 4,
});Cada período agrega dos llamadas a la API del banco, sin login extra. La
metadata de la tarjeta (nextBillingDate, nextDueDate, lastStatement,
billingPeriod) siempre sale del estado de cuenta más reciente. Hoy solo lo usa
Banco de Chile.
Output
{
"success": true,
"bank": "falabella",
"accounts": [
{
"balance": 1250000,
"movements": [
{
"date": "08-03-2026",
"description": "COMPRA SUPERMERCADO LIDER",
"amount": -45230,
"balance": 1250000,
"source": "account"
}
]
}
],
"creditCards": [
{
"label": "CMR Mastercard ****1234",
"national": { "used": 50000, "available": 950000, "total": 1000000 },
"nextBillingDate": "19-04-2026",
"nextDueDate": "05-05-2026",
"periodExpenses": 15990,
"movements": [
{
"date": "07-03-2026",
"description": "COMPRA COMERCIO",
"amount": -15990,
"balance": 0,
"source": "credit_card_unbilled",
"card": "****1234",
"owner": "titular",
"installments": "01/03",
"totalAmount": 47970
},
{
"date": "01-03-2026",
"description": "PAGO TARJETA DE CRÉDITO",
"amount": 70000,
"balance": 0,
"source": "credit_card_billed",
"card": "****1234"
}
]
}
]
}Campo source
Cada movimiento incluye un campo source que indica su origen:
| Valor | Descripción |
| ---------------------- | --------------------------------- |
| account | Cuenta corriente o vista |
| credit_card_unbilled | Tarjeta de crédito — por facturar |
| credit_card_billed | Tarjeta de crédito — facturado |
Campos opcionales en BankMovement:
| Campo | Descripción |
| -------------- | --------------------------------------------------------------------------- |
| owner | "titular" o "adicional" (Falabella CMR) |
| card | Máscara de la tarjeta, ej: "****8335" (BChile, Falabella) |
| installments | Cuotas en formato NN/NN, ej: "02/06" = cuota 2 de 6 |
| totalAmount | Monto total de la compra cuando es en cuotas (Falabella) |
Seguridad
- Tus credenciales nunca salen de tu máquina. Todo corre 100% local.
- No hay analytics, telemetría, ni tracking.
- Las credenciales se pasan por env vars, nunca se guardan en disco.
- Los screenshots de debug pueden contener datos sensibles — no los compartas.
- Lee SECURITY.md para más detalles.
Arquitectura
El proyecto sigue una arquitectura limpia en tres capas, separando responsabilidades para facilitar la reutilización y la adición de nuevos bancos:
src/
index.ts — Registro de bancos, getBank(), listBanks()
types.ts — Interfaces: BankScraper, BankMovement, ScrapeResult
utils.ts — Utilidades compartidas (parsing, fechas, dedup)
cli.ts — CLI entry point
infrastructure/
browser.ts — Gestión centralizada del browser (launch, sesión, cleanup)
scraper-runner.ts — Pipeline de ejecución (credenciales → browser → scrape → logout → resultado)
actions/
login.ts — Login genérico (RUT, password, submit, detección de errores)
navigation.ts — Navegación DOM (click por texto, sidebars, banners)
extraction.ts — Extracción de movimientos desde tablas HTML
pagination.ts — Iteración multi-página (Siguiente, Ver más)
credit-card.ts — Extracción de movimientos de tarjeta de crédito
balance.ts — Extracción de saldo
two-factor.ts — Detección y espera de 2FA
banks/
falabella.ts — Banco Falabella + CMR (cuenta + tarjeta de crédito)
bestado.ts — Banco Estado (CuentaRUT, requiere headful)
bchile.ts — Banco de Chile
bci.ts — BCI (iframes + BCI Pass)
bice.ts — Banco BICE
cencosud.ts — Tarjeta Cencosud (hCaptcha intermitente, requiere --headful si aparece)
edwards.ts — Banco Edwards
itau.ts — Itaú
santander.ts — Banco Santander
scotiabank.ts — Scotiabank ChileCapas
Infrastructure — Gestión del ciclo de vida del browser. launchBrowser() centraliza la configuración de Chrome (anti-detección, user agent, modo headful/headless). runScraper() envuelve toda la ejecución: valida credenciales, abre el browser, ejecuta el scraper del banco, hace logout y cierra el browser. Los errores se capturan y retornan como ScrapeResult.
Actions — Operaciones reutilizables e independientes del banco. Cada banco compone estas acciones en vez de reimplementarlas. Por ejemplo, fillRut() soporta múltiples formatos de RUT y funciona tanto en Page como en iframes; paginateAndExtract() navega automáticamente por páginas acumulando movimientos; detect2FA() detecta segundo factor por keywords configurables.
Banks — Orquestación específica de cada banco. Solo contienen la lógica particular: selectores CSS propios, flujo de navegación, y configuración de 2FA. Usan runScraper() como wrapper y componen acciones del layer anterior.
Utilidades compartidas (utils.ts)
Funciones comunes usadas por scrapers y acciones:
| Función | Descripción |
| ----------------------------------------------- | ---------------------------------------------------------------------- |
| parseChileanAmount(text) | Parsea montos en formato chileno ($1.234.567) a número |
| normalizeDate(raw) | Normaliza fechas a DD-MM-YYYY (soporta dd/mm/yyyy, "9 mar 2026", etc.) |
| normalizeOwner(raw) | Normaliza owner a "titular" o "adicional" |
| normalizeInstallments(raw) | Normaliza cuotas a formato NN/NN (ej: "1/3" → "01/03") |
| deduplicateMovements(movements) | Elimina movimientos duplicados por fecha+descripción+monto+source |
| logout(page, debugLog) | Cierra sesión buscando botones comunes (cerrar sesión, salir, etc.) |
| formatRut(rut) | Formatea RUT (12345678-9 → 12.345.678-9) |
| findChrome() | Busca Chrome/Chromium en el sistema |
| closePopups(page) | Cierra popups y modales genéricos |
| delay(ms) | Espera N milisegundos |
| saveScreenshot(page, name, enabled, debugLog) | Guarda screenshot si está habilitado |
Contribuir
Queremos cubrir todos los bancos de Chile. Si tienes cuenta en un banco que falta:
- Lee CONTRIBUTING.md para la guía paso a paso
- Crea
src/banks/<tu-banco>.tsimplementandoBankScraper - Usa
runScraper()deinfrastructure/y compone acciones deactions/(login, extracción, paginación, etc.) - Usa las utilidades compartidas de
utils.ts(parsing, fechas, dedup, logout) - Regístralo en
src/index.ts - Abre un PR
// La interfaz es simple:
interface BankScraper {
id: string; // "mi-banco"
name: string; // "Mi Banco Chile"
url: string; // "https://www.mibanco.cl"
scrape(options: ScraperOptions): Promise<ScrapeResult>;
}Automatización (cron)
# Ejemplo: sincronizar Falabella diariamente a las 7 AM
0 7 * * * source /home/user/.env && node /path/to/dist/cli.js --bank falabella >> /var/log/bank-sync.log 2>&1
# Ejemplo: sincronizar BICE diariamente y con 3 meses históricos
0 7 * * * source /home/user/.env && BICE_MONTHS=3 node /path/to/dist/cli.js --bank bice >> /var/log/bank-sync.log 2>&1Troubleshooting
| Problema | Solución |
| --------------------- | ---------------------------------------------------------------------------------------------- |
| Chrome no encontrado | Instala Chrome o usa CHROME_PATH=/ruta/chrome |
| 2FA / Clave dinámica | Si aparece, apruébalo manualmente en tu banco y vuelve a intentar |
| 0 movimientos | Usa --screenshots --pretty y revisa el debug log |
| Login falla | Verifica RUT y clave, prueba con --headful |
| BancoEstado bloqueado | BancoEstado bloquea headless (TLS fingerprinting). Siempre abre Chrome visible. Ver nota abajo |
| Cencosud pide CAPTCHA | Ocurre ocasionalmente. En headless retorna error — reintenta con --headful para resolverlo manualmente |
BancoEstado y modo headless
BancoEstado detecta navegadores headless a nivel de red (TLS fingerprinting), no solo por JavaScript. Ni puppeteer-extra-plugin-stealth ni rebrowser-puppeteer-core logran evadir esta detección. El scraper siempre corre en modo headful (Chrome visible).
Tarjeta Cencosud y CAPTCHA
Tarjeta Cencosud presenta ocasionalmente un hCaptcha en el login. No siempre aparece.
- Headless (modo por defecto): el scraper detecta el CAPTCHA y retorna un error claro.
- Headful (
--headful): el scraper pausa y espera a que resuelvas el CAPTCHA manualmente en el navegador visible, luego continúa.
node dist/cli.js --bank cencosud --headful --prettyEl tiempo máximo de espera es 180 segundos (configurable con CENCOSUD_CAPTCHA_TIMEOUT=segundos).
En servidores Linux sin GUI, usa Xvfb (display virtual):
# Instalar
sudo apt install xvfb
# Correr con display virtual
xvfb-run node dist/cli.js --bank bestado --pretty
# O como parte de tu app
xvfb-run node tu-app.jsEn Docker:
RUN apt-get update && apt-get install -y xvfb google-chrome-stable
CMD ["xvfb-run", "node", "server.js"]En Mac/Windows no necesitas nada extra — Chrome se abre y cierra automáticamente.
License
MIT — Hecho en Chile 🇨🇱
