Stripe & Billing

Stripe MRR and Churn in Node: Subscription Metrics

Stripe revenue metrics are easier to trust when Node stores the raw event once, projects subscriptions into a current snapshot, and keeps paid invoice revenue separate from MRR.

Key takeaways for Stripe MRR and churn analytics

  • Stripe Docs says webhook endpoints can listen for asynchronous events, including recurring payment success and subscription payment collection. [1]
  • Stripe's event type catalog includes subscription lifecycle events such as customer.subscription.created, customer.subscription.updated, and customer.subscription.deleted. [2]
  • The Stripe Subscription object includes status and subscription items, which are the core inputs for an active subscription snapshot. [3]
  • The Stripe Invoice object includes fields such as amount_paid, currency, status, and invoice lines, so paid revenue should be modeled separately from MRR. [4]
  • The Stripe Refund object includes amount, currency, charge, payment intent, and status fields, so refund events need their own revenue adjustment path. [5]

MRR should be a projection, not a webhook side effect

Bottom line: Store Stripe events idempotently, update a subscription-state table, and compute MRR and churn from that table instead of mutating dashboard totals inside each webhook branch.

Stripe Docs describes webhook endpoints as a way to receive asynchronous events, including recurring payment success and subscription payment collection. [1]

That event stream is a source of facts, not the dashboard itself. A reliable Node implementation records each event ID once, keeps the payload for replay, and then derives analytics from normalized subscription and invoice rows.

The Node webhook should write an immutable event ledger first

Start with one table keyed by Stripe event ID. Store event type, object ID, created time, processing status, and a JSON copy of the payload your app actually handled.

Stripe's event type catalog lists subscription lifecycle events including customer.subscription.created, customer.subscription.updated, and customer.subscription.deleted. [2]

Use those events to maintain subscription state. Do not increment or decrement global MRR counters directly in the request handler; duplicate delivery, retries, or backfills can otherwise distort the metric.

Clean verdict: The event ledger makes replay, debugging, and duplicate suppression the same problem instead of three separate fixes.

MRR comes from active subscription items and recurring intervals

The Stripe Subscription object includes status and subscription items. [3]

In Node, project each relevant subscription into an analytics row: customer ID, subscription ID, status, currency, price ID, quantity, recurring interval, unit amount, current period, and last event ID.

Then calculate current MRR from active recurring subscriptions at read time or in a scheduled snapshot job. Normalize yearly prices to one-twelfth of annual recurring revenue only after you have checked the price interval and currency.

Want this as a drop-in kit? Stripe MRR Analytics Kit packages webhook verification, subscription syncing, MRR, ARR, churn, paid invoice summaries, refunds, tests, and a Node demo server.

Churn needs subscription status plus refund adjustments

Use subscription lifecycle events to mark canceled or ended subscriptions in your analytics table, then calculate churn over a defined cohort window. The formula is your business choice, but the event inputs should be stable and replayable.

The Stripe Refund object includes amount, currency, charge, payment intent, and status fields. [5]

Model refunds as revenue adjustments instead of churn by default. A refund can be a support credit, duplicate charge fix, or partial reversal; a canceled subscription is the stronger signal that a customer left recurring revenue.

Avoid verdict: Do not let a single webhook branch decide both subscription churn and net revenue without writing the underlying event and object state first.

This article is informational and is not a substitute for a security, billing, tax, or legal review of your own product.

CI Tripwire has not commissioned independent expert review of this article. Read more about the organization byline at contributors and the source posture at sourcing.

Corrections can be routed through the corrections note. Sources: 5 entries, Stripe documentation, last reviewed 2026-06-09.

Sources

  1. Stripe Docs, Receive Stripe events in your webhook endpoint.
  2. Stripe API Reference, Event types.
  3. Stripe API Reference, The Subscription object.
  4. Stripe API Reference, The Invoice object.
  5. Stripe API Reference, The Refund object.