Skip to main content
More Stripe documentation

Stripe ASC 606 Revenue Recognition for SaaS

How ERPClaw handles Stripe ASC 606 revenue recognition. Deferred revenue, monthly recognition, plan changes, cancellations, and the journal entries behind each.

ASC 606 is the accounting standard for revenue recognition. It says you cannot count an annual subscription as revenue when the customer pays it. You have to recognize it monthly over the subscription period.

This page documents how ERPClaw implements ASC 606 for Stripe subscriptions, with the actual journal entries.

The five steps

ASC 606 defines a five-step framework for revenue recognition. For Stripe subscriptions, the steps map as follows:

  1. Identify the contract: a Stripe subscription = a contract.
  2. Identify performance obligations: the obligation is to deliver software access for the subscription period.
  3. Determine the transaction price: the subscription’s recurring amount.
  4. Allocate the transaction price: for single-product subscriptions, all of it goes to the one obligation.
  5. Recognize revenue when (or as) the obligation is satisfied: monthly, over the subscription period.

Multi-product subscriptions and bundles need step 4 to allocate, which gets complicated. The Stripe bridge creates one contract with one performance obligation per subscription, priced from the subscription’s plan amount. Bundles that need an allocation across several obligations are set up with the core revenue contract actions (performance obligations, variable consideration) instead.

How it runs

Recognition is two explicit steps, not a background job:

  1. Create the schedule for a subscription with stripe-create-rev-rec-schedule. ERPClaw creates the revenue contract, one obligation, and twelve monthly schedule entries starting from the subscription’s current period start. An annual plan is spread as one twelfth per month; a monthly plan as its plan amount each month.
  2. Recognize each month with stripe-recognize-subscription-revenue for the period. For every scheduled entry in that month it posts Deferred Revenue to your revenue account and marks the entry recognized.

Once a subscription has a schedule, its charges post to Deferred Revenue instead of revenue.

The journal entries

Customer pays $1,200 for an annual subscription

When the charge posts:

Account Debit Credit
Stripe Clearing $1,165
Stripe Processing Fees $35
Deferred Revenue $1,200

Note: the Stripe fee is an immediate expense, not deferred.

End of month 1 (recognize 1/12)

Account Debit Credit
Deferred Revenue $100
Subscription Revenue $100

Repeat each month.

End of month 12 (final recognition)

Account Debit Credit
Deferred Revenue $100
Subscription Revenue $100

After this, Deferred Revenue for this subscription is $0.

Customer cancels mid-year (after 4 months)

Eight months unused at $100/month = $800 unrecognized.

Record the cancellation with stripe-handle-subscription-change --change-type cancel. ERPClaw marks the revenue contract terminated and reports what is still unrecognized: eight entries, $800. What happens to that $800 is posted as its own entry:

  • If refunded, the refund posts from the synced Stripe refund (stripe-post-refund-gl) against Stripe Clearing.
  • If not refunded (e.g. cancellation effective end of period), post a journal entry that recognizes the remainder:
Account Debit Credit
Deferred Revenue $800
Subscription Revenue $800

Mid-cycle upgrades and downgrades

If a customer upgrades from $100/mo to $200/mo, record it with stripe-handle-subscription-change --change-type upgrade --new-plan-amount 200. ERPClaw keeps every month already recognized as it was and reprices every month not yet recognized at the new monthly amount. The contract total is updated to match.

Recognition is monthly, not daily. A proration charge that Stripe raises for the change posts like any other charge.

You can audit the result by reading the schedule (advacct_revenue_schedule) for that subscription’s contract.

Annual subscriptions paid with discount

If a customer pays $1,000 for a $1,200 annual plan (Stripe Coupon applied), the charge reflects the actual cash:

Account Debit Credit
Stripe Clearing $1,000
Deferred Revenue $1,000

The schedule is built from the plan price ($1,200, so $100 a month). For a discounted plan, reprice it to the cash actually collected (--change-type downgrade --new-plan-amount 1000) before the first recognition, so each month recognizes $83.33 and Deferred Revenue ends at $0.

Failed payment then re-attempted successfully

Stripe attempts to charge, fails, retries, succeeds. Bulk posting picks up only succeeded charges. The failed attempt is stored as a stripe_charge row with status='failed' for audit purposes, with no GL impact.

Subscriptions on Stripe trial

Trial periods do not collect payment, so no charge posts during a trial. If the customer cancels during trial, no journal entry, no Deferred Revenue.

A schedule created while the subscription is still trialing starts from the current period start. If you want recognition to start with the first paid period, create the schedule once that period begins.

Multi-currency subscriptions

ERPClaw v1 supports USD-denominated subscriptions only. Other currencies are recorded but not auto-converted to USD for GL posting. Multi-currency runs payment-side across 7 currencies (USD, EUR, GBP, CAD, INR, SGD, AED): an invoice settles in the currency it was raised in, with no conversion inside a transaction.

Audit trail

For an auditor reviewing your books, ERPClaw provides:

  • advacct_revenue_contract and advacct_revenue_schedule: the contract behind each subscription and its monthly schedule, planned and recognized
  • stripe-rev-rec-status: per subscription, the plan, total contract value, revenue recognized to date, and the deferred balance remaining
  • revenue-waterfall-report: the schedule laid out by period
  • The audit log: every schedule creation, recognition run, and subscription change is written with a timestamp

Your agent can save any of these as a file for a CPA or auditor.

What the bridge handles

  • Annual and monthly plans, spread over twelve months
  • Upgrades and downgrades, repricing the months not yet recognized
  • Cancellation, with the unrecognized remainder reported
  • Discounted plans, by repricing to the cash collected
  • Failed payments (no GL impact) and trials (no charge, no entry)

Edge cases NOT handled in v1

  • Multi-currency conversions
  • Billing intervals other than month or year (weekly, daily, every N months)
  • Day-level proration inside a month
  • Multi-element subscriptions with manual allocation
  • Variable consideration adjustments (price changes mid-cycle by usage)

If you hit one of these, the recognition will need a manual journal entry. Email [email protected] if you have a regular case that isn’t covered.

ASC 606 in plain English

You are not paying for “access to a SaaS tool.” You are paying for 12 months of access. The vendor cannot count your money as revenue until they have actually given you access for the period they promised. ASC 606 makes this rule formal.

The accounting effect is straightforward but easy to get wrong by hand. ERPClaw builds the schedule and posts each month’s entry for you, for any size book.

Source