MÉTRICAS DE CHURNLEMON SQUEEZY

Acompanhar o churn com os webhooks do Lemon Squeezy

Que eventos de webhook do Lemon Squeezy marcam um cancelamento, uma expiração, um pagamento falhado ou uma recuperação, e como criar um registo de churn.

Publicado a 6 min de leitura

Se vende subscrições através do Lemon Squeezy, todos os sinais de churn de que precisa passam pelos seus webhooks: cancelamentos, expirações, renovações falhadas, recuperações, pausas. A parte difícil não é recebê-los. É decidir que evento significa o quê, e registá-los de forma a que os seus números de churn ainda batam certo daqui a seis meses.

Este guia faz corresponder os eventos de subscrição do Lemon Squeezy aos conceitos de churn, mostra como guardá-los e lista os detalhes de entrega que fazem falhar os handlers ingénuos. Limita-se à documentação do próprio Lemon Squeezy: os tipos de eventos de webhook, a página de pedidos de webhook, a assinatura dos pedidos, o guia de sincronização com webhooks e a referência do objeto Subscription (todos consultados em novembro de 2026).

Os eventos de subscrição

A página de tipos de eventos do Lemon Squeezy lista estes eventos de subscrição:

Evento O que o desencadeia segundo o Lemon Squeezy Significado para o churn
subscription_created Uma nova subscrição Cliente novo (ou que regressa)
subscription_updated Qualquer alteração depois do pagamento inicial Usar para sincronizar o estado
subscription_cancelled Cancelada pelo cliente ou pelo dono da loja; entra num período de tolerância até à próxima data de faturação Churn agendado, ainda não aconteceu
subscription_resumed Retomada depois de cancelada Churn agendado revertido
subscription_expired Terminada depois de cancelada, ou quando o dunning foi concluído para subscrições past_due O churn aconteceu
subscription_paused Cobrança em pausa Não é churn; acompanhar à parte
subscription_unpaused Cobrança retomada Fim da pausa
subscription_payment_success Um pagamento bem-sucedido Receita
subscription_payment_failed Um pagamento de renovação falhou Risco de churn involuntário
subscription_payment_recovered Um pagamento bem-sucedido depois de um falhado Risco resolvido
subscription_payment_refunded Um pagamento reembolsado Ajuste de receita

Dois destes merecem um olhar mais atento.

Cancelado não é perdido

subscription_cancelled dispara quando o cliente clica em cancelar, mas a subscrição continua a funcionar até ends_at. Durante esse período de tolerância pode ser retomada, o que envia subscription_resumed. Se contar o churn em subscription_cancelled, cada subscrição retomada passa a ser um falso churn, e a sua data de churn fica desfasada até um período de faturação inteiro.

Conte o churn em subscription_expired. Mantenha subscription_cancelled como uma métrica antecipada à parte: “cancelamentos agendados este mês”.

Um evento, dois tipos de churn

subscription_expired dispara por duas razões muito diferentes: um cliente que cancelou e chegou a ends_at (churn voluntário), e uma subscrição que passou pelo dunning depois de pagamentos falhados sem recuperar (churn involuntário). O nome do evento não lhe diz qual.

Para os separar, veja o que veio antes. Se o seu registo tem um subscription_cancelled para essa subscrição e nenhum subscription_resumed depois, é voluntário. Se tem eventos subscription_payment_failed e nenhuma recuperação, é involuntário. Também pode ler o estado da subscrição quando recebe o evento: a referência do objeto Subscription mostra um booleano cancelled ao lado de status.

O churn voluntário e o involuntário pedem soluções diferentes, por isso esta separação é a coisa mais útil que o seu registo lhe pode dar.

Como são os pedidos

Segundo a página de pedidos de webhook:

  • Cada pedido é um POST com um corpo JSON:API: o recurso relacionado com o evento (uma subscrição para a maioria dos eventos de subscrição, uma subscription invoice para os eventos de pagamento).
  • O cabeçalho X-Event-Name traz o nome do evento.
  • O cabeçalho X-Signature traz a assinatura.
  • O seu endpoint tem de devolver 200. Qualquer outro estado é tentado de novo até mais três vezes com espera exponencial (a documentação dá 5, 25 e 125 segundos como exemplo), depois do que o pedido é considerado falhado.

A página de definições de webhooks no seu painel regista as entregas recentes com os seus payloads e permite reenviá-las. É a sua rede de segurança se o seu endpoint esteve em baixo.

Verificar a assinatura

