Webhook Stripe: configurare e testare

Webhook Stripe: configurare e testare

I webhook Stripe sono il meccanismo asincrono con cui Stripe notifica al tuo backend eventi rilevanti come pagamenti riusciti, dispute, subscription rinnovate. Configurarli correttamente è essenziale per qualunque integrazione robusta.

Come funzionano i webhook

Quando un'evento si verifica (es. payment_intent.succeeded), Stripe invia una POST HTTP a un'endpoint che hai definito, con il payload JSON dell'evento. Il tuo server deve rispondere con un 2xx entro 10 secondi. Se fallisci, Stripe ritenta con backoff esponenziale per 3 giorni. La firma HMAC nell'header Stripe-Signature garantisce l'autenticità.

Verifica firma e idempotency

La verifica firma è obbligatoria per sicurezza: usa la libreria ufficiale (stripe.webhooks.constructEvent in Node, Webhook::constructEvent in PHP). Implementa anche idempotency: lo stesso evento può arrivare più volte (in caso di retry), quindi salva l'event_id e ignora duplicati.

Eventi più' importanti da gestire

Gli eventi più' usati sono: payment_intent.succeeded (pagamento completato, attiva fulfillment), payment_intent.payment_failed (carta rifiutata, notifica cliente), charge.refunded (rimborso completato), invoice.paid e invoice.payment_failed (subscription), customer.subscription.deleted (cancellazione sub), customer.subscription.updated (cambio piano), charge.dispute.created (chargeback in arrivo). Per Connect: account.updated (status onboarding venditore), capability.updated (capability attivata/disattivata), payout.paid (versamento conto). Iscriviti solo agli eventi che servono per ridurre rumore e processing time.

Local development con Stripe CLI

Stripe CLI (scaricabile da stripe.com/docs/stripe-cli) è il tool di sviluppo essenziale: 'stripe listen --forward-to localhost:4242/webhook' crea un tunnel sicuro che inoltra eventi reali Stripe Test al tuo dev environment. Genera anche un signing secret temporaneo per testare la verifica firma. 'stripe trigger payment_intent.succeeded' genera eventi di test on-demand per scenari specifici. 'stripe logs tail' mostra in tempo reale tutte le richieste API. Indispensabile durante sviluppo per non dover deployare a staging per ogni test webhook.

Sicurezza endpoint e WAF

Endpoint webhook ricevono traffico pubblico da IP Stripe (range pubblico documentato). Protezioni essenziali: 1) HTTPS obbligatorio con TLS 1.2+; 2) Verifica firma sempre (sopra ogni altra cosa); 3) Rate limiting per evitare DoS (anche se Stripe non spammer); 4) WAF rules per bloccare User-Agent non-Stripe; 5) Mutual TLS opzionale (Stripe espone client cert su richiesta). NON whitelistare per IP - Stripe range cambia, e potresti perdere webhook critici. Logging completo: ogni webhook ricevuto con timestamp, event_id, processing time, result (success/error).

Webhook signing rotation e key management

Periodically (consigliato annualmente o dopo incident), ruota il signing secret webhook: in Dashboard -> Webhooks -> select endpoint -> 'Roll secret'. Stripe espone il secret nuovo immediatamente ma continua a firmare con il vecchio per 24h (grace period). Configura il tuo endpoint per accettare entrambi i secret durante questo periodo, poi deprecate vecchio. Best practice: store secret in secret manager (AWS Secrets Manager, HashiCorp Vault), mai in repo Git. Ogni microservizio ha access via IAM role, no shared secret tra team.

Esempi di payload e schema

Esempi payload webhook tipici: payment_intent.succeeded contiene event.data.object con id (pi_X), amount, currency, customer, payment_method, status='succeeded'. invoice.paid contiene invoice id (in_X), subscription, customer, total, status='paid', period_start/end. customer.subscription.deleted contiene subscription id, customer, canceled_at, cancellation_details (reason, comment). Schema completo in docs.stripe.com/api/events/types. Per ogni evento, considera quali campi dell'event.data.object sono rilevanti per la tua business logic. Stripe garantisce backward compatibility: aggiungono campi nuovi senza rimuovere esistenti. Pattern: salva l'intero payload JSON nel tuo DB per debug e replay, in aggiunta al business state derivato.

Webhook in produzione: deployment pattern

Pattern deployment webhook production-grade: 1) Endpoint dietro load balancer per HA (multiple replica); 2) HTTPS con TLS termination su LB; 3) Auth via Stripe signature verification (no API key, no IP whitelist); 4) Database persistente per idempotency (Redis fine per cache, RDBMS per audit trail); 5) Queue per processing async (RabbitMQ, AWS SQS, Google Pub/Sub); 6) Monitoring (DataDog, NewRelic) con alert su error rate; 7) Runbook documentato per incident response. Disaster recovery test trimestrale: simula webhook flood, simula Stripe API down, simula database lock. Ready-to-deploy Stripe webhook handler reduces 80% production incident relate.

Procedura passo-passo

  1. Vai in Dashboard -> Developers -> Webhooks -> Add endpoint.
  2. Inserisci l'URL HTTPS pubblico del tuo endpoint (es. https://app.tuosito.it/webhooks/stripe).
  3. Seleziona gli eventi da ricevere (es. payment_intent.succeeded, invoice.paid, customer.subscription.deleted).
  4. Copia il signing secret (whsec_...) e salvalo nelle env variable del server.
  5. Implementa l'handler verificando la firma con stripe.webhooks.constructEvent.
  6. Aggiungi idempotency salvando event.id nel DB ed escludendo duplicati.
  7. Testa con Stripe CLI: 'stripe listen --forward-to localhost:4242/webhooks'.
  8. Monitora la dashboard webhook per failed delivery e debug.

Errori comuni e come risolverli

  • Firma non verificata: endpoint vulnerabile a forge; usa sempre constructEvent.
  • Timeout >10 secondi: Stripe considera fallito e ritenta; sposta logica pesante in queue async.
  • Doppia elaborazione: senza idempotency rischi double-charge; controlla event.id.
  • Endpoint non HTTPS: Stripe rifiuta endpoint HTTP in produzione.

Domande frequenti

D: Quanti retry fa Stripe?
R: Backoff esponenziale per 3 giorni: ~70 tentativi totali.

D: Posso testare webhook in localhost?
R: Sì, usa Stripe CLI con stripe listen che fa forward da Stripe a localhost.

D: Devo configurare un'endpoint per Sandbox e uno per Live?
R: Sì, sono ambienti separati con webhook distinti.

D: Cosa succede se non gestisco un'evento?
R: Niente, gli eventi non gestiti sono ignorati; ricevi solo quelli a cui ti iscrivi.

Hai bisogno di aiuto?

Se vuoi integrare Stripe con il team di G Tech Group, scrivici tramite il modulo di contatto.

Hai trovato utile quest'articolo?