Skip to content
FuncionalidadesPreçosAfiliadosBlogAjudaSobre nósContato
ComeçarEntrar
Voltar ao Blog
guides2026-08-295 min de leitura

Idempotência de Webhook: Quando o Stripe Dispara o Mesmo Evento de Comissão Três Vezes

A entrega at-least-once do Stripe implica ~0,3% de eventos duplicados em produção. Como o padrão claim de stripe_webhook_events do thMenu lida com duplicados — race condition incluída.

th

thMenu Team

thmenu.com

Por 14 meses registramos cada webhook do Stripe no thMenu: 312 de 100.000 eventos chegaram com o mesmo event_id duas ou três vezes. É a promessa "at-least-once delivery" do Stripe em números concretos — sem idempotência, três duplicados no livro de comissões.

Por Que o Mesmo Evento Chega Três Vezes

Se o Stripe não receber resposta 2xx em ~10 segundos, refaz a tentativa. Timeouts TCP, cold starts lambda, falhas DNS transitórias, até processamento bem-sucedido seguido de queda de conexão — tudo dispara retries.

Três cenários frequentes: cold start Cloudflare Workers >10s, transação D1 batch commitada mas conexão cortada, ou clique manual "resend" no dashboard Stripe.

O Padrão INSERT-Claim

A defesa do thMenu é a tabela stripe_webhook_events com event_id PRIMARY KEY. Primeira ação: INSERT. Erro unique constraint 23505 = duplicado — 200 OK no-op.

Crítico: o claim deve preceder a lógica de negócio para evitar race condition.

Race Condition: Eventos Fora de Ordem

Incidente real: customer.subscription.updated chegou 800ms antes de checkout.session.completed. UPDATE afetou 0 linhas. Fix: rollback do claim, retorno 503, Stripe refaz tentativa.

FAQ

Verificar assinatura antes ou depois do claim? Antes. Verify é barato, escrita DB cara.

Quanto tempo manter linhas de idempotência? Stripe garante 30 dias; mantemos 90 dias.

Stripe tenta para sempre? Não, máximo 3 dias.

Achou útil? Compartilhe.