ouro.capital
||
gateways

Webhooks de Pagamento: A Arquitetura Definitiva para Não Perder Eventos (e Dinheiro)

2024-03-20·9 min read·Matheus Feijão

Ponto-chave

Para escalar operações financeiras, o consumo de webhooks exige filas assíncronas, chaves de idempotência e validação de assinaturas HMAC. Depender de requisições síncronas resulta em perda de eventos, falhas no Pix e prejuízos diretos no e-commerce.

Sexta-feira de Black Friday. O relógio marca 20h. O Banco Central registra picos absurdos no Sistema de Pagamentos Instantâneos (SPI). Apenas para dar dimensão, o Pix já ultrapassou a marca de 227 milhões de transações em um único dia. Um cliente entra no seu e-commerce, coloca um notebook de R$ 8.000 no carrinho e escaneia o QR Code. O dinheiro sai da conta dele no Nubank em um segundo. O gateway de pagamento — seja Mercado Pago, Stone ou Pagar.me — processa a liquidação e dispara um webhook (um POST HTTP) para o seu servidor avisando: 'Pagamento aprovado'.

Mas o seu servidor está sobrecarregado. A requisição baté na sua API, fica pendurada por 15 segundos e cai por timeout. O gateway registra falha na entrega. O seu sistema nunca muda o status do pedido para 'Pago'. O cliente não recebe o e-mail de confirmação, entra em pânico, aciona o Procon no Twitter e entope o seu canal de atendimento. O dinheiro está na sua conta, mas a sua operação quebrou.

Aqui na Ouro Capital, observamos esse exato cenário destruir margens de lucro de dezenas de varejistas e empresas SaaS todos os anos. A integração de pagamentos modernos exige uma arquitetura orientada a eventos impecável. Se você opera qualquer negócio digital hoje, preste atenção aqui: tratar webhooks como meras requisições HTTP triviais é o caminho mais rápido para o fracasso operacional.

A anatomia de uma falha milionária

Antes do Pix, o mercado brasileiro vivia na era da conciliação em lote (D+1, D+30). Os sistemas rodavam rotinas noturnas (os famosos jobs de conciliação) lendo arquivos de remessa e retorno da rede bancária. A latência era medida em dias. A tolerância a falhas sistêmicas era alta, porque sempre havia o arquivo do dia seguinte para corrigir discrepâncias.

Agora em 2024, a banda toca em tempo real. A Resolução BCB nº 1 de 2020 determinou a liquidação instantânea. O webhook tornou-se o sistema nervoso central das finanças digitais. Ele é uma API reversa: em vez de você perguntar ao gateway 'Este boleto foi pago?' (técnica conhecida como polling, que destrói recursos de infraestrutura), o gateway empurra a informação para você assim que o evento ocorre.

O erro mais comum que vemos nas integrações de fintechs iniciantes e e-commerces é o processamento síncrono. O desenvolvedor cria um endpoint /api/webhooks/pagamentos, recebe o payload e, dentro da mesma requisição, tenta: buscar o pedido no banco de dados, atualizar o status, disparar um e-mail via SendGrid, emitir a nota fiscal na prefeitura e atualizar o ERP.

Tudo isso leva tempo. Se a prefeitura demorar 10 segundos para responder, a conexão com o gateway de pagamento vai expirar. O gateway vai assumir que você não recebeu o aviso. O resultado? Ele vai tentar mandar de novo. E de novo. Até o seu banco de dados travar por excesso de concorrência ou você gerar duas notas fiscais para o mesmo pedido. Precisamos quebrar esse ciclo.

A Tríade da Resiliência em Webhooks

Para construir um motor de pagamentos blindado, você precisa dominar três conceitos inegociáveis. Não são 'boas práticas' opcionais. São regras de sobrevivência.

1. Idempotência: O escudo contra a dupla cobrança

