Pular para o conteúdo

Design clássico · Sênior

Sistema de pagamentos

Idempotência ponta a ponta, conciliação e consistência entre ledger e PSP.

19 min de leitura · Conteúdo revisado em 23 de outubro de 2026

Resposta curta

Idempotência ponta a ponta, conciliação e consistência entre ledger e PSP. O exercício clássico pede que um comerciante consiga iniciar uma cobrança de um valor específico contra um cliente e acompanhar o estado dela (pendente, sucesso ou falha). O pagamento em si é feito por um provedor externo, o PSP: o cliente informa os dados no site do comerciante, que…

01 · CONTEXTO

Mover dinheiro não tolera meio-termo

O exercício clássico pede que um comerciante consiga iniciar uma cobrança de um valor específico contra um cliente e acompanhar o estado dela (pendente, sucesso ou falha). O pagamento em si é feito por um provedor externo, o PSP: o cliente informa os dados no site do comerciante, que os repassa ao PSP, e o PSP devolve o resultado.

A carga de referência do exercício é de cerca de 10.000 transações por segundo no pico, e o requisito que mais pesa no desenho não é a vazão: é garantir durabilidade e auditabilidade, sem perder dado de transação nem em caso de falha. Esse requisito explica as três decisões do caso: operações idempotentes para tolerar repetição, filas para absorver a natureza assíncrona do PSP e um registro contábil imutável para provar o que aconteceu.

02 · IDEMPOTÊNCIA

Repetir a chamada sem cobrar duas vezes

O perigo central é descrito sem rodeios por quem opera um PSP: chamar a operação duas vezes por acidente deixaria o cliente cobrado em dobro. E a repetição é inevitável, porque a chamada pode ter sucesso e a conexão cair antes de o servidor avisar o cliente. A saída é tornar a operação segura para repetir, com uma chave de idempotência gerada pelo cliente.

O mecanismo: o cliente reenvia a mesma requisição com o mesmo identificador, o servidor correlaciona esse identificador com o estado da requisição do seu lado e, se a operação já tinha dado certo, responde com o resultado em cache. Na API do Stripe o resultado da primeira execução é guardado e devolvido nas repetições, inclusive quando era um erro de servidor; além disso, a camada de idempotência compara os parâmetros recebidos com os da requisição original e recusa a chamada se forem diferentes, o que evita o uso indevido da mesma chave.

  1. O cliente gera uma chave única para esta intenção de pagamento e a envia junto com a requisição de cobrança.

    Diagrama da arquitetura: Cobrança com chave de idempotência
    CLClientechave
    NWAPI do comerciante
    CPServiço de pagamentos
    DBBanco de pagamentos
    CPPSP (externo)
  2. O serviço de pagamentos consulta o banco: se a chave já existe, devolve o resultado guardado; se não, registra a chave antes de falar com o PSP.

    Diagrama da arquitetura: Cobrança com chave de idempotência
    CLCliente
    NWAPI do comerciante
    CPServiço de pagamentos
    DBBanco de pagamentosregistra a chave
    CPPSP (externo)
  3. Só então o serviço pede a cobrança ao PSP, repassando a mesma chave para que a repetição também seja segura nesse trecho.

    Diagrama da arquitetura: Cobrança com chave de idempotência
    CLCliente
    NWAPI do comerciante
    CPServiço de pagamentos
    DBBanco de pagamentos
    CPPSP (externo)
  4. O PSP executa a cobrança, mas a conexão cai antes de a resposta chegar: o serviço não sabe se o dinheiro andou.

    Diagrama da arquitetura: Cobrança com chave de idempotência
    CLCliente
    NWAPI do comerciante
    CPServiço de pagamentos
    DBBanco de pagamentos
    CPPSP (externo)resposta perdida
  5. O cliente repete com a mesma chave. O serviço reconhece a chave, confere o estado e devolve o resultado, sem criar uma segunda cobrança.

    Diagrama da arquitetura: Cobrança com chave de idempotência
    CLCliente
    NWAPI do comerciante
    CPServiço de pagamentos
    DBBanco de pagamentosresultado salvo
    CPPSP (externo)

Repetir sem critério também tem custo: se todos os clientes tentam de novo ao mesmo tempo, o servidor recebe uma onda sincronizada. Por isso a espera entre tentativas cresce de forma exponencial e recebe um componente aleatório (jitter) por cliente, para espalhar as repetições no tempo.

03 · ASSÍNCRONO

O PSP avisa depois: webhooks e fila

Parte do desfecho de um pagamento chega depois, por eventos: o banco do cliente confirma a cobrança, o cliente contesta, um pagamento recorrente acontece. O comerciante recebe esses eventos num endpoint de webhook e precisa tratá-los como um fluxo assíncrono, não como a continuação da chamada original.

