# Banco por Dentro (3/3): A Arquitetura de Sistemas de um Banco

A terceira parte da série 'Banco por Dentro' desce o elevador até o andar técnico: explica o ledger de dupla entrada, os motores que compõem um core banking, por que idempotência é o problema central em dinheiro, e como resiliência e segurança funcionam quando um bug significa prejuízo real. Para desenvolvedores e arquitetos migrando para o setor financeiro.

- URL: https://fernando.moretes.com/studies/banco-por-dentro-3-arquitetura-de-sistemas

- Markdown: https://fernando.moretes.com/studies/banco-por-dentro-3-arquitetura-de-sistemas/study.md?lang=pt

- Type: Guia / Deep Dive

- Domain: Mercado Financeiro

- Date: 2026-06-21

- Tags: core-banking, ledger, idempotency, event-sourcing, financial-architecture, bacen, hsm, settlement

- Reading time: 8 min

---

Se você veio do mundo de software e está entrando no mercado financeiro, provavelmente já ouviu que 'banco é diferente'. Mas diferente *como*? A Parte 1 desta série explicou o negócio bancário e a regulação (BACEN, SPB). A Parte 2 cobriu os produtos e os rails de pagamento (PIX, TED, boleto). Agora descemos o elevador — no sentido de Gregor Hohpe — até o andar onde vivem os engenheiros: o núcleo técnico de um banco. Aqui você vai entender por que um banco não é apenas um CRUD com saldo, por que idempotência não é opcional, e por que 'eventual consistency' pode ser aceitável no seu e-commerce mas é perigosa quando o ativo é dinheiro de verdade.

## O que você vai aprender

- O que é um ledger de dupla entrada e por que ele é imutável por design
- Quais são os 'motores' de um core banking e o que cada um faz
- Por que idempotência é o problema central em sistemas de dinheiro
- Como filas de eventos e reprocessamento seguro se encaixam nesse contexto
- Por que consistência forte importa aqui (e o que o incidente Coinbase/AWS MSK ensina)
- Como HSM e auditabilidade funcionam na prática

## Glossário Rápido — Termos do Andar Técnico

- **Core Banking:** O sistema central que mantém contas, saldos e movimentações. É o 'banco de dados de verdade' do banco.
- **Ledger (Razão):** Registro contábil de todas as movimentações. Cada linha é um lançamento; nunca se apaga, só se estorna.
- **Dupla Entrada (Double-Entry):** Princípio contábil: todo débito tem um crédito correspondente. A soma sempre é zero. Inventado em 1494 por Luca Pacioli.
- **Idempotência:** Propriedade de uma operação que pode ser executada múltiplas vezes com o mesmo resultado. Em dinheiro: processar a mesma transferência duas vezes não pode debitar duas vezes.
- **Liquidação (Settlement):** O momento em que o dinheiro de fato muda de dono no sistema do banco central (BACEN). Antes disso é só promessa.
- **Conciliação (Reconciliation):** Processo de comparar dois registros independentes para garantir que estão de acordo. Se divergem, há um problema.
- **HSM (Hardware Security Module):** Dispositivo físico dedicado a operações criptográficas. As chaves nunca saem do hardware. Obrigatório para operações com cartão e assinatura de transações.
- **Boletador:** Motor que gera e registra boletos bancários no sistema do banco e na CIP/BACEN.

## O Ledger de Dupla Entrada: o Git do Dinheiro

Imagine o Git: você nunca apaga um commit, só adiciona novos. O histórico é imutável e auditável. O ledger bancário funciona exatamente assim — e por razões que vão muito além da preferência técnica.

A contabilidade de dupla entrada diz que toda movimentação de dinheiro tem **dois lados**: um débito e um crédito. Quando você transfere R$ 100 da sua conta para a de outra pessoa, o sistema registra: débito na sua conta (saldo diminui) e crédito na conta do destinatário (saldo aumenta). A soma algébrica é sempre zero. Isso não é uma regra do banco — é um princípio contábil de 500 anos que garante que dinheiro não some nem apareça do nada.