A rede de internet não é confiável. Pacotes se perdem, roteadores falham, instabilidades da AWS ocorrem. Por causa disso, gateways de pagamento robustos operam sob a premissa de at-least-once delivery (entrega pelo menos uma vez). Isso significa que, na dúvida se você recebeu o webhook, a Stone, o Asaas ou a Iugu vão enviar o evento novamente.

Se o seu sistema não for idempotente, receber o mesmo evento de 'pagamento aprovado' duas vezes significa que você pode creditar o saldo do cliente duas vezes na plataforma. Um desastre.

Idempotência é a propriedade de uma operação matemática ou na ciência da computação que pode ser aplicada várias vezes sem alterar o resultado além da aplicação inicial. Na prática, todo webhook traz um identificador único (geralmente no header x-idempotency-key ou um event_id no payload).

O seu banco de dados precisa ter uma tabela dedicada ao registro de eventos já processados. Assim que o webhook bater na sua porta, a primeira ação é um check rápido: 'Já vi este event_id?'. Se a resposta for sim, retorne um 200 OK imediatamente e ignore o payload. Se for não, grave o event_id e siga o fluxo.

2. Políticas de Retry e Exponential Backoff

Quando o seu sistema cai (e ele vai cair), os eventos não podem sumir no limbo. Gateways sérios implementam políticas de retry. Mas como eles fazem isso? Eles não martelam o seu servidor a cada segundo, pois isso configuraria um ataque DDoS acidental.

Eles usam Exponential Backoff. A primeira tentativa falha. A segunda ocorre após 5 minutos. A terceira após 30 minutos. A quarta após 2 horas. A quinta após 12 horas.

Você precisa conhecer a política de retry do seu adquirente. O Stripe, por exemplo, tenta por até 3 dias. O Mercado Pago tem sua própria janela de horas. Se você tiver um tempo de inatividade prolongado e a janela do gateway expirar, esses eventos estarão perdidos para sempre via webhook.

Para evitar buracos na conciliação, mantenha uma rotina de fallback (aí sim, usando polling) que roda uma vez por dia, buscando ativamente na API do gateway todos os pagamentos das últimas 24 horas para cruzar com o seu banco de dados e encontrar os 'órfãos' que os webhooks não entregaram.

3. Ordem de Entrega: O caos cronológico

Sistemas distribuídos não garantem a ordem de entrega. Isso muda o jogo. Imagine uma assinatura SaaS. O cliente cancela o plano e, cinco minutos depois, se arrepende e reativa.

O gateway gerou dois eventos: subscription.canceled (gerado às 10:00) e subscription.reactivated (gerado às 10:05).

Por flutuações de rede, o evento de reativação chega ao seu servidor às 10:06. O evento de cancelamento ficou travado numa fila do gateway e só chega às 10:07. Se o seu sistema processar cegamente o que chega por último, você vai cancelar a assinatura de um cliente que já havia reativado o serviço.

Para resolver isso, jamais confie na ordem de chegada do HTTP. Confie no timestamp do evento gerado na origem (o gateway). O seu banco de dados deve ter uma trava lógica: 'Só atualizo o status da assinatura se o timestamp deste evento for MAIOR que o timestamp da última atualização que gravei'. Se um evento antigo chegar atrasado, ele é descartado silenciosamente.

Segurança: Validando a origem do dinheiro

Se o seu endpoint de webhooks é público (e precisa ser, para o gateway acessá-lo), qualquer pessoa no mundo pode enviar um POST para sua-api.com/webhooks/pagamentos com um payload falso dizendo {"status": "paid", "amount": 10000}. Se você não validar a origem, você acaba de dar R$ 10.000 em créditos de graça para um fraudador.

Aqui na Ouro Capital, cruzamos com startups que tentam esconder a URL do webhook como medida de segurança (o famoso 'security through obscurity'). Isso não funciona. Hackers descobrem essas URLs rápidamente.

