Stripe ASC 606 Revenue Recognition: A Practical Guide for SaaS Founders
ASC 606 for SaaS founders on Stripe: the five-step model, journal entries, mid-cycle changes, refunds, trials, and an audit-prep checklist.
ASC 606 came into force for private companies in 2018. For about three years after, most SaaS founders cheerfully ignored it. They booked Stripe deposits as revenue the month the cash hit the bank and went back to building features.
Then somebody asks for audited financials. A potential acquirer. A Series A lead. A new bank line. And the same conversation happens:
“We need to restate three years of revenue.”
Three weeks of panic, a five-figure invoice from a Big Four firm, and a brand new column in the cap table called “audit findings.” It happens because nobody told the founder that “Stripe deposited $14,200 in March” is not the same sentence as “we earned $14,200 of revenue in March.”
This post is the practical guide I wish someone had handed me when I was wiring up my first SaaS company’s books. I spent several years as an SAP and ASC 606 implementation lead at Accenture before founding ERPClaw, so I have watched a lot of these conversations from both sides of the table. We will walk through the five-step ASC 606 framework using a concrete Stripe subscription, write the actual journal entries, work through the awkward edge cases, and finish with a checklist for your first audit.
This post mixes founders and CPAs. If you already know what a performance obligation is, skip the definitions in brackets. If you already know what MRR means, the same applies in the other direction.
What ASC 606 actually says
ASC 606 is the revenue recognition standard issued by FASB and IASB jointly. “ASC 606” is the FASB codification; “IFRS 15” is the international equivalent. Same standard, different name.
The core idea is one sentence: revenue should be recognized when (or as) the seller transfers control of the promised good or service to the customer. Cash receipt is irrelevant. Invoice date is irrelevant. Contract signature date is irrelevant. What matters is when the customer actually gets what they paid for.
For a SaaS subscription, “what they paid for” is access to your software for some period. If they paid for twelve months in January, you have not earned that money in January; you earn it day-by-day across the year. The cash sits on your balance sheet as a liability called deferred revenue (sometimes “unearned revenue”: money the customer paid you that you have not yet earned because you still owe service). It stays there until you deliver.
That is the entire intuition. Everything else is mechanics.
The five-step framework, applied to a Stripe subscription
The standard prescribes a five-step model for any contract. For a straightforward SaaS subscription on Stripe, the steps map cleanly. Let us use a running example: Acme Inc subscribes to your $1,200/year “Pro” plan on January 1, 2026, paid up front via Stripe.
Step 1: Identify the contract
A contract creates enforceable rights and obligations. For SaaS, it is usually three artifacts: your Terms of Service, your pricing page, and the Stripe subscription record itself.
Practically: a Stripe subscription is the contract. When Acme
clicks Subscribe and Stripe creates a sub_xxx record, you have a
contract. The subscription ID is your identifier;
current_period_start and current_period_end are the boundaries;
plan_amount and plan_interval define the consideration.
If you sell enterprise contracts with a separately-signed MSA, the MSA is the contract and Stripe is just the billing mechanism. Same accounting; the artifact you point an auditor at is different.
Step 2: Identify performance obligations
A performance obligation is a distinct promise to transfer a good or service. (For founders: the “thing you are on the hook to deliver” line item.) For a typical single-product SaaS sub, there is one: deliver software access for the subscription period.
Trivial for most plans. It gets interesting when your plan bundles things:
- SaaS access plus implementation services = two obligations
- SaaS access plus training = potentially two obligations (depends on whether training is “distinct”)
- SaaS access plus a hardware kit = two obligations
- A “platform fee” plus a “per-transaction fee” = usually one combined obligation, recognized as transactions occur
The test for “distinct” is whether the customer could benefit from each on its own. A training course you only sell to subscribers is probably not distinct. A training course you also sell standalone is.
For the rest of this post assume one obligation. If you have multiple, repeat steps 3 through 5 per obligation, which is where this stops being a spreadsheet exercise and starts being a software one.
Step 3: Determine the transaction price
The amount you expect to be entitled to in exchange for delivering. For Acme: $1,200, paid up front.
Adjustments that affect transaction price:
- Discounts and coupons: reduce the price. If Acme used 20% off and paid $960, transaction price is $960.
- Expected refunds: estimated returns reduce price. For SaaS, small but not zero (think 7-day money-back).
- Variable consideration: usage pricing, performance bonuses, success fees. Estimate the expected amount, constrained so you do not recognize revenue you might have to reverse.
- Significant financing component: prepayments over a year should technically split out interest. Most SaaS companies treat this as immaterial for twelve months or less.
Transaction price for our example: $1,200.
Step 4: Allocate the transaction price
Allocation only matters when you have multiple performance obligations. For Acme’s single-obligation subscription, the entire $1,200 is allocated to the SaaS access obligation.
If you bundled a $200 implementation fee into the $1,200 price, you would allocate based on standalone selling prices (SSP: what each component would sell for if you sold it alone). Say SaaS access alone is $1,200/year and implementation alone is $300:
- Total SSP = $1,500
- Allocate $1,200 × ($1,200 / $1,500) = $960 to SaaS access
- Allocate $1,200 × ($300 / $1,500) = $240 to implementation
This is “relative SSP allocation” and it is where most DIY ASC 606 spreadsheets quietly start lying.
Step 5: Recognize revenue when (or as) the obligation is satisfied
For Acme: satisfied over time, ratably across twelve months. So you recognize $1,200 / 12 = $100/month.
For one-time obligations (hardware delivery, implementation milestone), recognize at the point in time the obligation is satisfied. For variable obligations (transaction-based pricing), recognize as the customer consumes.
That is the whole framework. Now the journal entries.
The journal entries you would actually post
Every example below uses debits and credits from your perspective (the SaaS company). Stripe takes 2.9% plus $0.30 per card transaction; we will use a flat $35 fee on the $1,200 charge for arithmetic clarity (real number is $34.80; close enough).
Entry 1: Acme pays $1,200 on January 1
When Stripe confirms the charge succeeds:
| Account | Debit | Credit |
|---|---|---|
| Stripe Clearing (asset) | $1,165 | |
| Stripe Fees (expense) | $35 | |
| Deferred Revenue (liability) | $1,200 |
A few things worth noting:
- Stripe Clearing is an asset account that holds funds Stripe owes you but has not paid out yet. It typically takes 2 to 7 business days for Stripe to deposit into your bank.
- Stripe Fees are recognized immediately as an expense. They are not deferred over the subscription period (this is one of the rare cases where cash-basis intuition is correct).
- Deferred Revenue is a liability. You owe Acme twelve months of software access; until you deliver, that obligation lives on the balance sheet.
- Subscription Revenue is zero at this point. You have not earned anything yet.
Entry 2: Stripe pays you out (a few days later)
| Account | Debit | Credit |
|---|---|---|
| Bank (asset) | $1,165 | |
| Stripe Clearing (asset) | $1,165 |
Stripe Clearing nets to zero for this transaction. This is the “three-layer reconciliation” pattern: every payout from Stripe must match the net of the underlying transactions, or your books are wrong.
Entry 3: End of January, recognize 1/12
| Account | Debit | Credit |
|---|---|---|
| Deferred Revenue (liability) | $100 | |
| Subscription Revenue (income) | $100 |
You have now delivered one month of access. Deferred Revenue drops by $100; Subscription Revenue picks it up.
Repeat this entry every month. By December 31, Deferred Revenue for Acme’s contract is $0 and you have recognized $1,200 of revenue across the year.
Entry 4: Acme cancels at end of April with a pro-rata refund
Acme used four months ($400 earned) and wants a refund for the unused eight months ($800).
The refund settles in two parts. The cash refund:
| Account | Debit | Credit |
|---|---|---|
| Deferred Revenue (liability) | $800 | |
| Stripe Clearing (asset) | $800 |
You no longer owe Acme the eight months of access (because you are giving the money back), so Deferred Revenue is cleared. You also no longer have $800 sitting in Stripe Clearing waiting to be paid out; Stripe pulls it back to refund Acme.
Note: Stripe does not refund the original processing fee. The $35 you paid in January stays gone. Some Stripe regions have changed this policy over the years; check your account, but assume the worst.
Entry 5: Acme cancels at end of April but elects “no refund, end-of-period grace”
Same scenario, but Acme just stops using the product on April 30 and your terms say “no refund.” The eight months of unrecognized revenue are still your money, and you have just been told you no longer need to deliver anything.
| Account | Debit | Credit |
|---|---|---|
| Deferred Revenue (liability) | $800 | |
| Subscription Revenue (income) | $800 |
The full $800 hits revenue at the moment of cancellation, because the performance obligation is discharged. Whether by delivery or by extinguishment, it is gone, and the deferred liability has to clear.
This is a place where DIY spreadsheet bookkeeping silently goes wrong: founders forget that “customer cancelled, kept the money” is a revenue recognition event, not a non-event. The auditor will catch it.
The awkward stuff: mid-cycle changes
Real SaaS contracts do not sit politely from January to December. They get upgraded, downgraded, paused, and modified. Stripe handles the billing math correctly with prorations; ASC 606 has its own opinion on how those prorations should hit your books.
Mid-cycle upgrade
Acme upgrades from $100/month to $200/month on day 15 of a 30-day cycle. Stripe creates a proration invoice for the additional $50 (half a month at the $100 incremental price), charged immediately.
The recognition schedule splits:
- Days 1 to 15: recognized at $100/month rate, so $50 earned. No change.
- Days 16 to 30: $200/month rate, so $100 earned across the remainder.
- The $50 proration invoice goes to Deferred Revenue first, then recognizes ratably across days 16 to 30.
End-of-month total recognized: $50 plus $100 = $150. Cash collected: $100 plus $50 = $150. Books balance.
If you do this in a spreadsheet, you will mess it up the third time it happens. Trust me.
Mid-cycle downgrade
Acme downgrades from $200/month to $100/month on day 15. Stripe issues a credit note for the unused half-month at the higher tier ($50 credit). The credit applies to the next invoice rather than refunding cash.
Journal entries:
- Reverse the $50 of unearned high-tier revenue:
DR Deferred Revenue $50, CR Stripe Clearing $50(credit memo). - The credit sits in Stripe as a customer balance, applied at next invoice.
The recognition schedule for days 16 to 30 reverts to the $100/month rate.
Annual subscription with a discount
Acme subscribes to the $1,200 annual plan with a 20% off coupon and pays $960 up front.
The transaction price (Step 3) is $960, not $1,200. The discount is not a separate accounting line item; it is absorbed into the price and disappears.
| Account | Debit | Credit |
|---|---|---|
| Stripe Clearing (asset) | $933 (after $27 fee) | |
| Stripe Fees (expense) | $27 | |
| Deferred Revenue (liability) | $960 |
Monthly recognition: $960 / 12 = $80/month, not $100.
The fact that the “list price” was $1,200 is irrelevant for revenue purposes. It might matter for sales reporting or pricing analytics, but not for GAAP.
Trial-to-paid transition
Acme signs up for a 14-day free trial on January 1. Stripe creates the
subscription in trialing status; no charge, no payout, no journal
entry. Deferred Revenue is zero, because nothing has been
collected and nothing has been promised in exchange for cash.
On January 15, the trial ends. Stripe attempts the first charge, it succeeds, and the regular flow kicks in: $1,200 to Stripe Clearing, $1,200 to Deferred Revenue.
If Acme cancels during trial, no journal entries are ever posted. The fact that the trial existed has no GL consequences. (For metrics, your MRR/ARR system might track trial conversion rates, but that is analytics, not accounting.)
Failed payment then recovery
Stripe attempts to charge Acme on day 1 of a renewal. The card is declined. Stripe retries on days 3, 5, and 7, and the charge finally succeeds on day 7.
You post one journal entry, dated day 7, for the successful
charge. The four failed attempts have no GL impact. Log them for audit
(a proper integration syncs them to a stripe_charge table with
status='failed'), but they do not touch the GL.
If the customer is in past_due status with a recognition schedule
that should have started on day 1, decide policy: backdate recognition
to day 1 (when access was nominally granted) or day 7 (when payment
arrived)? Most SaaS companies pick day 7. No payment, no obligation,
no recognition.
When you can DIY and when you cannot
- Monthly-only, no annuals, under $1M ARR: you probably do not need ASC 606 in practice. Recognize cash as revenue, document the policy, move on.
- Annual contracts, pre-audit: DIY in a spreadsheet is feasible. The math is grade-school arithmetic. The risk is consistency, you forgetting to update the schedule when contracts change.
- Annual contracts plus a Series A or acquisition on the horizon: get this right now. Retroactive rebuilds of three years of schedules cost 10x to 100x what real-time would have.
- Multi-element bundles, Connect platform fees, variable pricing: get a CPA who knows ASC 606. Steps 4 and 5 involve real judgment.
- Public-company-bound: not a question. Software, controller, Big Four sign-off.
Audit-prep checklist
When the auditor shows up they will ask for evidence. Minimum viable file:
- Revenue recognition policy memo, one page in plain English: subscriptions recognized ratably from access-grant date, implementation at milestone, Stripe fees expensed as incurred, refunds reverse unrecognized portion (or hit revenue if already recognized).
- Per-contract recognition schedule: for every active sub, a row with contract value, start, end, monthly recognition, and recognized-to-date.
- Period-end recognition journal entries: one voucher per month-end cycle, with per-contract detail attached.
- Deferred Revenue rollforward: opening + new + recognized - refunds = closing. Closing must reconcile to both the GL liability balance and the sum of unrecognized contract values.
- Stripe payout reconciliation: every payout matched to bank deposits, with underlying charges, fees, and refunds tied out. Stripe Clearing must net to zero each period, or the discrepancy must be explained.
- Modification log: every upgrade, downgrade, mid-cycle change, and the journal entry that recorded it.
- Refund register: every refund, with original charge reference and treatment (reversed deferred vs. booked against revenue).
If you can produce these seven artifacts on demand, you will pass an ASC 606 audit. If you cannot, you will spend a lot of money having your auditor produce them for you.
Tools that can help
Ordered roughly by founder budget:
- Google Sheets. Free. Works for 50 or fewer active subs if you are disciplined. Breaks the moment you forget to update for a contract change. The number-one cause of audit findings I have seen is “we maintained recognition in a spreadsheet that diverged from the GL.” That said, if you are a five-customer company with three annual contracts, a sheet is the right answer for now.
- Stripe’s Revenue Recognition product. $0.04 per processed transaction. Computes schedules from Stripe data and gives you journal entries to post into your accounting system. Good if Stripe is your sole source of truth and you are fine hand-posting entries into QuickBooks or Xero each month.
- Synder, Bookkeep, A2X: connector tools, $20 to $100/month, mostly ecommerce-focused. ASC 606 specifically is light, but they sync the underlying charges and fees cleanly into your GL.
- Rillet. SaaS-focused finance platform with strong ASC 606 support. Enterprise pricing, typically $1K to $3K/month. See our Rillet comparison.
- Sage Intacct. Legacy mid-market, $400 to $1,500/month per user, full ASC 606 module. Overkill for most early-stage SaaS but the default landing spot once a controller arrives.
- NetSuite. If you are asking whether you need NetSuite, you do not.
- ERPClaw. Free, open-source, AI-native, self-hosted on your own infrastructure. Implements the five-step model for Stripe subscriptions and posts journal entries with full audit trail. The other tools above are all AI-decorated; ERPClaw is the only AI-native option in the category, which is part of why the price can be zero. See the Stripe integration page. We built it because we wanted what Rillet does at zero monthly cost.
Pick the cheapest one that produces the seven audit artifacts above without you having to think about it. For most pre-Series-A SaaS companies, Stripe’s own Revenue Recognition product plus a tidy QuickBooks file is enough.
Frequently asked questions
Do I need ASC 606 if I am cash-basis for tax purposes?
Tax basis and book basis are separate. You can file taxes on a cash basis and still need ASC 606 for your audited financials, board reporting, or due diligence. Most VC-backed SaaS companies maintain two sets of books for exactly this reason.
What if I just recognize annual prepayments evenly across 12 months, is that good enough?
For a single-product, single-period subscription with no mid-cycle changes and no refunds, yes. Straight-line monthly recognition is correct for SaaS access. The complications come from refunds, upgrades, downgrades, trials, and bundles, exactly the things that happen in a real customer base.
My subscriptions are monthly, not annual. Do I still need to defer?
If a customer pays on January 1 for January access, recognize the full amount in January. In practice you can treat monthly subscriptions as recognized in the period charged, provided your billing dates align with your accounting periods.
If a customer pays on January 20 for service through February 19, you should split: roughly 36% in January, roughly 64% in February. Most companies ignore this because the error washes out across periods, but it is technically incorrect.
What about usage-based or metered billing?
Recognize as the customer consumes. If Acme uses 10,000 API calls in March and you bill $0.001 per call, you recognize $10 of revenue in March. Stripe’s metered billing handles the invoicing; you just need to make sure your accounting picks up the right period.
How do I handle Stripe processing fees?
Expense them in the period incurred. They are not part of revenue recognition and they are not refundable when you refund a customer. Treat them like any other vendor fee.
What about the discount on an annual plan, do I recognize the “list price” or the discounted price?
Discounted price. The transaction price under ASC 606 is what the customer is contractually obligated to pay, net of discounts. The “list price” is a marketing concept with no GAAP relevance.
How does ASC 606 treat Stripe Connect application fees?
Application fees you collect from connected accounts are your revenue, recognized when the underlying transaction completes (usually point-in-time). The gross transaction is not your revenue if you are not the principal. Principal-vs-agent is the biggest judgment call in Connect accounting and worth a CPA conversation if material.
Will my auditor accept journal entries posted automatically by software?
Yes, provided the software has an audit trail (who, what, when, why) and the recognition logic is documented. Any reasonable accounting system, including ERPClaw, provides this. Auditors care that the logic is documented and reproducible, not who typed the entry.
Closing
ASC 606 is not hard. It is fiddly. The five-step framework is straightforward, the journal entries are standard, and the principles are intuitive once you internalize that “cash received” and “revenue earned” are different events.
What makes it hard in practice is consistency: applying the same logic to every contract, modification, refund, and period, forever. Humans are bad at this. Spreadsheets are okay until they are not.
If you take one thing from this post: stop booking Stripe deposits as monthly revenue if any of your subs are annual. Set up a deferral schedule and recognize ratably. Your future audited self will thank you.
If you are comparing tools, the ERPClaw plus Stripe launch post, the canonical ASC 606 reference, and the Rillet comparison cover the rest. The SaaS landing page and pricing round it out.
Questions or edge cases? Email [email protected].
Related posts
Agency Accounting, Project P&L, and Time Billing: A Real Guide
Why your friendly retainer client is secretly losing you $40 an hour, the four metrics every agency owner should know, and how to fix project P&L.
A2X Alternative: The Free Open-Source Tool Most Shopify Stores Don't Know About
Looking for an A2X alternative? ERPClaw uses the same clearing account method, books every order separately, includes per-warehouse stock costs, and costs $0. A founder's honest comparison.
AI Decorated vs AI Native Software: Why Most AI Features Will Lose
AI-decorated tools bolt a chatbot onto 2015 software and charge a new fee. AI-native software rebuilds the architecture. One of these wins. Here is why.