Aviso. Este artigo é baseado inteiramente em comunicações públicas da Stripe — seu engineering blog, palestras de conferências, repos open source e estudos de caso externos. Não é um documento de arquitetura oficial Stripe. Modelamos o que sabemos publicamente para ilustrar como um stack complexo pode ser tornado legível com o modelo C4. Quando os detalhes são inferidos em vez de afirmados pela Stripe, dizemos.
Anatomia de um Charge: modelando a Stripe em C4 com Archyl
Uma request POST atinge a Stripe às 3 da manhã Pacific durante a Black Friday. Vinte segundos depois o merchant foi creditado, o banco emissor do cardholder autorizou o débito, os fundos estão na fila para settlement, o servidor do merchant recebeu um webhook assinado, e o motor de risco da Stripe pontuou a transação em menos de 100 milissegundos.
Essa única request, repetida 27 395 vezes por segundo no pico do BFCM 2024, atravessa quatorze sistemas Stripe e pelo menos quatro redes externas antes do frame zero chegar ao dashboard do merchant.
Em 2025, a Stripe processou 1,9 trilhão de dólares através deste stack, sustentando 99,9999% de uptime durante a Black Friday — seis noves, equivalentes a 32 segundos de downtime por ano. Fizeram isso sobre cerca de quinze milhões de linhas de Ruby, type-checked pelo seu próprio sistema de tipos feito em casa.
Como você entende um stack que faz rodar os pagamentos por cartão de meio internet? Como a Netflix, você não entende — não de uma vez. É exatamente o problema que o modelo C4 foi inventado para resolver.
Neste post seguimos uma única ação de usuário — uma chamada stripe.PaymentIntents.create() — e a vemos atravessar a arquitetura da Stripe nos quatro níveis C4. Não cobriremos cada produto. Vamos rastrear um charge, escrever os ADRs que explicam as escolhas que encontramos no caminho, e terminar com um mapa das equipes que possuem cada caixa.
Nível 1 — System Context: quinze produtos, um trilhão de dólares

No nível System Context, a Stripe não é "uma API de pagamentos". São quinze sistemas-produto distintos compartilhando uma fundação:
- Payments — o coração histórico: charges, payment intents, refunds, payouts
- Connect — pagamentos multi-parte, marketplaces, plataformas
- Billing — assinaturas, faturas, billing por consumo
- Atlas — incorporação Delaware C-Corp/LLC
- Capital — empréstimos a merchants
- Issuing — criação de cartões virtuais e físicos
- Treasury — banking-as-a-service (parceria Goldman Sachs)
- Identity — verificação KYC/KYB
- Tax — sales tax, IVA, GST
- Climate — compensações de carbono por transação
- Radar — detecção de fraude ML (scoring sub-100ms)
- Sigma — analytics SQL sobre os dados Stripe
- Terminal — hardware POS
- Financial Connections — linking de conta bancária (o Plaid deles)
- Apps Marketplace — apps de terceiros no Dashboard
Em torno: merchants, cardholders, as quatro redes de cartões (Visa, Mastercard, Amex, Discover) mais as regionais (JCB, UnionPay), 100+ métodos de pagamento alternativos (Apple Pay, Klarna, ACH, SEPA, iDEAL...), bancos adquirentes e emissores, parceiros bancários (Goldman Sachs, Evolve, Cross River), autoridades fiscais, provedores de identidade, e AWS como cloud subjacente mono-cloud.
Quinze sistemas, oito categorias de atores externos. Tudo o resto é detalhe.
Esse é o presente do Nível 1: no System Context você não precisa saber que Payments são vinte microsserviços. Você precisa saber que existe, que conversa com card networks, que Connect coordena com Treasury, e que AWS sustenta tudo. O diagrama é um iniciador de conversa, não um inventário.
ADR-001 · Idempotency keys integradas na API desde o dia 1
Status · Accepted (2011, ainda ativo em 2026)
Contexto · Redes não são confiáveis. Um merchant tentando novamente um POST /charges falhado poderia cobrar duas vezes um cliente. A resposta da indústria em 2011 foi "o merchant deveria gerenciar isso" — empurrando complexidade de sistemas distribuídos para cada consumidor de API.
Decisão · Exigir Idempotency-Key em cada chamada API mutante. Armazenar a chave, o hash da request, e a resposta. Em retry, replay da resposta armazenada se a chave coincidir. Lançar como parte first-class da API, não opt-in.
Consequências · O modelo de idempotência da Stripe se tornou o padrão de fato da indústria. O draft IETF de Idempotency-Key é diretamente inspirado nele. Cada usuário da API Stripe, sabendo ou não, beneficia de um contrato que transforma POST /charges em uma operação safely retryable. Vamos dar zoom em como funciona no Nível 3.
Esta é a escolha arquitetural única que mais dá forma à superfície API da Stripe. Sem ela, o modelo C4 teria que expor lógica de retry em cada boundary mutante — vazando complexidade de sistemas distribuídos para cada consumidor.
No Archyl, é assim que um ADR ganha seu lugar: explica por que a boundary parece como parece.
Nível 2 — Container: zoom em Payments core