A única forma profissional de proteger webhooks financeiros é através de assinaturas HMAC (Hash-based Message Authentication Code). Funciona assim:

  1. Você e o gateway compartilham um segredo (uma string complexa gerada no painel deles).
  2. Quando o gateway envia o webhook, ele pega o corpo da requisição, usa o segredo para gerar um hash criptográfico e coloca esse hash no header da requisição (ex: x-signature).
  3. Quando o seu servidor recebe o POST, ele pega o corpo bruto da requisição, usa o mesmo segredo guardado no seu cofre de chaves (KMS/Vault) e gera o próprio hash.
  4. Se o hash que você gerou for idêntico ao hash do header, a mensagem é autêntica e não foi adulterada no meio do caminho. Se for diferente, retorne 401 Unauthorized.

Players como Pagar.me, Vindi e Stripe exigem e documentam exaustivamente essa prática. Ignorar a verificação de assinatura é negligência grave de engenharia financeira.

A Arquitetura Assíncrona Recomendada

Como juntamos todas essas peças sem que o servidor exploda na Black Friday? Separando o recebimento do processamento. A arquitetura padrão-ouro do mercado financeiro hoje baseia-se em filas de mensagens (Message Brokers).

Em vez de processar a regra de negócio no momento em que o webhook baté na sua API, você faz o seguinte:

  1. O gateway envia o POST.
  2. O seu endpoint /webhooks recebe a requisição.
  3. O seu endpoint verifica a assinatura HMAC (segurança).
  4. O seu endpoint joga o payload bruto (JSON) direto em uma fila assíncrona — como AWS SQS, RabbitMQ ou Apache Kafka.
  5. O seu endpoint retorna 200 OK para o gateway imediatamente. Tempo total da requisição: 50 milissegundos.

Agora, o gateway está feliz e sabe que você recebeu o aviso. Nos bastidores da sua infraestrutura, os Workers (serviços rodando em background) vão consumir essa fila no ritmo que o seu banco de dados aguentar.

Se entrarem 10.000 webhooks por segundo, a fila absorve o choque. Os seus workers vão processar 500 por segundo, levando 20 segundos para esvaziar a fila, mas nenhum evento será perdido. Se o seu banco de dados cair, as mensagens continuam seguras na fila (ou vão para uma Dead-Letter Queue - DLQ, para análise manual posterior).

Implicações práticas para o seu negócio

Se você é um CTO, Tech Lead ou Product Manager lidando com dinheiro, a responsabilidade pela resiliência é sua. O ecossistema brasileiro não perdoa amadorismo. O Banco Central tem apertado o cerco sobre a qualidade técnica dos participantes diretos e indiretos do Pix e do Open Finance.

Na prática, audite a sua integração hoje mesmo. Vá aos logs da sua aplicação. Procure por timeouts nos endpoints de webhooks. Verifique se o seu time de atendimento está recebendo chamados de 'paguei e não liberou' ou 'cobrou duas vezes'. Esses são os sintomas claros de que a sua arquitetura síncrona está vazando dinheiro.

Implementar uma fila SQS básica na AWS custa centavos e leva poucas horas para um desenvolvedor sênior. O custo de não fazer isso é perder clientes que nunca mais voltarão a comprar na sua loja porque tiveram uma experiência de pagamento frustrante.

O futuro orientado a eventos

O mercado financeiro já abraçou a arquitetura orientada a eventos. Com a maturidade do Open Finance no Brasil, não estaremos mais falando apenas de webhooks de pagamento aprovado. Estaremos lidando com webhooks de consentimento revogado, atualização de limites de crédito, portabilidade de chaves Pix e iniciação de pagamentos (ITP).

O volume de eventos vai multiplicar por dez nos próximos três anos. Quem construir a fundação correta agora — focada em idempotência, filas assíncronas e validação criptográfica — terá uma vantagem competitiva brutal. Sistemas confiáveis não são aqueles que nunca falham, mas aqueles que sabem exatamente o que fazer quando a falha acontece. E no mundo dos pagamentos, o silêncio de um webhook perdido é o som do dinheiro indo para o seu concorrente.

Perguntas Frequentes

MF

Matheus Feijão

CEO & Fundador — ouro.capital

Especialista em fintech e criptoativos desde 2002. CEO da ouro.capital.