Monitorare il churn con i webhook di Lemon Squeezy
Quali eventi webhook di Lemon Squeezy segnano una disdetta, una scadenza, un pagamento fallito o un recupero, e come farne un registro di churn affidabile.
Se vendi abbonamenti tramite Lemon Squeezy, ogni segnale di churn che ti serve passa dai suoi webhook: disdette, scadenze, rinnovi falliti, recuperi, pause. La parte difficile non è riceverli. È decidere quale evento significa cosa, e registrarli in modo che i tuoi numeri sul churn tornino ancora sei mesi dopo.
Questa guida associa gli eventi degli abbonamenti di Lemon Squeezy ai concetti di churn, mostra come salvarli ed elenca i dettagli di consegna che mandano in crisi gli handler ingenui. Si attiene alla documentazione di Lemon Squeezy: i tipi di evento webhook, la pagina sulle richieste webhook, la firma delle richieste, la guida alla sincronizzazione con i webhook e il riferimento dell’oggetto Subscription (tutti consultati a novembre 2026).
Gli eventi degli abbonamenti
La pagina dei tipi di evento di Lemon Squeezy elenca questi eventi degli abbonamenti:
| Evento | Cosa lo fa partire secondo Lemon Squeezy | Significato per il churn |
|---|---|---|
subscription_created |
Un nuovo abbonamento | Cliente nuovo (o di ritorno) |
subscription_updated |
Qualsiasi modifica dopo il pagamento iniziale | Da usare per sincronizzare lo stato |
subscription_cancelled |
Annullato dal cliente o dal proprietario dello store; entra in un periodo di tolleranza fino alla prossima data di fatturazione | Churn programmato, non ancora avvenuto |
subscription_resumed |
Ripreso dopo essere stato annullato | Churn programmato annullato |
subscription_expired |
Terminato dopo essere stato annullato, o una volta completato il dunning per gli abbonamenti past_due |
Churn avvenuto |
subscription_paused |
Incasso dei pagamenti in pausa | Non è churn; seguilo a parte |
subscription_unpaused |
Incasso dei pagamenti ripreso | Fine della pausa |
subscription_payment_success |
Un pagamento riuscito | Ricavi |
subscription_payment_failed |
Un pagamento di rinnovo è fallito | Rischio di churn involontario |
subscription_payment_recovered |
Un pagamento riuscito dopo uno fallito | Rischio risolto |
subscription_payment_refunded |
Un pagamento rimborsato | Rettifica dei ricavi |
Due di questi meritano uno sguardo più attento.
Annullato non significa perso
subscription_cancelled parte quando il cliente clicca su disdici, ma l’abbonamento continua fino a ends_at. Durante quel periodo di tolleranza può essere ripreso, il che invia subscription_resumed. Se conti il churn su subscription_cancelled, ogni abbonamento ripreso diventa un falso churn, e la tua data di churn è sbagliata fino a un intero periodo di fatturazione.
Conta il churn su subscription_expired. Tieni subscription_cancelled come metrica anticipatrice separata: “disdette programmate questo mese”.
Un evento, due tipi di churn
subscription_expired parte per due motivi molto diversi: un cliente che ha disdetto ed è arrivato a ends_at (churn volontario), e un abbonamento che è passato per il dunning dopo pagamenti falliti senza essere recuperato (churn involontario). Il nome dell’evento non ti dice quale.
Per separarli, guarda cosa è venuto prima. Se il tuo registro ha un subscription_cancelled per quell’abbonamento e nessun subscription_resumed dopo, è volontario. Se ha eventi subscription_payment_failed e nessun recupero, è involontario. Puoi anche leggere lo stato dell’abbonamento quando ricevi l’evento: il riferimento dell’oggetto Subscription mostra un booleano cancelled accanto a status.
Churn volontario e involontario richiedono rimedi diversi, quindi questa separazione è la cosa più utile che il tuo registro possa darti.
Come sono fatte le richieste
Secondo la pagina sulle richieste webhook:
- Ogni richiesta è un
POSTcon un corpo JSON:API: la risorsa legata all’evento (un abbonamento per la maggior parte degli eventi degli abbonamenti, una subscription invoice per gli eventi di pagamento). - L’header
X-Event-Namecontiene il nome dell’evento. - L’header
X-Signaturecontiene la firma. - Il tuo endpoint deve restituire
200. Qualsiasi altro stato viene ritentato fino ad altre tre volte con backoff esponenziale (la documentazione cita come esempio 5, 25 e 125 secondi), dopodiché la richiesta è considerata fallita.
La pagina delle impostazioni dei webhook nella tua dashboard registra le consegne recenti con i loro payload e ti permette di reinviarle. È la tua rete di sicurezza se il tuo endpoint era giù.
Verificare la firma
La firma delle richieste spiega lo schema: imposti un segreto di firma quando crei il webhook (da 6 a 40 caratteri), e Lemon Squeezy calcola con esso un digest esadecimale HMAC-SHA256 del corpo della richiesta. Ricalcola il digest sul corpo grezzo, non su un JSON riserializzato, e confrontalo con una funzione a tempo costante. Rifiuta tutto ciò che non corrisponde.
Gli eventi di pagamento contengono fatture
Gli eventi subscription_payment_* contengono un oggetto subscription invoice, non l’abbonamento. Fa riferimento all’abbonamento, quindi salva quell’ID e, se ti serve lo stato, recupera l’abbonamento.
Costruire un registro di churn passo per passo
L’obiettivo è una tabella in sola aggiunta di ciò che è successo a ogni abbonamento, da cui ogni metrica di churn possa essere ricalcolata.
- Crea un solo endpoint per tutti gli eventi degli abbonamenti. Iscrivilo agli eventi della tabella qui sopra. La guida alla sincronizzazione di Lemon Squeezy precisa che
subscription_updatedcopre ogni modifica, quindi puoi iscriverti solo a quello se ti interessa solo lo stato. Per monitorare il churn, gli eventi specifici sono più facili da interpretare, quindi prendili entrambi. - Verifica, poi salva il payload grezzo. Scrivi il nome dell’evento, l’ID dell’abbonamento, l’ID del cliente, il timestamp e il JSON grezzo prima di fare qualsiasi altra cosa.
- Deduplica. Tentativi e reinvii manuali fanno sì che lo stesso evento possa arrivare due volte. La documentazione che abbiamo usato non descrive un ID univoco dell’evento nella richiesta, quindi costruisci una tua chiave dal nome dell’evento, dall’ID della risorsa e dall’
updated_atdella risorsa, e ignora le ripetizioni. - Rispondi in fretta. Restituisci
200appena l’evento è salvato, ed elaboralo in un job in background. Un handler lento che va in timeout fa partire i tentativi. - Deriva, non sovrascrivere. Mantieni il registro immutabile. Calcola da esso lo “stato attuale” e i conteggi del churn, così un bug nella tua logica si può correggere rielaborando il registro.
- Riconcilia ogni tanto. Una volta a settimana, elenca gli abbonamenti tramite l’API e confronta i loro stati con ciò che dice il tuo registro. Qualsiasi discrepanza indica un evento perso.
Le metriche che puoi calcolare
Con quel registro, queste sono immediate:
- Tasso di churn clienti di un mese: abbonamenti scaduti nel mese, divisi per gli abbonamenti attivi all’inizio del mese.
- Quota volontaria e involontaria: scadenze suddivise con la regola qui sopra.
- Disdette programmate: eventi
subscription_cancellednel mese, un indicatore anticipatore del churn del mese successivo. - Salvataggi nel periodo di tolleranza: abbonamenti annullati seguiti da
subscription_resumed. - Tasso di recupero dei pagamenti: abbonamenti con un
subscription_payment_recovereddivisi per abbonamenti con unsubscription_payment_failednello stesso periodo. - Quota in pausa: abbonamenti attualmente
paused. Riportali a parte; non sono né paganti attivi né persi.
Definisci ogni metrica una volta, per iscritto, e mantieni stabile la definizione. Un tasso di churn è utile solo confrontato con se stesso nel tempo.
Testare prima di fidarsi
La modalità test di Lemon Squeezy può simulare eventi webhook per gli abbonamenti. Fai passare ogni ciclo di vita: crea, annulla, riprendi, annulla di nuovo e lascia scadere; un pagamento fallito che viene recuperato; uno che non lo è. Verifica che registro e metriche corrispondano a ciò che ti aspetti a ogni passaggio.
Farlo con NoChurn
Lemon Squeezy resta la fonte di verità per abbonamenti e pagamenti; NoChurn non li modifica. NoChurn si iscrive ai tuoi webhook Lemon Squeezy, salva e deduplica gli eventi e separa per te il churn volontario da quello involontario. In più aggiunge un churn score da 0 a 100 per cliente, i dati personalizzati che invii via API e le risposte del flusso di disdetta che spiegano perché le persone se ne vanno. Le contestazioni, che Lemon Squeezy gestisce come merchant of record, vengono mostrate in sola lettura. Vedi NoChurn + Lemon Squeezy.