Do ponto de vista de engenharia, isso mapeia diretamente para **Event Sourcing** (Martin Fowler): o estado atual (saldo) não é armazenado diretamente — ele é *derivado* da sequência de eventos imutáveis (lançamentos). Você pode recalcular o saldo de qualquer conta em qualquer ponto no tempo simplesmente replaying os eventos até aquela data. Isso tem consequências profundas: auditoria é trivial, rollback é um estorno (novo evento, não deleção), e inconsistências ficam visíveis porque a soma dos lados nunca fecha.

Para um dev vindo de CRUD: esqueça o `UPDATE saldo = saldo - 100`. No ledger você faz `INSERT INTO lancamentos (conta, tipo, valor, idempotency_key, timestamp)`. O saldo é uma view, não uma coluna.

## Arquitetura de Core Banking: os Motores e suas Responsabilidades

Visão de capacidades de um banco digital moderno. Cada 'motor' é um domínio com responsabilidade única. As setas mostram dependências e fluxo de dados principais.

### 🏦 Canais / Channels

- App / Internet Banking (frontend)
- API Gateway + Auth (mTLS) (edge)

### ⚙️ Motores de Negócio / Business Engines

- Motor de Contas Cadastro + KYC ref (compute)
- Motor de Limites PIX, TED, cartão (compute)
- Motor de Crédito Score + concessão (compute)
- Boletador Geração + registro CIP (compute)
- Motor de Pagamentos Orquestração PIX/TED (compute)

### 📒 Ledger Central / Central Ledger

- Ledger Service Dupla entrada, imutável (compute)
- Ledger DB (append-only, ACID) (data)
- Motor de Liquidação SPB / STR / SPI (compute)
- Conciliação Comparação bilateral (compute)

### 📨 Mensageria / Messaging

- Event Bus (Kafka / MSK) (messaging)
- Dead Letter Queue Reprocessamento seguro (messaging)

### 🔐 Segurança / Security

- HSM Chaves nunca saem (security)
- Audit Log Imutável, WORM (storage)

### 🏛️ Reguladores / Regulators

- BACEN / STR / SPI Liquidação final (external)
- CIP Registro boletos (external)

### Fluxos

- app -> api_gw: HTTPS/mTLS
- api_gw -> payments: requisição
- api_gw -> accounts: requisição
- payments -> limits: valida limite
- payments -> ledger_svc: lançamento
- ledger_svc -> ledger_db: INSERT (append)
- ledger_svc -> event_bus: evento publicado
- event_bus -> settlement: aciona liquidação
- event_bus -> reconciliation: aciona conciliação
- event_bus -> dlq: falha → DLQ
- settlement -> bacen: mensagem SPB
- boleto -> cip: registro
- payments -> hsm: assina transação
- ledger_svc -> audit_log: log imutável
- credit -> ledger_svc: desembolso

## Os Motores: Cada Domínio tem uma Responsabilidade Única

Um banco não é um monolito com uma tabela de saldo. É um conjunto de **motores especializados**, cada um com responsabilidade clara e fronteiras bem definidas — o que um arquiteto de software reconheceria como Domain-Driven Design aplicado a décadas de regulação.

**Motor de Contas**: mantém o cadastro de clientes e contas. Não mexe em saldo. Pensa nele como o serviço de `users` + `accounts` do seu sistema, mas com obrigação legal de KYC (Know Your Customer — verificação de identidade exigida pelo BACEN).

**Motor de Limites**: antes de qualquer transação ser processada, o limite é consultado e reservado. Funciona como um semáforo: se não há limite disponível, a transação nem chega ao ledger. Isso evita race conditions de saldo negativo sem precisar de lock na tabela principal.

**Motor de Crédito**: avalia score, concede crédito e, quando aprovado, instrui o ledger a fazer o desembolso. É o único motor que pode criar dinheiro na conta do cliente sem que ele tenha depositado antes — daí a importância da sua auditabilidade.

**Boletador**: gera o boleto, calcula o código de barras, registra na CIP (Câmara Interbancária de Pagamentos) e monitora o pagamento. Quando o boleto é pago em outro banco, a CIP notifica o boletador, que instrui o ledger.

