Acompanhar o churn com os webhooks do Polar
Que webhooks do Polar marcam um cancelamento, uma revogação, um pagamento falhado ou uma recuperação, entregas e assinaturas, e um registo de churn.
O Polar já mostra o churn no seu dashboard. Mas se quiser o churn ao lado dos seus próprios dados de produto (utilização, plano, origem da inscrição), precisa dos eventos em bruto na sua própria base de dados. Os webhooks do Polar dão-lhe tudo, desde que os leia da forma que o Polar prevê.
Este guia faz a correspondência entre os eventos de subscrição do Polar e o churn, explica as regras de entrega e de assinatura que fazem tropeçar os handlers e mostra como construir um registo de churn em que possa confiar. Baseia-se na documentação do próprio Polar: webhook events, handling and monitoring deliveries, Managing subscriptions, Recovering failed payments, Analytics e a Get Metrics API (todos consultados em novembro de 2026).
Os eventos de subscrição
A página de webhook events do Polar descreve estes eventos de subscrição:
| Evento | O que o Polar diz que significa | Significado para o churn |
|---|---|---|
subscription.created |
Uma nova subscrição | Cliente novo ou que regressa |
subscription.active |
Uma subscrição fica ativa: uma nova subscrição paga, ou um pagamento recuperado | A pagar |
subscription.updated |
Qualquer alteração à subscrição, incluindo renovações | Usar para sincronizar o estado |
subscription.canceled |
Cancelada; o cliente pode manter o acesso até ao fim do período | Churn agendado |
subscription.uncanceled |
O cliente reverteu um cancelamento pendente | Churn agendado revertido |
subscription.past_due |
Um pagamento de renovação falhou e ainda pode ser recuperado | Risco de churn involuntário |
subscription.revoked |
O acesso termina agora: o período de uma subscrição cancelada terminou, o comerciante revogou-a ou as novas tentativas de pagamento esgotaram-se | Churn consumado |
O Polar indica que subscription.updated dispara a cada alteração e sugere ouvir os eventos específicos quando só precisa de certas transições. Para o churn, os eventos específicos são mais claros.
A ordem dos eventos
O Polar documenta as sequências, e elas contam para a contagem:
- Cancelamento no fim do período:
subscription.updatedesubscription.canceledchegam de imediato. Quando o período termina, seguem-sesubscription.updatedesubscription.revoked. - Revogação imediata:
subscription.updated,subscription.canceledesubscription.revokedchegam juntos.
Assim, cada subscrição perdida produz um subscription.canceled e um subscription.revoked, possivelmente com um mês ou um ano de intervalo. Conte o churn em subscription.revoked. Conte subscription.canceled à parte como “cancelamentos agendados”, um indicador antecipado.
Voluntário vs involuntário
subscription.revoked cobre tanto o churn voluntário (um cancelamento chegou ao fim) como o involuntário (as novas tentativas de pagamento esgotaram-se). Para os distinguir:
- Se a subscrição tinha
cancel_at_period_enddefinido e umsubscription.canceledsem umsubscription.uncanceledposterior, é voluntário. - Se passou por
subscription.past_duesem voltar asubscription.active, é involuntário.
A página sobre pagamentos falhados do Polar explica o caminho involuntário: após uma renovação falhada, a subscrição passa a past_due e o Polar envia um email ao cliente com um link para o Customer Portal. Volta a tentar 4 vezes, 2, 5, 7 e 7 dias após a tentativa anterior (2, 7, 14 e 21 dias após a primeira falha), e revoga se todas as novas tentativas falharem ou se o código de recusa mostrar que o método de pagamento nunca vai funcionar, como lost_card. Pode ser definido um período de tolerância para os benefícios (imediato, 2, 7, 14 ou 21 dias a partir de past_due_at); não altera o calendário de novas tentativas.
Uma incoerência a ter em conta: a documentação de revogação do Polar e a sua referência de webhooks descrevem de forma diferente o estado final após o esgotamento das novas tentativas (canceled numa, unpaid na outra). Não fixe nenhum dos dois no código; baseie-se no evento subscription.revoked e no seu registo do que veio antes.
Os motivos vêm com a subscrição
Quando um cancelamento tem um motivo, está na subscrição: customer_cancellation_reason (valores too_expensive, missing_features, switched_service, unused, customer_service, low_quality, too_complex, other) e customer_cancellation_comment (Managing subscriptions). Guarde-os a partir do payload de subscription.canceled para poder dividir o churn por motivo.
Regras de entrega
Segundo a página de entrega do Polar:
- Novas tentativas: as entregas falhadas são tentadas de novo até 10 vezes com backoff exponencial.
- Timeout: 10 segundos, com a recomendação de responder em 2 segundos e fazer o trabalho pesado numa tarefa em segundo plano, já que o timeout pode ser reduzido.
- Endpoints desativados: após 10 respostas não 2xx consecutivas, o endpoint é desativado e todos os membros da organização recebem um email. A reativação é manual, nas definições do webhook.
- Firewalls: o Cloudflare Bot Fight Mode pode provocar falhas 403; autorize os pedidos do Polar com uma regra WAF.
O terceiro ponto é o que deve prever. Um deploy que estrague o seu handler durante uma tarde pode desativar o endpoint, e nada lhe chega até alguém o voltar a ativar.
Assinaturas
A mesma página explica que o esquema de assinatura depende de quando foi criado o segredo do endpoint. Os segredos criados a 8 de setembro de 2026 (00:00 UTC) ou depois usam o esquema Standard Webhooks e são passados tal como estão a uma biblioteca Standard Webhooks. Os segredos mais antigos usam o HMAC original do Polar, em que a string completa do segredo whsec_ é codificada em base64 antes de ser dada à biblioteca. O campo uses_standard_webhook_signature do endpoint diz-lhe qual se aplica, e os SDKs do Polar a partir da 1.0.0-alpha.19 experimentam os dois.
Na dúvida, verifique esse campo antes de passar horas a depurar um “signature mismatch”.
Testes locais
O polar webhook listen do Polar CLI reencaminha os eventos da sua organização para um URL local e mostra o segredo a usar na verificação (CLI webhooks).
Construir um registo de churn
- Um endpoint, eventos específicos. Subscreva os sete eventos da tabela acima.
- Verifique, guarde, responda. Verifique a assinatura, escreva o payload em bruto com o tipo de evento, o ID da subscrição, o ID do cliente e o timestamp, e devolva um 2xx em poucos segundos.
- Elimine duplicados. As novas tentativas querem dizer repetições. Se as suas entregas trouxerem um ID de mensagem único, use-o; caso contrário, construa uma chave a partir do tipo de evento, do ID da subscrição e do timestamp da última alteração da subscrição, e ignore o que já tiver guardado.
- Processe em segundo plano. Atualize os registos dos clientes a partir do evento guardado, nunca no pedido.
- Mantenha-o só de acrescento. Derive o estado atual e as métricas a partir do registo, para poder reprocessar depois de um bug.
- Vigie o endpoint. Crie alertas para respostas não 2xx antes de se atingir o limite de 10 falhas do Polar.
- Reconcilie. Todas as semanas, liste as subscrições pela API e compare com o seu registo.
Comparar com os números do próprio Polar
Os Analytics do Polar definem as suas métricas com precisão, o que os torna uma boa verificação cruzada:
- Canceled subscriptions: cancelamentos desencadeados pelos clientes no intervalo; a subscrição pode ainda estar ativa.
- Churned subscriptions: subscrições cujo período pago terminou no intervalo.
- Churn rate: subscrições perdidas no intervalo a dividir pelas subscrições ativas no início do intervalo.
- MRR: exclui as subscrições em período experimental; inclui as pausadas e as em atraso até terminarem de facto.
A Get Metrics API devolve campos como active_subscriptions, churned_subscriptions, canceled_subscriptions, churn_rate e monthly_recurring_revenue por intervalo, com uma repartição dos motivos de cancelamento.
Se adotar as mesmas definições no seu próprio registo, a sua taxa de churn e a do Polar devem coincidir para o mesmo período. Quando não coincidem, provavelmente perdeu eventos, muitas vezes porque o endpoint esteve desativado algum tempo.
O que o seu próprio registo acrescenta
Os analytics do Polar respondem a “quanto churn”. O seu registo, cruzado com os seus dados de produto, responde a “o churn de quem e porquê”: churn por origem da inscrição, por ativação, por plano, por motivo de cancelamento, voluntário vs involuntário. É aí que está o trabalho com consequências práticas.
Fazer isto com o NoChurn
O Polar continua a ser a fonte de verdade para as subscrições, os pagamentos e o seu calendário de novas tentativas, e os seus analytics continuam úteis. O NoChurn subscreve os seus webhooks do Polar, guarda os eventos e elimina duplicados, separa o churn voluntário do involuntário e cruza-os com os dados próprios que envia pela API. Acrescenta um score de churn de 0 a 100 por cliente e os motivos recolhidos no seu fluxo de cancelamento. As disputas ficam no Polar enquanto merchant of record e são mostradas em modo só de leitura. Veja NoChurn + Polar.