Skip to content
FunzionalitàPrezziAffiliatiBlogAiutoChi siamoContatti
Inizia oraAccedi
Torna al Blog
guides2026-08-295 min di lettura

Idempotenza Webhook: Quando Stripe Spara Lo Stesso Evento di Commissione Tre Volte

La consegna at-least-once di Stripe significa ~0,3% di eventi duplicati in produzione. Come il pattern claim di stripe_webhook_events di thMenu gestisce i duplicati — race condition inclusa.

th

thMenu Team

thmenu.com

In 14 mesi abbiamo loggato ogni webhook Stripe su thMenu: 312 su 100.000 eventi sono arrivati con lo stesso event_id due o tre volte. È la promessa "at-least-once delivery" di Stripe in numeri concreti — senza idempotenza, tre duplicati nel libro commissioni.

Perché Lo Stesso Evento Arriva Tre Volte

Se Stripe non riceve risposta 2xx entro ~10 secondi, ritenta. Timeout TCP, cold start lambda, fallimenti DNS transitori, anche processamento riuscito seguito da caduta connessione — tutto innesca retry.

Tre scenari frequenti: cold start Cloudflare Workers >10s, transazione D1 batch committata ma connessione interrotta, o click manuale "resend" nel dashboard Stripe.

Il Pattern INSERT-Claim

La difesa di thMenu è la tabella stripe_webhook_events con event_id PRIMARY KEY. Prima azione: INSERT. Errore unique constraint 23505 = duplicato — 200 OK no-op.

Critico: il claim deve precedere la logica di business per evitare race condition.

Race Condition: Eventi Fuori Ordine

Incidente reale: customer.subscription.updated è arrivato 800ms prima di checkout.session.completed. UPDATE ha influito 0 righe. Fix: rollback del claim, ritorno 503, Stripe ritenta.

FAQ

Verificare firma prima o dopo il claim? Prima. Verify è economico, scrittura DB costosa.

Quanto conservare le righe di idempotenza? Stripe garantisce 30 giorni; noi teniamo 90 giorni.

Stripe ritenta all'infinito? No, massimo 3 giorni.

Ti è stato utile? Condividilo.