**Motor de Liquidação**: traduz a intenção interna ('transferir R$ 100 para fulano') em mensagens para o BACEN (STR para TED, SPI para PIX). É a ponte entre o mundo interno do banco e o sistema financeiro nacional.

## Idempotência: o Problema Central em Sistemas de Dinheiro

Em qualquer sistema distribuído, falhas parciais acontecem: a rede cai depois que você enviou a requisição mas antes de receber a resposta. No seu serviço de e-mail, isso significa reenviar o e-mail — chato, mas inofensivo. Em dinheiro, significa **debitar duas vezes**.

Idempotência é a propriedade que garante: não importa quantas vezes você processe a mesma operação, o efeito é o mesmo que processar uma vez. A implementação canônica é simples: cada transação carrega um `idempotency_key` único (gerado pelo cliente, geralmente um UUID). Antes de processar, o ledger verifica: 'já vi essa chave?' Se sim, retorna o resultado anterior sem reprocessar. Se não, processa e persiste a chave junto com o resultado.

Isso parece trivial até você pensar em filas de eventos. Quando você usa Kafka (ou AWS MSK), a semântica padrão é **at-least-once delivery**: a mensagem pode ser entregue mais de uma vez, especialmente em reprocessamento após falha. Se o seu consumer não for idempotente, você tem um bug que só aparece sob pressão — exatamente o cenário do incidente Coinbase/AWS MSK de 2021, onde uma partição Kafka ficou indisponível e o reprocessamento causou inconsistências contábeis.

A regra de ouro: **nunca confie que uma mensagem chegou exatamente uma vez**. Projete todos os consumers financeiros como idempotentes. O `idempotency_key` deve ser persistido no mesmo banco, na mesma transação ACID que o lançamento contábil — não em cache separado.

## Consistência: o que muda quando o ativo é dinheiro
| Critério | Dimensão | E-commerce / SaaS típico | Sistema bancário | Por quê a diferença importa |
| --- | --- | --- | --- | --- |
| Consistência de dados | Eventual consistency aceitável | Consistência forte (ACID) no ledger | Saldo desatualizado por 200ms pode causar duplo débito | — |
| Idempotência | Boa prática, raramente crítica | Obrigatória em todos os consumers | Reprocessamento sem idempotência = prejuízo real | — |
| Rollback de dados | DELETE ou UPDATE são aceitáveis | Apenas estorno (novo lançamento inverso) | Auditoria regulatória exige rastreabilidade completa | — |
| Disponibilidade vs Consistência (CAP) | Prefere disponibilidade (AP) | Prefere consistência (CP) no core | Banco indisponível é ruim; banco inconsistente é catastrófico | — |
| Criptografia de chaves | Software KMS geralmente suficiente | HSM físico obrigatório (PCI-DSS, BACEN) | Chaves de transação nunca podem ser extraídas por software | — |
| Auditoria | Logs úteis, mas não mandatórios por lei | Audit log WORM, retenção mínima 5 anos (BACEN) | Fiscalização do BACEN pode exigir reconstituição de qualquer transação | — |

## Fluxo de Liquidação PIX com Idempotência e Conciliação

Fluxo end-to-end de uma transferência PIX: do app do usuário até a liquidação no BACEN (SPI) e conciliação. Destaque para os pontos de idempotência e tratamento de falha.

### 📱 Iniciação / Initiation

- Usuário App móvel (user)
- API Gateway mTLS + rate limit (edge)

### ⚙️ Processamento / Processing

- PIX Service orquestrador (compute)
- Idempotency Store idempotency_key → result (data)
- Motor de Limites reserva + validação (compute)
- Ledger Service Débito + Crédito interno (compute)

### 📨 Eventos / Events

- Event Bus (Kafka / MSK) (messaging)
- DLQ Reprocessamento c/ idempotência (messaging)

### 🏛️ Liquidação / Settlement

- Settlement Engine formata msg SPI (compute)
- SPI / BACEN Liquidação final (external)
- Conciliação compara extrato SPI × ledger (compute)
- Alerta Divergência time financeiro (compute)

### 🔐 Segurança / Security

- HSM assina msg SPI (security)
- Audit Log WORM S3 Object Lock (storage)

### Fluxos

