DEV Community

Cover image for How to add paid subscriptions to a Chrome extension without a backend
Miltos Tave
Miltos Tave

Posted on

How to add paid subscriptions to a Chrome extension without a backend

I sell a few Chrome extensions, and every time one of them was ready to charge for, I hit the same wall: the Chrome Web Store doesn't take payments anymore. Google stopped it charging money on 1 February 2021, so every paid extension now brings its own way to take the money and check who paid.

I ended up building my own service for this (Toolaby, more on that below, so take my opinions with that in mind). Here's how the options compare as of October 2026.

What you actually need

The check inside the extension is the easy part. Behind it you need:

  • a checkout for each plan
  • webhooks for payments, renewals, failed payments, refunds and disputes
  • somewhere that records who paid, for which plan, on which device
  • an answer the extension can trust, which is not a paid: true flag in chrome.storage that anyone can flip
  • sign-in on a second device
  • trials that don't reset when someone reinstalls

You can build all of that on Stripe yourself, or use something that already does it.

The options

ExtensionPay

The one most people know. Open source, made by Glen Chiacchieri after Google shut down Web Store payments. 5% of each charge, no monthly fee, money goes to your own Stripe account. You check extpay.getUser() and read user.paid. It supports Firefox too, and sign-in on other browsers is by email link. Its README notes that each getUser() call is a network request, and that using onPaid adds a permission warning at install.

crxbase

Newer (launched July 2026). Same model: 5% per transaction on your own Stripe, client.getUser() and user.paid, email one-time codes for sign-in, and a dashboard with MRR and trials.

Gumroad

Not built for extensions, but people use its licence keys. You verify a key with one request to its API, even from the browser. It's a merchant of record, so it handles sales tax for you, which is a real plus. The cost is 10% + 50¢ a sale plus card processing, and enforcement is on you: how many devices a key works on, and whether an ended subscription still unlocks.

Lemon Squeezy

Also a merchant of record, 5% + 50¢ a transaction plus extras (1.5% for international buyers, 0.5% on subscriptions). Its License API has activation limits per key, which is nicer than Gumroad for this. Stripe owns it now and is moving its users to Stripe Managed Payments, so I'd check where that's going before building on it.

Paddle

Merchant of record at 5% + 50¢, but Paddle Billing no longer generates licence keys. You'd need your own webhook handler and server.

Stripe alone

Lowest fees (2.9% + 30¢ on US cards, plus 0.7% for Billing on subscriptions) and the most work: everything in the list above is yours to build and keep running.

Checking whether someone paid

Whatever you pick, put the real check right before the paid action, in the background, not just in what the popup shows. Code on the user's machine can be changed, so the thing you trust should be signed by a server, not a flag in local storage.

With Toolaby it looks like this:

// background.js
import { toolaby } from './toolaby.js';

toolaby.startBackground({
  handlers: {
    async exportAll({ tableIds }) {
      const permit = await toolaby.gate();
      if (!permit.allowed) return { permit };
      return { ok: true, file: await buildExport(tableIds) };
    },
  },
});
Enter fullscreen mode Exit fullscreen mode
// popup.js
const r = await chrome.runtime.sendMessage({ action: 'exportAll', tableIds });
if (r.permit) return toolaby.showPaywall(r.permit);
save(r.file);
Enter fullscreen mode Exit fullscreen mode

gate() checks a token Toolaby signs for that device, so a paid user gets through with no request and keeps working offline for a while. For drawing the UI there's getUser(), which gives you paid, the plan and the subscription status.

Why I built another one

Mostly the missing pieces. I kept rebuilding device limits, trials that survive a reinstall and seats for teams, and a percentage fee grows with every sale. Toolaby takes 0.5% of a sale, or $25 a month per workspace with no fee, on your own Stripe account. It does device limits per plan, seats, bundles of several extensions, and analytics including why people uninstall. It also has an MCP server, so Claude Code or Cursor can set up the plans and the gating for you.

What I'd pick

  • First paid extension, no backend: one of the extension services. Compare the fee at the sales you expect.
  • Sales tax is the thing you dread: a merchant of record.
  • You already run a backend with accounts: Stripe alone.

I wrote up a longer side-by-side, with links to each product's own pricing page, here: https://toolaby.app/guides/chrome-extension-payment-tools

If you've shipped a paid extension, I'd like to hear what you used and what annoyed you about it.

Top comments (0)