A documentação do Stripe é explícita sobre três propriedades dessa entrega. Primeiro, o mesmo evento pode chegar mais de uma vez, e a defesa é registrar os identificadores de evento já processados. Segundo, a ordem de entrega não é garantida, então o tratamento não pode depender de uma sequência; quando falta um objeto, a saída é consultá-lo na API. Terceiro, o endpoint deve responder com sucesso rapidamente, antes de qualquer lógica pesada, e processar os eventos por meio de uma fila assíncrona, a uma taxa que o sistema aguente. Se a entrega falha, o PSP tenta de novo por vários dias com espera crescente.

  1. O PSP envia um evento (pagamento confirmado, falho ou contestado) ao endpoint de webhook do comerciante.

    Diagrama da arquitetura: Eventos do PSP: webhook, fila e ledger
    CPPSP (externo)evento
    NWEndpoint de webhook
    QFila de eventos
    CPConsumidor de eventos
    DBBanco de pagamentos e ledger
    NWMonitoramento
  2. O endpoint valida a origem do evento, coloca-o na fila e responde com sucesso de imediato, sem tocar no banco.

    Diagrama da arquitetura: Eventos do PSP: webhook, fila e ledger
    CPPSP (externo)
    NWEndpoint de webhook
    QFila de eventosnovo
    CPConsumidor de eventos
    DBBanco de pagamentos e ledger
    NWMonitoramento
  3. A fila desacopla o ritmo do PSP do ritmo do nosso processamento: um pico de eventos vira espera, não queda.

    Diagrama da arquitetura: Eventos do PSP: webhook, fila e ledger
    CPPSP (externo)
    NWEndpoint de webhook
    QFila de eventosabsorve picos
    CPConsumidor de eventos
    DBBanco de pagamentos e ledger
    NWMonitoramento
  4. O consumidor confere se o identificador do evento já foi processado; se sim, descarta, se não, aplica o efeito e grava o identificador na mesma transação.

    Diagrama da arquitetura: Eventos do PSP: webhook, fila e ledger
    CPPSP (externo)
    NWEndpoint de webhook
    QFila de eventos
    CPConsumidor de eventos
    DBBanco de pagamentos e ledgerid do evento
    NWMonitoramento
  5. Se o consumidor cai no meio, a mensagem não foi confirmada e continua na fila; ao voltar, ele reprocessa, e a checagem do identificador impede o efeito duplicado.

    Diagrama da arquitetura: Eventos do PSP: webhook, fila e ledger
    CPPSP (externo)
    NWEndpoint de webhook
    QFila de eventos
    CPConsumidor de eventoscaiu
    DBBanco de pagamentos e ledger
    NWMonitoramento

04 · LEDGER

O registro que ninguém reescreve

O estado do pagamento (pendente, sucesso, falha) responde "onde está esta cobrança". Já a pergunta "para onde foi o dinheiro" pede outro registro: um ledger, uma sequência de lançamentos que só cresce. O Stripe descreve o seu como um log imutável de eventos e sistema de registro de todos os dados financeiros: o que já foi publicado não pode ser apagado nem alterado, e é essa imutabilidade que permite auditar e reproduzir qualquer dado a qualquer momento. Um erro é corrigido com um novo lançamento compensatório, nunca editando o antigo.

A contabilidade por partidas dobradas dá ao ledger uma regra verificável: todo lançamento tira de uma conta e põe em outra pelo mesmo valor, então o conjunto sempre fecha. O mesmo texto do Stripe usa essa construção como base para uma prova matemática de correção. Gravar o lançamento junto com a mudança de estado numa única transação do banco mantém as duas visões coerentes dentro do nosso sistema; entre nós e o PSP não há transação compartilhada, e é aí que entra a conciliação.

05 · CONCILIAÇÃO

Provar que os dois lados concordam

Mesmo com idempotência e fila, dois sistemas independentes podem divergir: um evento perdido, um lançamento atrasado, um estorno que só um dos lados viu. A conciliação é a checagem periódica que compara o nosso ledger com os registros do PSP e levanta toda diferença. O Stripe descreve a mesma ideia internamente: mede qual fração do ledger está devidamente zerada no estado estável e usa verificações explícitas de completude de dados para se proteger de casos em que algo deixa de ser registrado.

  1. O job de conciliação lê os lançamentos do período no nosso ledger.

    Diagrama da arquitetura: Conciliação entre ledger e PSP
    DBLedgernossa visão
    DBRegistros do PSP
    CPJob de conciliação
    NWAlertas
  2. Em paralelo, ele carrega os registros que o PSP publica sobre o mesmo período.

    Diagrama da arquitetura: Conciliação entre ledger e PSP
    DBLedger
    DBRegistros do PSPvisão do PSP
    CPJob de conciliação
    NWAlertas
  3. Cada pagamento é casado pelos identificadores; o que existe só de um lado, ou tem valor diferente, vira uma divergência.

    Diagrama da arquitetura: Conciliação entre ledger e PSP
    DBLedger
    DBRegistros do PSP
    CPJob de conciliaçãocompara
    NWAlertas
  4. As divergências vão para monitoramento e viram trabalho de correção por lançamento compensatório, nunca por edição do histórico.

    Diagrama da arquitetura: Conciliação entre ledger e PSP
    DBLedger
    DBRegistros do PSP
    CPJob de conciliação
    NWAlertasdivergência
MecanismoProblema que resolveO que ainda deixa passar
Chave de idempotênciaCobrança duplicada por repetição do clienteDivergência causada por evento perdido do PSP
Fila com deduplicação por id de eventoEventos duplicados, fora de ordem ou em rajadaEvento que nunca chegou
Ledger imutávelPerda de rastro e edição indevida do históricoDiferença entre o nosso registro e o do PSP
Conciliação periódicaDivergências entre os dois lados, achadas depoisPrejuízo no intervalo até a próxima rodada

Perguntas frequentes

O que é Sistema de pagamentos?

Idempotência ponta a ponta, conciliação e consistência entre ledger e PSP.

O que o design de Sistema de pagamentos cobre?

Ele está organizado nestas seções: Mover dinheiro não tolera meio-termo, Repetir a chamada sem cobrar duas vezes, O PSP avisa depois: webhooks e fila, O registro que ninguém reescreve e Provar que os dois lados concordam.

Quanto tempo leva Sistema de pagamentos e qual é o nível?

Leva cerca de 19 minutos para ler e tem nível Sênior.

Agora projete você mesmo

Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.