- user_pix -> gw_pix: POST /pix {idempotency_key}
- gw_pix -> pix_svc: requisição autenticada
- pix_svc -> idem_store: 1. já processou?
- idem_store -> pix_svc: HIT → retorna cached
- pix_svc -> limit_check: 2. valida e reserva limite
- pix_svc -> ledger_pix: 3. lançamento ACID
- ledger_pix -> idem_store: persiste key (mesma tx)
- ledger_pix -> kafka_pix: 4. publica TransactionCreated
- kafka_pix -> settle_svc: consome evento
- kafka_pix -> dlq_pix: falha → DLQ
- dlq_pix -> settle_svc: reprocessa (idempotente)
- settle_svc -> hsm_pix: 5. assina mensagem
- settle_svc -> spi: 6. envia ao SPI
- spi -> recon_svc: 7. extrato SPI (T+0)
- ledger_pix -> recon_svc: extrato interno
- recon_svc -> alert: divergência detectada
- ledger_pix -> worm_log: log imutável
- settle_svc -> worm_log: log liquidação

## Resiliência e Segurança: quando um Bug Custa Dinheiro de Verdade

Em sistemas bancários, a tríade clássica de engenharia — disponibilidade, consistência, tolerância a partição (CAP) — tem um peso diferente. Um banco prefere ficar **indisponível** a ficar **inconsistente**. Isso não é dogma: é regulação. O BACEN pode multar um banco por saldo incorreto muito mais severamente do que por uma janela de manutenção.

O incidente da Coinbase com AWS MSK (2021) é um caso didático: uma partição Kafka ficou indisponível, o sistema fez reprocessamento automático dos eventos, e consumers não-idempotentes geraram lançamentos duplicados. O problema não foi o Kafka — foi a ausência de idempotência nos consumers. A lição: **infraestrutura resiliente não substitui design idempotente**.

Para segurança, o conceito central é o **HSM (Hardware Security Module)**. Pense nele como um cofre físico que faz cálculos criptográficos internamente: você envia os dados, ele retorna o resultado assinado, mas as chaves privadas nunca saem do hardware. Isso é exigido pelo PCI-DSS para operações com cartão e pelo BACEN para assinatura de mensagens no SPB. AWS CloudHSM e Azure Dedicated HSM são opções de nuvem que mantêm essa garantia.

Auditabilidade é a outra face da moeda: todo lançamento, toda decisão de crédito, toda alteração de limite deve ser registrada em um **audit log imutável** (WORM — Write Once Read Many). Na AWS, S3 Object Lock com Compliance Mode implementa isso. O BACEN exige retenção mínima de 5 anos para a maioria dos registros transacionais.

## Descendo o Elevador: da Estratégia ao Código

Gregor Hohpe descreve o arquiteto como alguém que transita entre o andar executivo (estratégia, regulação, produto) e o andar técnico (código, infraestrutura, operações) — o 'Architecture Elevator'. Esta série inteira foi essa viagem.

A **Parte 1** subiu ao andar executivo: o que é um banco, como o BACEN regula, o que é o SPB. A **Parte 2** parou no andar de produto: os rails de pagamento, como PIX, TED e boleto funcionam do ponto de vista do usuário e do negócio. Esta **Parte 3** desceu até o subsolo técnico: o ledger, os motores, idempotência, HSM.

O insight que conecta os três andares: **cada decisão de negócio tem um custo técnico, e cada escolha técnica tem uma consequência de negócio**. O BACEN exige auditabilidade por 5 anos (negócio) → você precisa de WORM storage (técnico). PIX é liquidação em tempo real (negócio) → você precisa de consumers idempotentes e conciliação automática (técnico). Crédito é criação de dinheiro (negócio) → o motor de crédito precisa de consistência forte e trilha de auditoria (técnico).

Para um dev ou arquiteto entrando nesse domínio: o maior erro é tratar o sistema bancário como 'só mais um microsserviço com dinheiro'. As restrições são diferentes, as consequências de falha são diferentes, e o modelo mental precisa mudar antes do código.

## Por onde começar: checklist mental para o arquiteto

