Skip to main content

Chrome Extension Developer Bookkeeping: Reconciling Payouts After Google Killed In-App Payments

10 min readMike ThriftMike Thrift
Chrome Extension Developer Bookkeeping: Reconciling Payouts After Google Killed In-App Payments

Open the Chrome Web Store developer dashboard today and you'll notice something missing: a "payments" tab. Google shut down its own in-app payment system for extensions back in 2021, and it never came back. If you want to charge for a Chrome extension in 2026, you are on your own for billing, subscriptions, refunds, tax collection, and — the part almost nobody plans for — reconciling what actually landed in your bank account against what you sold.

That last piece trips up more indie developers than pricing ever does. A single-developer shop running three or four extensions through Stripe, Paddle, or a wrapper like ExtensionPay ends up with payout deposits that don't map cleanly to any one product, refund spikes that arrive out of nowhere after a Chrome Web Store review delay, and a bank balance that never quite matches what the sales dashboard says it should. None of that is a bug in your business. It's the predictable result of stitching together a payments stack that Google used to run for you.

Here's how to build bookkeeping that survives it.

Why Google Got Out of the Payments Business

Chrome Web Store Payments launched in the early 2010s, when there weren't many good options for a solo developer to charge for a browser extension. By 2021, Stripe, Braintree, and a wave of "merchant of record" services had matured enough that Google decided it no longer needed to run its own checkout, license-key, and payout system. It deprecated Chrome Web Store Payments and pushed every paid extension to pick between going free or switching to a third-party processor.

The practical result for developers: every dollar an extension earns now flows through a payment stack you assembled yourself, and every reconciliation problem that stack creates is yours to solve. There's no single "Chrome Web Store payout report" anymore — there's whatever your processor gives you, plus whatever the Chrome Web Store's own listing analytics show, plus your bank statement, and those three things rarely agree on the first look.

Payment Processor or Merchant of Record — Pick One Per Extension

Before reconciliation even starts, you need to know which side of the transaction you're legally on, because it changes what lands in your books.

A payment processor (Stripe directly, or a wrapper built on top of it like ExtensionPay) makes you the seller. You collect the money, you're the merchant of record for tax purposes, and you're responsible for figuring out sales tax and VAT obligations in every jurisdiction a customer lives in. Fees are lower — Stripe's baseline is 2.9% + $0.30 per charge, and a wrapper like ExtensionPay typically adds its own cut on top — but the compliance burden sits with you.

A Merchant of Record (Paddle, Lemon Squeezy, Fungies, and similar) legally becomes the seller instead of you. They collect the VAT or GST, file the returns in the more than 140 countries that now require it for digital goods, handle chargebacks, and pay you the net proceeds. You give up 4–8% of revenue instead of ~3%, but an entire category of bookkeeping and tax-filing work disappears. For a full breakdown of the tradeoffs and how to run the math on when the switch pays for itself, see our Merchant of Record guide.

For most solo extension developers below a few thousand dollars a month, the extra 3–5% an MoR charges is cheap insurance against having to register for VAT in a dozen countries by hand. Once you're running real recurring revenue across multiple extensions, run the comparison again — the math shifts as volume grows.

Whichever you pick, write it down. Your books need a clear answer to "who is the legal seller of record for this extension," because it determines whether sales tax liability shows up on your balance sheet at all.

The Reconciliation Problem Is Structural, Not a Mistake