O stripe.PaymentIntents.create() do merchant pousa na borda de Payments. Vamos abrir a caixa.
Dentro de Payments, fontes públicas revelam pelo menos estes containers:
- Apiori — o API gateway. Originalmente Ruby + Rails, com código de hot-path progressivamente reescrito em Go para latências sub-150 µs na camada de auth e routing.
- Idempotency layer — a cross-cutting concern que se senta na frente de cada endpoint mutante. Backed por PostgreSQL com row-level locking.
- PaymentIntent service — orquestra a state machine:
requires_payment_method→requires_confirmation→requires_action(challenge 3DS) →processing→succeeded(ourequires_capture). - Card Data Vault — ambiente PCI fisicamente isolado, AES-256 at rest, nenhum serviço principal pode descriptografar um PAN. Toda a card data flui por tokenization.
- Radar — scoring de fraude em menos de 100 ms p99. DNN puro desde 2022, arquitetura inspirada em ResNeXt.
- Network connectors — adapters para Visa, Mastercard, Amex, etc. Falam ISO 8583 e protocolos proprietários no fio.
- Webhook delivery service — at-least-once delivery, 16 retries em 3 dias com exponential backoff, signing HMAC-SHA256.
- Ledger — log de eventos imutável, ~5 bilhões de eventos por dia, ~100 entradas de ledger por pagamento. Source of truth para reconciliação, audit e contabilidade.
- DocDB — Database-as-a-Service custom da Stripe, construída em cima de MongoDB. 5 milhões de queries por segundo, 5 000+ collections, 2 000+ shards, petabytes de dados financeiros.
O stack tecnológico neste nível: Ruby com Sorbet types como linguagem dominante (15M linhas), Go nos hot paths, PostgreSQL para concerns relacionais (idempotência, accounts), DocDB para workloads document de alto volume, Apache Kafka para eventos, Apache Pinot para analytics tempo real, Apache Flink para stream processing.
Um charge típico toca Apiori → Idempotency layer → PaymentIntent service → (Vault para tokens) → (Radar para risco em paralelo) → Network connector → Ledger → Webhook fanout. Tudo isso, com retries, instrumentado end-to-end via Veneur e roteado de forma segura através do Smokescreen para qualquer egress externo.
ADR-002 · DocDB — construir em cima de MongoDB ao invés de reescrever
Status · Accepted (~2018, investimento contínuo)
Contexto · Em 2018, o volume de dados da Stripe no MongoDB estava estressando o produto off-the-shelf: migrações de schema em collections de petabytes eram perigosas, sharding era trabalho operacional, e os requirements de uptime 99,999% não deixavam janelas de manutenção. A indústria teria dito "reescrever para um store relacional".
Decisão · Não migrar a camada de dados para outro engine. Em vez disso, construir um Database-as-a-Service custom em cima de MongoDB: um Database Proxy, um Chunk Metadata Service, uma Data Movement Platform que executa o padrão dual-write/backfill/dual-read/cleanup como primitiva managed, e um serviço CDC para eventos de saída.
Consequências · A Stripe obtém o melhor do modelo flexível de MongoDB mais as garantias operacionais de uma plataforma managed: 5M QPS, 99,999% de uptime steady-state, migrações zero-downtime como operação rotineira. A migração "Mongo → DynamoDB" que o boato de internet às vezes alega ter acontecido nunca aconteceu. Eles dobraram a aposta.
Este ADR é um excelente exemplo de arquitetura path-dependent: a resposta certa em 2018 era estender, não substituir.
Nível 3 — Component: dentro da Idempotency layer

