MerchantFlowMerchantFlow Docs
Dashboard

Subscription Revenue - Recurring Revenue and Churn

Track subscription and recurring revenue in MerchantFlow. See active subscribers, renewals, churn, refunds and refund rate on subscription items, contribution margin on recurring orders, and a projection for the current month.

Subscription Revenue

The subscriptions view reports the recurring side of your store: how many subscribers you have, what renewals brought in, what those renewals actually earned after variable costs, and how many subscribers you lost. Subscription revenue is more predictable and usually higher-margin than one-off revenue, and separating it out stops a good month of renewals from disguising a bad month of acquisition.

Open it from Dashboard → Customers → Subscriptions.

Availability

Three things must all be true:

  1. Plan -- subscription revenue is included on Pro and Plus, not on Starter.
  2. Rollout -- the page is behind the subscription_revenue_beta feature flag, which ships disabled and is turned on for named accounts first. Without it the navigation entry does not appear and the page does not exist for your store -- contact support to ask for access.
  3. Detection -- MerchantFlow has to know which of your products are sold on subscription. See below.

Detection has to be configured

Detection is what makes every other number on the page possible, and it is not automatic in every case. MerchantFlow treats a line item as subscription-eligible when any of these is true:

  • The line was sold on a Shopify selling plan (pre-orders and try-before-you-buy are excluded -- those are deferred one-off purchases, not recurring billing).
  • The order carries a subscription app tag -- the markers written by Recharge and Kaching.
  • The product, variant, or SKU is one you picked manually in settings.

With none of these active the page shows "No subscriptions detected yet" and an Open subscription settings button through to Dashboard → Settings. If you bill through an app that does not use Shopify selling plans, picking your subscription products there is the fix.

A separate empty state, "No renewals in this period", means detection is working but no repeat charge landed in the selected range.

Every figure is an estimate

This is the most important thing to understand about the page, and it is labelled as such in the product.

Every page carries an Estimated badge and this notice: "These figures are estimated from charges that have already happened. MerchantFlow cannot read subscription contracts directly, so a paused subscription, a failed payment being retried, and a cancellation all look the same until a charge is missed."

MerchantFlow infers subscription activity from evidence it can see: Shopify selling-plan policies, customer tags written by subscription apps, and the pattern of repeat charges themselves. Contract-level state would need protected Shopify scopes that MerchantFlow does not request.

In practice that means the figures are good directional numbers and poor legal ones. Use them to steer the business; use your subscription app's own dashboard for anything requiring exactness.

The one exception is refunds, which are exact rather than inferred. See Refunds are the one exact figure on this page below for why.

What the page shows

The five headline cards

CardMeaning
Active Subscribers (est.)Customers with a recent charge and no missed renewal. New and estimated-churn counts for the period sit underneath it
Renewal RevenueRepeat billing only -- subscription signups count as acquisitions, not renewals. The renewal order count sits underneath it
Refunds on RenewalsMoney refunded on renewal orders. The refund rate, as a share of gross renewal revenue, sits underneath it
Renewal Contribution ProfitRevenue less COGS, payment fees, and fulfilment. The contribution margin % sits underneath it
Est. Revenue This MonthCharges expected before month end, from each subscriber's observed billing cadence

Renewal revenue, refunds, and contribution profit are computed as:

Gross renewal revenue       = subtotal, on renewal orders
Refunds on renewals         = amount refunded, on renewal orders
Refund %                    = refunds / gross renewal revenue
Renewal revenue             = gross renewal revenue - refunds
Renewal contribution profit = renewal revenue - COGS - payment fees - fulfilment cost
Contribution margin %       = renewal contribution profit / renewal revenue

A line under the cards spells the first part out -- "Gross X less Y refunded gives Z in renewal revenue" -- because renewal revenue has always been net of refunds without showing you the deduction.

Ad spend is zero on renewals by design -- only the first charge of a subscription is an acquisition and keeps its blended ad-spend share. That is why contribution margin on renewals is usually the most useful figure here: it is what your subscription business is really worth once acquisition is out of the picture, and it tells you whether discounting to win subscribers still pays off over the life of the subscription.