Here's the part that catches developers off guard: even with a processor correctly configured, the payout you receive almost never equals the revenue you generated that period. Three things break the 1:1 match:

  • Batched payouts. Stripe and most MoRs pay out on a rolling schedule (often 2–7 days after the charge, sometimes weekly), so a payout landing on the 5th of the month contains sales from the last several days of the previous month. If you book payouts as revenue on the day they hit your bank, you're misattributing income to the wrong period every single month.
  • Multiple extensions, one processor account. If you run several extensions through the same Stripe or Paddle account — common for developers who ship a handful of small tools rather than one flagship product — the payout is a single lump sum covering all of them. Without per-extension tagging (Stripe's metadata fields, or separate Products/Prices per extension), you can't tell which extension actually drove the revenue, which makes it impossible to know which one is worth your maintenance time.
  • Fees, refunds, and currency conversion netted out before you see the number. The payout amount is already net of processing fees, any refunds issued that period, and currency conversion if you sell internationally. Booking the payout as gross revenue overstates your top line and hides your real margin.

The fix is a three-way match, done monthly at minimum:

  1. Processor sales report — gross transactions, itemized by product/extension if your account supports it, before fees and refunds are netted out.
  2. Processor payout report — the net amounts that actually moved to your bank, with fees and refunds broken out as separate line items.
  3. Bank statement — the deposits that actually cleared.

Match all three. The sales report tells you what you earned (revenue, recognized when the customer paid for the period of service). The payout report tells you the fee drag and refund activity to book as expenses and contra-revenue. The bank statement confirms cash actually arrived. When any two of the three don't tie out, that's your signal something needs investigating — a failed payout, a disputed chargeback, or a processor fee you didn't expect.

The Chrome-Specific Risk: Review Delays and Takedowns

Every payment stack has ordinary refund activity. Chrome extensions have an extra failure mode that's worth tracking as its own line item: Chrome Web Store review delays and policy takedowns.

When Google's review team flags a published extension for a policy violation, you get either an immediate takedown (moderate-to-severe violations) or a warning period of roughly 7 to 30 days to fix a minor one. Either way, users lose access to an extension they're actively paying for, and that generates a predictable spike in refund requests, chargebacks, and support tickets — developers have reported losing double-digit percentages of a month's subscription revenue to exactly this pattern, on top of the direct refunds.

Two bookkeeping habits make this manageable instead of a surprise:

  • Tag refunds and chargebacks by cause. A refund because a customer didn't like the extension is a normal cost of doing business. A refund because your extension was taken down for a week is a distinct, trackable business risk. Separating them (even just a memo field or a sub-account) lets you see, over a year, how much revenue volatility is coming from platform risk versus product-market fit.
  • Treat a pending review or an open policy warning as a disclosure-worthy event, the same way you'd flag a key-customer churn risk. If you're running the numbers to decide whether to raise prices, hire help, or take on a loan, an extension currently under a 30-day compliance warning is not "stable recurring revenue" — model it as at-risk until it clears review.

Recognize Revenue When You Earn It, Not When the Payout Lands

Subscription and one-time-purchase extensions need different treatment, and mixing them up is the single most common accounting mistake in this niche:

  • Monthly or annual subscriptions: recognize revenue evenly over the period the customer is paying for, not all at once when the charge hits. An annual plan paid up front creates a deferred revenue liability — you've been paid, but you haven't yet delivered eleven of the twelve months of service, so only 1/12th is revenue in the month of sale and the rest rolls off the balance sheet month by month.
  • Lifetime deals (a popular pricing model for extensions specifically, since users are wary of ongoing subscriptions for a browser tool): these still represent an obligation to provide updates and support indefinitely, so recognizing 100% of the cash as revenue on day one overstates your actual earned income for that month. A more defensible approach recognizes lifetime-deal revenue over a reasonable estimated service period (many businesses use 12–36 months as a proxy) rather than all at once.
  • One-time purchases with no ongoing obligation: recognize in full when delivered — this is the simple case.

MRR (monthly recurring revenue) is a useful growth metric, but it is not the same number as recognized revenue in your books. MRR tells you the run-rate of active subscriptions; your ledger should reflect what you've actually earned this period after deferrals.

A Ledger Structure That Survives Multiple Extensions

If you're keeping books in a plain-text, double-entry system, the fix for the "one payout, several extensions" problem is a chart of accounts that separates income by product from day one, plus explicit accounts for the deductions a payout report already nets out:

2026-07-05 * "Stripe payout - batch #4471"
  Assets:Bank:Checking                      842.17 USD
  Income:Extensions:FocusTimer             -510.00 USD
  Income:Extensions:TabArchiver            -390.00 USD
  Expenses:PaymentProcessing:StripeFees      41.83 USD
  Expenses:Refunds:FocusTimer                16.00 USD

Every payout becomes one transaction that reconciles the bank deposit against per-extension income, fees, and refunds as separate postings — instead of one opaque "Stripe deposit" line that tells you nothing about which product is actually profitable. Because the file is plain text, you can grep or query it by extension, by month, or by cause of refund, which is exactly the visibility a lump-sum payout report doesn't give you.

A Monthly Checklist

  1. Pull the processor's sales report for the month (gross, itemized by product if possible).
  2. Pull the payout report and separate fees, refunds, and chargebacks into their own line items.
  3. Confirm payout deposits against the bank statement.
  4. Book subscription and lifetime-deal revenue on a recognition schedule, not on receipt.
  5. Tag any refund tied to a Chrome Web Store review delay or takedown separately from ordinary churn.
  6. If you sell internationally through a straight payment processor (not an MoR), check whether your cumulative sales in any country have crossed a VAT/GST registration threshold.

Keep Your Extension Business's Books as Clean as Your Code

You wouldn't ship an extension without version control, and your finances deserve the same discipline — especially once payouts are split across several products and processors. Beancount.io offers plain-text, version-controlled accounting that lets you tag income by extension, track deferred revenue, and reconcile payouts against your bank statement with the same precision you bring to your codebase. Get started for free and see why developers are managing their books the same way they manage everything else they build.

Share this article