From invoices to MRR
This guide explains how GrowPanel transforms your billing data—invoices, subscriptions, refunds—into MRR movements. Understanding this process helps you trust your numbers, explain differences from your billing platform, and interpret edge cases correctly.
MRR movements are the foundation of nearly every report in GrowPanel: MRR, ARR, churn, retention, cohorts, and more. They all derive from the same underlying movement data.
How billing data becomes MRR movements
GrowPanel processes your billing data in this order:
- Import invoices and subscriptions from your billing source
- Walk through invoices chronologically for each customer
- Calculate MRR from each invoice line item (subscription charges)
- Compare to previous state to determine what changed
- Classify the change as New, Expansion, Contraction, Churn, or Reactivation
The MRR calculation
For each subscription line item on a paid invoice:
- Start with the charge amount (unit price × quantity)
- Subtract discounts (percentage or fixed-amount coupons)
- Normalize to monthly:
- Monthly subscriptions: use the amount directly
- Quarterly: divide by 3
- Semi-annual: divide by 6
- Annual: divide by 12
Example:
- Customer pays $2,400/year for an annual plan with 20% discount
- Gross: $2,400, Discount: $480, Net: $1,920
- MRR: $1,920 ÷ 12 = $160/month
Movement types
Every MRR change is classified into one of these types:
| Type | When it happens |
|---|---|
| New | Customer's first payment (MRR goes from $0 to >$0, no prior history) |
| Expansion | Existing customer's MRR increases |
| Contraction | Existing customer's MRR decreases but stays above $0 |
| Churn | Customer's MRR goes to $0 with no remaining active subscriptions |
| Reactivation | Previously churned customer starts paying again |
There are also internal movement types used for reporting:
| Type | Purpose |
|---|---|
| Segment exit | Customer leaves a plan (used in plan-level reporting) |
| Segment entry | Customer joins a plan (used in plan-level reporting) |
Multiple subscriptions
A single customer can have multiple active subscriptions simultaneously—even with different billing intervals or currencies.
How it works
- Each subscription is tracked independently
- The customer's total MRR is the sum of all active subscriptions
- Churn only happens when all subscriptions end and total MRR reaches $0
Example: Customer with monthly + annual subscriptions
| Date | Event | Subscription A (Monthly) | Subscription B (Annual) | Total MRR |
|---|---|---|---|---|
| Jan 1 | Subscribes to A | $100 | — | $100 |
| Mar 1 | Adds B | $100 | $200 | $300 |
| Jun 1 | Cancels A | $0 | $200 | $200 |
| Mar 1 (next year) | B expires | $0 | $0 | $0 (Churn) |
In this example:
- Adding subscription B is recorded as Expansion (+$200)
- Canceling subscription A is recorded as Contraction (-$100)
- The customer only churns when subscription B ends
Different billing intervals
When a customer has subscriptions with different intervals (e.g., one monthly, one annual), each is normalized to monthly MRR independently. The customer's movements reflect changes to their combined MRR.
Mid-cycle changes and prorations
When a customer upgrades, downgrades, or changes quantity mid-billing-cycle, your billing platform typically creates prorated invoice line items.
How GrowPanel handles prorations
- Proration credits ("Unused time on...") indicate the old subscription ending
- Proration charges ("Remaining time on...") indicate the new subscription starting
- GrowPanel reads both to understand the change
Example: Mid-month upgrade
Customer upgrades from $50/month to $100/month on the 15th:
| Invoice line | Amount | GrowPanel interpretation |
|---|---|---|
| Unused time on Basic | -$25 | Old plan ending |
| Remaining time on Pro | +$50 | New plan starting |
| Net charge | $25 | — |
GrowPanel records:
- Segment exit from Basic (-$50 MRR)
- Segment entry to Pro (+$100 MRR)
- Expansion of $50 MRR
The movement is dated when the change took effect (the 15th), not when the invoice was created.
Invoice gaps and missing renewals
Sometimes there's a gap in invoicing—a subscription should have renewed but no invoice appeared.
How GrowPanel detects this
If a subscription's billing period ended more than 3 days ago and no new invoice has arrived, GrowPanel marks it as churned. This catches cases where:
- A subscription was quietly canceled
- The billing platform failed to generate an invoice
- Data sync missed an event
What you'll see
The churn movement is backdated to when the subscription period ended, ensuring your historical MRR is accurate even if the detection happens later.
Edge cases
Paying customer starts a new trial
If a customer already has a paying subscription and then starts a trial on a different product:
- The trial doesn't affect their existing MRR
- The trial is tracked separately
- When the trial converts, it's recorded as Expansion (not New)
First invoice fully refunded
If a customer's very first invoice is fully refunded:
- GrowPanel treats it as if the subscription never happened
- No "New" movement is recorded
- No "Churn" movement is recorded
- The customer remains a lead/trial (depending on their state)
This prevents inflating your New MRR with subscriptions that were immediately cancelled or disputed.
Partial refunds
Partial refunds don't automatically reduce MRR. MRR is based on the ongoing subscription, not individual invoice adjustments. If a refund represents an actual subscription change (downgrade, quantity reduction), that change should appear in subsequent invoices.
Zero-value invoices
Invoices with $0 total (common during trials) don't create MRR movements. However, they may update subscription status or trigger trial tracking.
Customer with only free/zero-MRR subscriptions
A customer can have active subscriptions with $0 MRR (e.g., free plans, 100% discounted plans). In this case:
- They're considered "active" (not churned)
- Their MRR is $0
- Churn only happens if those subscriptions are cancelled
Churn recognition timing
GrowPanel offers two options for when to recognize churn:
End of billing period (default)
Churn is recorded when the subscription actually ends—when the customer's paid access expires.
Example:
- Customer cancels on January 15
- Their annual subscription runs until March 1
- Churn is recorded on March 1
This approach shows when revenue actually stops.
Immediate
Churn is recorded when the cancellation is submitted.
Example:
- Customer cancels on January 15
- Churn is recorded on January 15
This approach shows when the customer made their decision.
To change: Settings → Reporting → When to recognize churn
Past-due and failed payments
When a payment fails, the customer enters a "past-due" state while your billing platform retries.
Auto-churn threshold
GrowPanel automatically marks customers as churned after a configurable number of days past-due (default: 30 days).
Example:
- Payment fails on January 1
- Billing platform retries for several weeks
- After 30 days (January 31), GrowPanel records churn
To change: Settings → Reporting → Auto-churn past-due subscribers
Why this matters
Without auto-churn, customers with perpetually failing payments would stay in your "active" count forever. The threshold should match your dunning (retry) period—if your billing platform gives up after 30 days, set this to 30.
Movement grouping
When a customer makes multiple changes in quick succession, GrowPanel can combine them into a single movement.
How it works
Movements within the configured time window (default: 24 hours) are grouped together.
Without grouping:
- 10:00 AM — New: $50 MRR (subscribed to Basic)
- 10:05 AM — Expansion: $50 MRR (upgraded to Pro)
With 24-hour grouping:
- 10:00 AM — New: $100 MRR (subscribed to Pro)
Why this is useful
- Cleaner movement logs
- Accurate "New customer" tracking (the final plan, not the starting plan)
- Reduces noise from immediate upgrades during checkout
To change: Settings → Reporting → Group MRR movements
Why numbers differ from your billing platform
Common reasons for differences:
| Difference | Reason |
|---|---|
| GrowPanel shows less MRR | Trials excluded, past-due customers auto-churned, end-of-period churn recognition |
| GrowPanel shows more MRR | Currency conversion differences, multiple data sources combined |
| Churn timing differs | Different churn recognition (immediate vs. end-of-period) |
| New customer count differs | Movement grouping combines signup + upgrade into single "New" |
Stripe-specific differences
| Stripe shows | GrowPanel shows | Why |
|---|---|---|
| Subscription MRR | Invoice-based MRR | GrowPanel uses actual charges, not projected amounts |
| Trials in MRR | Trials excluded | GrowPanel only counts paid revenue |
| Immediate cancellation impact | End-of-period impact (default) | Configurable in settings |
| Indefinite retry on failed payments | Churn after 30 days (default) | Configurable in settings |
Verifying the calculations
To investigate a specific customer's MRR:
- Go to Customers and find the customer
- Click to open their detail page
- Review the MRR movements table
- Compare with invoices in your billing platform
Each movement shows:
- Date it occurred
- Type (New, Expansion, etc.)
- Description of what changed
- MRR change amount
Summary
GrowPanel calculates MRR movements by:
- Processing paid invoices chronologically
- Normalizing subscription charges to monthly amounts
- Tracking each subscription independently
- Detecting changes by comparing current vs. previous state
- Classifying changes into movement types
Key configurable settings:
- Churn recognition timing — when cancelled subscriptions count as churned
- Auto-churn threshold — when past-due customers count as churned
- Movement grouping — how quickly successive changes are combined
Understanding these rules helps you interpret your data correctly and explain any differences from your billing platform.
Related pages
- MRR report — Using the MRR report
- MRR movements report — Viewing all movements
- Reporting settings — Configuring calculation rules
- Data discrepancies — Troubleshooting differences