Current-month projection

The Est. Revenue This Month card projects revenue for the current calendar month from the subscribers whose billing cadence MerchantFlow can confirm. When it renders, its subtext names the basis: "Based on N subscribers with a confirmed billing cadence."

The projection is deliberately conservative. Below the evidence floor it shows N/A rather than a zero or a guess, and a line under the cards says why:

  • Not enough confirmed billing history -- the projection appears once at least 3 subscribers have been charged more than once
  • Closed historical period -- the selected range does not end in the current month, so there is nothing to project

A blank projection means "not enough evidence", never "zero expected revenue".

Refunds are the one exact figure on this page

Everything else here is inferred, but the refund amount is not. A renewal order only ever contains subscription items -- an order mixing a subscription with a one-off product is treated as an acquisition, not a renewal -- so the entire refund on a renewal order belongs to your subscription products. Nothing is estimated or apportioned.

Two things to know when you compare it against another report:

  • Refunded shipping is included in the amount but not in the base. The amount is all the cash you returned, including any shipping or duties. The base it is measured against is product revenue before shipping. If you routinely refund shipping, the percentage reads slightly high. This is deliberate: it keeps Gross - Refunds equal to the Renewal Revenue card exactly.
  • Signup refunds are not counted. A customer who subscribes and immediately refunds their very first charge does not appear here, because that charge is an acquisition rather than a renewal.

Which period a refund lands in

Refunds follow the same refund recognition setting as your P&L, under Dashboard -> Settings:

  • On the sale date (the default) -- a refund is counted in the period the original order was placed. An order placed 1 August and refunded 20 August counts in August; one placed 25 July and refunded 3 August counts in July.
  • On the refund date -- a refund is counted in the period the money went back.

Because the setting is applied when the page loads rather than baked into stored figures, changing it updates this page on the next load. Your subscription numbers and your P&L will always agree with each other, but neither will necessarily match Shopify's own Refunds report, which is always refund-date based.

Per-product breakdown

Below the cards, a By product table breaks the same period down per product: Product, Subscribers, Renewals, Revenue, Refunds, Refund %, Contribution Profit, and Margin, sorted by revenue. It shows which products actually drive recurring revenue rather than assuming it is spread evenly.

Revenue in this table is net of refunds, matching the Renewal Revenue card above it. Contribution Profit and Margin follow from that net figure.

Per-product refunds use the exact per-item refund your store reported wherever that detail is available. Where it is not -- older orders, and refunds recorded in MerchantFlow that were never pushed back to your store -- the order's refund is divided across its subscription items in proportion to what each contributed to the order. The column always adds up to the Refunds card, so the split affects which product a refund is attributed to, never the total.

Time ranges

The page follows the global time range selector. The presets 7 days, 30 days, 90 days, and 1 year are cached and load fastest; custom date ranges are computed on request.

On plans with a history limit, a range reaching further back than your plan allows is trimmed to the earliest date available to you. The trim is silent -- the API reports it, but the page renders the trimmed figures without flagging them, so cross-check the range against your plan's history window before reading a long-range total.

Improving accuracy

  • Keep COGS complete. Contribution margin on renewals is only as good as your COGS coverage.
  • Let history accumulate. Charge-pattern inference needs several cycles before it is confident, so a newly connected store will show gaps.
  • Check your subscription app's tags. Apps that tag customers give MerchantFlow much stronger evidence than charge inference alone.

Common questions

Why do subscriber counts differ from my subscription app? Because MerchantFlow infers them from observable evidence rather than reading contracts. Expect directional agreement, not a match. Your subscription app is authoritative.

Is a subscriber counted as a new customer too? Their first order makes them a new customer in the normal KPI metrics. Subsequent renewals are renewals, not new customers.

Why is my projection blank? Either fewer than 3 subscribers have been charged more than once yet, or your selected range does not end in the current month. The page states which.

Does subscription revenue double-count in the P&L? No. Renewal orders are ordinary orders that also happen to be identified as recurring. This page re-cuts revenue you already have; it does not add any.

Last updated on

On this page