- Aprenda dupla entrada antes de tocar em código: entenda débito, crédito e por que a soma é sempre zero
- Trate idempotência como requisito funcional, não como otimização: toda operação financeira precisa de idempotency_key
- Nunca use UPDATE em saldo: use INSERT em ledger e derive o saldo como agregação
- Projete consumers de eventos como idempotentes: at-least-once delivery é a realidade do Kafka
- Consistência forte no core, eventual consistency apenas nas projeções (relatórios, dashboards)
- Entenda o que é liquidação vs autorização: autorizar não é liquidar; o dinheiro só muda de dono no BACEN

> **Perspectiva do Arquiteto: o que ninguém te conta na entrevista:** Quando entrei no mercado financeiro vindo de sistemas de alta escala em outros setores, o maior choque não foi a complexidade técnica — foi a mudança de mentalidade sobre falha. Em e-commerce, uma falha de consistência é um bug a corrigir. Em banco, é um incidente regulatório com potencial de multa, notificação ao BACEN e, em casos extremos, intervenção. Isso muda tudo: o apetite por risco, o processo de deploy, a forma de fazer testes, a obsessão com idempotência.

Minha recomendação para quem está fazendo essa transição: antes de qualquer linha de código, passe tempo com o time de contabilidade e com o time de compliance. Entenda o que é um lançamento contábil, o que é uma divergência de conciliação, o que o BACEN exige em termos de rastreabilidade. Esse contexto vai fazer você tomar decisões de arquitetura completamente diferentes — e muito melhores.

O segundo conselho: não subestime o legado. A maioria dos bancos tem sistemas core com décadas de operação. Seu trabalho frequentemente não é substituí-los, mas criar uma camada de abstração que permita inovar nas bordas sem tocar no núcleo. O Architecture Elevator de Hohpe é literal aqui: você vai precisar traduzir entre o COBOL do mainframe e o Kafka do novo sistema, e essa tradução tem que ser idempotente.

## Veredicto: o que leva para casa

Um banco, visto por dentro, é um sistema de eventos imutáveis com garantias de consistência forte, idempotência obrigatória e auditabilidade regulatória — não um CRUD com saldo. O ledger de dupla entrada não é uma curiosidade histórica: é o invariante central que garante que dinheiro não some nem aparece do nada, e que mapeia diretamente para Event Sourcing. Os motores (contas, limites, crédito, boletador, liquidação, conciliação) são domínios com responsabilidade única; entender suas fronteiras é o primeiro passo para desenhar ou evoluir um core banking. Idempotência não é otimização — é o contrato que permite reprocessamento seguro em um mundo de at-least-once delivery. E resiliência aqui significa preferir indisponibilidade a inconsistência, porque o custo regulatório de um saldo errado é ordens de magnitude maior que o custo de um timeout. Se você absorveu esses cinco princípios, você já pensa como um arquiteto de sistemas financeiros — o resto é aprender os detalhes de cada rail e cada regulação, que as Partes 1 e 2 desta série cobrem.

## Referências

- [Gregor Hohpe — The Software Architect Elevator](https://architectelevator.com/book/)
- [Martin Fowler — Event Sourcing Pattern](https://martinfowler.com/eaaDev/EventSourcing.html)
- [BACEN — Estabilidade Financeira e Regulação](https://www.bcb.gov.br/estabilidadefinanceira)
- [AWS — Building a Modern Core Banking Platform](https://aws.amazon.com/financial-services/banking/)
- [AWS CloudHSM — Hardware Security Module](https://aws.amazon.com/cloudhsm/)
- [Amazon S3 Object Lock — WORM Storage](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html)
- [Martin Fowler — Accounting Patterns](https://martinfowler.com/ap2/index.html)

## Fontes do caso

- [Gregor Hohpe — The Software Architect Elevator](https://architectelevator.com/book/)
- [Martin Fowler — Patterns: Event Sourcing / Ledger](https://martinfowler.com/eaaDev/EventSourcing.html)
- [BACEN — Estabilidade financeira e regulação](https://www.bcb.gov.br/estabilidadefinanceira)
- [AWS — Building a modern core banking platform](https://aws.amazon.com/financial-services/banking/)