De todos os componentes do stack da Stripe, a Idempotency layer é a mais publicamente documentada — o post de 2017 de Brandur Leach continua sendo uma referência canônica para engenheiros de sistemas distribuídos.
Um único POST /charges com uma idempotency key atravessa estes componentes dentro da camada:
- Request hasher — calcula um hash determinístico do payload da request. Se a mesma idempotency key chega com um payload diferente, a API retorna 422 (o cliente cometeu um erro de programação).
- Idempotency key store — uma tabela PostgreSQL com chave em
(account_id, idempotency_key). Incluirequest_hash,response_code,response_body,recovery_point,last_run_at,locked_at. A colunalocked_atimplementa row-level locking para retries concorrentes. - Phase executor — divide a operação em fases atômicas separadas por foreign state mutations. Cada fase é ou puramente local (Postgres-only, transacional com a linha de idempotência) ou um único side-effect externo (tokenize Vault, charge rede, envio webhook).
- Recovery point tracker — persiste a fase atual:
started→ran_charge→wrote_ledger→enqueued_webhook→finished. Em retry, o executor retoma do recovery point. - Job enqueuer — para side-effects assíncronos (emails, webhooks), enqueue um job durável na mesma transação Postgres da atualização do recovery point. Atômico por construção.
- Background runner — drena a fila de jobs com sua própria semântica de retry, exponential backoff, e dead-letter store.
O padrão é brutalmente simples uma vez que você o vê: toda mutação local vive na mesma transação Postgres da atualização da linha de idempotência; toda mutação externa vive entre dois recovery points. Essa forma elimina uma classe inteira de bugs de double-write que assolam sistemas distribuídos construídos sem essa primitiva.
Isso é o que Component-level C4 parece: não "aqui está algum código", mas "aqui está a cadeia de primitivas business-meaningful, cada uma owned, cada uma substituível, cada uma mensurável".
ADR-003 · Sorbet — investir num type checker, não reescrever Ruby
Status · Accepted (~2017, open-sourced em 2019, ainda default)
Contexto · Em 2017, o monolito Ruby + Rails da Stripe tinha crescido além de 10 milhões de linhas. O conselho dominante da indústria para uma fintech desse tamanho era reescrever em uma linguagem tipada — Java, Go, ou Scala. O custo estimado era anos e centenas de engenheiros. A DX de Ruby, enquanto isso, era a vantagem competitiva da Stripe para shippar rápido.
Decisão · Não reescrever. Construir um type checker gradual para Ruby. Levar 18 meses e um time pequeno para shippar um sistema de tipos multithreaded, IDE-grade, que escala a milhões de linhas. Open-source.
Consequências · Sorbet agora type-checa 15 milhões de linhas de Ruby da Stripe com latência incremental sub-segundo. A Stripe nunca pagou a rewrite tax. Pagaram a invent-a-type-checker tax — uma única vez. Sorbet se tornou um projeto open source significativo usado por Coinbase, Shopify, GitHub, e outros.
Em um modelo Archyl, ADRs como esta viajam com a arquitetura. Quando você clica no container Apiori em 2026 e vê "Ruby + Sorbet", você vê também a decisão de 2017 que explica por que não é Java.

Três decisões. Três cards no Archyl, cada uma linkada aos elementos C4 que ela molda — Idempotency keys a cada endpoint mutante, DocDB à camada de dados, Sorbet a cada container Ruby. O diagrama é o presente; os ADRs são o porquê.
Ownership: transformar um modelo em accountability

