Paddle sells as merchant of record, which is convenient operationally and adds two specific distortions to any churn or MRR analysis: revenue arrives net of Paddle's fees, and displayed prices are frequently tax-inclusive with the tax rate varying by the customer's country.
TL;DR: Paddle is a merchant of record, so its revenue figures are net of fees and its prices are often tax-inclusive. Here is which Paddle objects to export, how to normalise them, and how Paddle Billing differs from Paddle Classic.
Every churn calculation needs the same seven things: a stable customer identifier, subscription status, recurring amount and currency, billing interval and term, start date, cancellation or end date, and ideally the date of the last successful payment. (Why each one, and what breaks without it →) What changes between platforms is where those fields live and which status values mislead you.
Paddle exposes subscriptions, transactions, customers and prices as separate objects. The subscription carries the recurring commitment; the transaction carries what actually moved, net of fees and tax. For churn you want the subscription objects, with transactions used only to establish whether payments have actually been landing. Note that Paddle has two generations of API and dashboard — Paddle Billing and the older Paddle Classic — with different object shapes and different export layouts. Establish which one the target is on before anything else, because a script written against one will silently misread the other.
| Needed | Where it lives in Paddle | Watch out for |
|---|---|---|
| Account identifier | Customer ID on the subscription object. Do not use the email, which changes. | One customer can hold several subscriptions; aggregate first. |
| Subscription status | active, trialing, past_due, paused, canceled | past_due is unresolved churn, not revenue. Treat separately. |
| Amount and currency | Recurring price on the subscription, plus currency code | Frequently tax-inclusive. Two customers on the same plan in different countries can show different amounts. |
| Billing interval and term | Billing cycle interval and frequency | Normalise annual to monthly before summing. |
| Start date | Subscription start / first billed date | Paddle Classic and Billing name this differently. |
| Cancellation or end date | Canceled-at, plus the scheduled change if a cancellation is pending | A pending cancellation is economically churned and still shows as active. |
| Last successful payment date | Derive from the most recent completed transaction | Not present on the subscription object; you have to join. |
These are the errors we see repeatedly on this platform. Each one is silent: the analysis completes and returns a number that is wrong.
Where displayed prices include VAT or sales tax, the recurring amount varies with the customer's country for the same plan. Summing those amounts gives you a gross-of-tax figure that is not revenue. Either use the net amount from the transaction records or apply the plan's list price consistently, and say in the memo which you did.
Because Paddle is the seller, what you see in payouts is after their fee and after tax remittance. A gross MRR built from subscription prices and a net revenue figure from payouts will never reconcile, and the gap is not a discrepancy — it is the fee and the tax. Reconcile them deliberately once, then work in one of the two consistently.
Object names, status vocabularies and export columns differ between the two. A target that migrated part-way through the period you are analysing may have history split across both. Ask which generation the data came from, and whether the file spans a migration.
A subscription scheduled to cancel at period end is still active until it ends. If you count status alone you will miss revenue that is already committed to leaving. Check for scheduled changes as well as status.
Vague requests produce filtered exports. This wording asks for the complete set in the platform's own vocabulary, which is what gets you a usable file first time:
Please export all subscriptions from Paddle, including cancelled and past-due ones, for the full history. Confirm whether the account is on Paddle Billing or Paddle Classic. Include the recurring amount, currency, billing interval, start date, cancellation date and status, plus a note on whether displayed prices include tax. Separately, please export completed transactions so payment history can be reconciled.
One check first, and it is the same on every platform: count the rows that carry a cancellation or end date. If none do across a multi-year Paddle export, the file was filtered to active subscriptions and every churn figure you compute from it will come out at zero. That single defect causes more wrong churn numbers than every definitional argument put together, and it is fixed with one email rather than with analysis. The three further checks — row count, MRR reconciliation and history length — take another five minutes.
Once you have a clean export, the analysis is the same regardless of where it came from: recompute churn in both logo and revenue terms, build the renewal calendar, check concentration on parent entities rather than accounts, and test whatever the seller has claimed. The seller-claims pages cover the twelve claims worth testing and the arithmetic for each, and the 23-point checklist is the short version.
Official Paddle documentation: https://developer.paddle.com/. Export layouts change; the data model and the traps above do not.
All billing platforms → · Already integrated: Stripe, ChartMogul, ProfitWell, QuickBooks.
Every check on this page can be run by hand in a spreadsheet, and if you have the time you should. If you would rather not: send us the target's subscription export and we run the full human-reviewed analysis — logo churn, revenue churn, customer concentration, annual-plan decay, zombie MRR and an A–F revenue-quality grade. The free Starter tier covers one CSV per month, which is enough to check a single deal.
See a sample report → · Get the free 23-point checklist →
Because Paddle is a merchant of record. Subscription prices are gross and often tax-inclusive, while payouts are net of Paddle's fee and net of the tax they remit. Both numbers are correct and they measure different things. Reconcile them once, decide whether you are working gross or net, and state which in the analysis.
Only if the export was not filtered to active subscriptions. This is the single most common reason a churn analysis returns zero. Count rows with a cancellation date before doing anything else — if none exist across a multi-year file, request a complete export.
They are different generations with different object models, status vocabularies and export layouts. Analysis written for one misreads the other, usually silently. Establish which one produced the file, and ask specifically whether the history spans a migration between them.