A assinatura dos pedidos explica o esquema: define um segredo de assinatura ao criar o webhook (6 a 40 caracteres), e o Lemon Squeezy calcula com ele um digest HMAC-SHA256 em hexadecimal do corpo do pedido. Recalcule o digest sobre o corpo bruto, não sobre JSON reserializado, e compare com uma função de tempo constante. Rejeite tudo o que não corresponder.

Os eventos de pagamento trazem faturas

Os eventos subscription_payment_* trazem um objeto subscription invoice, não a subscrição. Este referencia a subscrição, por isso guarde esse ID e, se precisar do estado, obtenha a subscrição.

Construir um registo de churn passo a passo

O objetivo é uma tabela só de acrescento com o que aconteceu a cada subscrição, a partir da qual se pode recalcular qualquer métrica de churn.

  1. Crie um endpoint para todos os eventos de subscrição. Subscreva-o aos eventos da tabela acima. O guia de sincronização do Lemon Squeezy nota que subscription_updated cobre todas as alterações, por isso pode subscrever só esse se apenas quiser o estado. Para acompanhar o churn, os eventos específicos são mais fáceis de interpretar, por isso fique com ambos.
  2. Verifique e depois guarde o payload bruto. Escreva o nome do evento, o ID da subscrição, o ID do cliente, a data e hora e o JSON bruto antes de fazer qualquer outra coisa.
  3. Elimine duplicados. As novas tentativas e os reenvios manuais fazem com que o mesmo evento possa chegar duas vezes. A documentação que usámos não descreve um ID de evento único no pedido, por isso construa a sua própria chave a partir do nome do evento, do ID do recurso e do updated_at do recurso, e ignore as repetições.
  4. Responda depressa. Devolva 200 assim que o evento está guardado e processe-o numa tarefa em segundo plano. Um handler lento que excede o tempo desencadeia novas tentativas.
  5. Derive, não sobrescreva. Mantenha o registo imutável. Calcule o “estado atual” e as contagens de churn a partir dele, para que um bug na sua lógica possa ser corrigido voltando a reproduzir o registo.
  6. Reconcilie de vez em quando. Uma vez por semana, liste as subscrições através da API e compare os estados com o que o seu registo diz. Qualquer diferença significa um evento perdido.

As métricas que pode calcular

Com esse registo, estas são diretas:

  • Taxa de churn de clientes num mês: subscrições que expiraram durante o mês, divididas pelas subscrições ativas no início do mês.
  • Parte voluntária vs involuntária: expirações separadas pela regra acima.
  • Cancelamentos agendados: eventos subscription_cancelled no mês, um indicador antecipado do churn do mês seguinte.
  • Recuperações no período de tolerância: subscrições canceladas seguidas de subscription_resumed.
  • Taxa de recuperação de pagamentos: subscrições com um subscription_payment_recovered divididas pelas subscrições com um subscription_payment_failed no mesmo período.
  • Parte em pausa: subscrições atualmente paused. Apresente-as à parte; não são pagantes ativos nem churn.

Defina cada métrica uma vez, por escrito, e mantenha a definição estável. Uma taxa de churn só é útil comparada consigo própria ao longo do tempo.

Testar antes de confiar

O modo de teste do Lemon Squeezy pode simular eventos de webhook para subscrições. Passe cada ciclo de vida por ele: criar, cancelar, retomar, cancelar de novo e deixar expirar; um pagamento falhado que recupera; um que não recupera. Verifique que o seu registo e as suas métricas correspondem ao que espera em cada passo.

Fazer isto com a NoChurn

O Lemon Squeezy continua a ser a fonte de verdade para as subscrições e os pagamentos; a NoChurn não os altera. A NoChurn subscreve os seus webhooks do Lemon Squeezy, guarda e elimina duplicados nos eventos, e separa por si o churn voluntário do involuntário. Por cima disso acrescenta um churn score de 0 a 100 por cliente, os dados próprios que envia por API e as respostas do fluxo de cancelamento que explicam porque é que as pessoas saem. As disputas, que o Lemon Squeezy trata enquanto merchant of record, são mostradas só em leitura. Veja NoChurn + Lemon Squeezy.

PROMPT

Read https://www.nochurn.sh/llms.txt,
then follow https://www.nochurn.sh/docs/quickstart/
to add NoChurn to this app. Use a test key
(nc_test_…) until I say we go live.

Pare de perder receita.

  • Grátis até $300 de MRR
  • Sem cartão
  • Pronto em 10 minutos
  • Nunca uma comissão sobre o que recuperamos