Um modelo C4 é um artefato estático até você mapear equipes nele.
A Stripe comunica publicamente sobre sua estrutura engineering: um grupo Foundations forte (Infrastructure, Security, Data Platform, Developer Experience), times de produto alinhados a cada sistema maior (Payment Methods, Connect, Capital, Identity, Issuing, Treasury, Climate, Radar), e grupos cross-cutting para ML e observability.
Coloque-os no modelo C4:
- Foundations possui Apiori, Sorbet, Veneur, Smokescreen, a plataforma Kubernetes, DocDB, Card Data Vault — o substrato sobre o qual cada produto constrói
- Payment Methods possui os Network connectors, a state machine PaymentIntent, os serviços por-método (cartões, ACH, SEPA, wallets)
- Connect possui o serviço Account, capability gating, fluxos multi-parte, payouts
- Capital possui a pipeline de decisão de empréstimo e a integração com o histórico Payments do merchant
- Identity possui os workflows KYC/KYB e o compliance gating para onboarding Connect
- Radar (time ML) possui o DNN de fraude, o model serving, as training pipelines
- Issuing & Treasury possuem as integrações bank-partner e o card lifecycle
- Climate possui a integração com o marketplace de offsetting de carbono
Esse mapeamento não é decoração. É o substrato de tudo que vem depois.
Uma vez que um sistema, container ou componente tem uma equipe proprietária, a detecção de drift fica responsável: quando um novo serviço aparece em commits e não está no diagrama, uma equipe específica é interpelada. Quando uma regra de conformidade é violada (um serviço não-Foundations tentando ler do Card Data Vault diretamente, por exemplo), há um nome em uma inbox.
No Archyl, o Ownership Map é o momento em que uma ferramenta de doc vira uma ferramenta de governança.
Drift, conformidade, e o resumo semanal
Um modelo desse tamanho vai derivar. Novos produtos chegam — Climate em 2022, Treasury, expansões Tax, Apps Marketplace. Os stacks mudam — caminhos do Apiori migram para Go, Pinot substitui analytics mais antigo, a strictness do Sorbet sobe.
O Archyl computa um drift score semanal: o gap entre o modelo C4 documentado e o que está atualmente no código. Regras de conformidade adicionam a camada policy — "todo container precisa de uma equipe proprietária", "só serviços Foundations podem ler Card Data Vault", "toda mudança de API pública deve referenciar um ADR de versioning".
Para a Stripe é detecção de drift na escala de quinze milhões de linhas e 27 000 requests por segundo. As regras são as mesmas que para dez serviços.
E o Resumo de Arquitetura de Equipe que lançamos recentemente, num setup tipo Stripe, significaria:
- O resumo de segunda da Foundations cobre Apiori, o Vault, DocDB, a plataforma K8s
- O resumo de Payment Methods cobre Network connectors, o PaymentIntent service, cada integração por-método
- O resumo de Radar cobre o DNN de fraude, as training pipelines, os rollouts de modelo
- Cada resumo scoped ao perímetro próprio de sua equipe
Mesma superfície. Scopes diferentes. Essa é a simetria que C4 + ownership desbloqueiam.
Você não precisa processar um trilhão de dólares
Você não é a Stripe. A maioria das organizações de engenharia não é.
Mas a lição escala também para baixo. A disciplina de separar Context de Container de Component, de escrever o ADR que explica uma decisão path-dependent (construímos em cima de Mongo, type-checamos Ruby ao invés de reescrever), de anexar ownership a cada caixa — essa disciplina é o que impede um stack de cinquenta serviços de parecer quinze milhões de linhas.
C4 + ADRs + Ownership + Drift + Conformidade é o que o Archyl te dá out of the box. O exemplo Stripe é só o maior stress-test plausível do modelo no domínio de sistemas financeiros.
Abra sua própria arquitetura. Esboce quinze produtos (ou três, se você tem três). Pegue o que tem as decisões passadas mais surpreendentes e zoom nos containers dele. Escreva três ADRs explicando o que confundiria um novato. Mapeie uma equipe a cada container.
Você estará à frente de onde a maioria das organizações de engenharia chega em um ano.
Quer modelar sua própria arquitetura em C4? Comece com Archyl. Leia também por que ADRs e C4 funcionam melhor juntos ou como Architecture Change Requests trazem o rigor da pull request ao seu modelo C4. O case study anterior modelava Netflix em C4 — Anatomia de um Play.