Google Chrome Extension Payment in 2026: What It Means (3 Different Things), Why Native Payments Died, and the Complete Developer Guide to Taking Payments Inside Your Extension

"Google Chrome extension payment" is one of the most ambiguous search terms in the Chrome ecosystem. If you Google it, you'll get a mess: crypto wallet extensions like MetaMask, merchant payment plugins like PayJunction, Google Pay's autofill feature for online checkout, and a handful of tutorials on how developers can monetize their extensions. All under the same phrase.

This post sorts it out, then goes deep on the developer question — because that's the one where the real work lives. Google killed the native Chrome Web Store payment system on February 1, 2021, and every paid extension shipping today is on a third-party stack. The decisions you make about which stack determine whether you spend an hour shipping or eight weeks debugging webhooks.

I've built payment systems in two Chrome extensions in the last few months and went through every approach. Long post. Save it.

Disambiguation: which "Google Chrome extension payment" are you actually searching for?

Three different things people mean when they type this phrase:

1. "I'm a Chrome user and I want to pay for something more easily online." You're looking for browser extensions that help you pay — wallet extensions (MetaMask, TronScan), price-comparison tools (Honey, Capital One Shopping), Google Pay's built-in autofill, or a buy-now-pay-later browser extension. These are end-user tools. Not what this post is about.

2. "I'm a merchant and I want to accept payments via a browser extension I install." You're looking for tools like PayJunction's No-code Payments Integration — a Chrome extension you install that lets your existing business software take payments. These are B2B point-of-sale tools. Also not what this post is about.

3. "I'm a developer and I want to take payments inside a Chrome extension I'm building." You want to charge users for premium features in your own extension. This is what the rest of the post is about. Google killed the native payments API in 2021, so you're building on a third-party stack — Stripe, ExtPay, CRXPay, Lemon Squeezy, or DIY.

If you came here for #1 or #2, you can stop reading. The rest is the developer monetization guide.

Why Google Chrome extension payments are weirdly hard

Stripe is well-documented. Chrome extensions are well-documented. Combining them is where everything quietly falls over. Five structural reasons:

1. There is no native payment API in Chrome anymore. Google deprecated Chrome Web Store payments on February 1, 2021. Whatever you ship, you bring yourself.

2. Chrome extensions can't run a backend. The extension is JavaScript that runs in the user's browser. Stripe webhooks need a server. So you're already building two things: an extension AND a backend.

3. Manifest V3 service workers die. Background scripts terminate after ~30 seconds idle. Anything in memory is gone. Half the "add Stripe to your Chrome extension" tutorials on Google are written for the persistent-background MV2 model and silently break in production today.

4. Manifest V3 bans remote code execution. You cannot lazy-load Stripe.js from a CDN inside the extension. Hosted Stripe Checkout in a new tab is the only correct UI pattern.

5. Your extension has no user accounts by default. A Chrome extension is just JavaScript running in the browser. There's no login, no user ID, no email — until you build one. Most payment platforms assume you already have these. You don't.

If you skip those five realities, you'll spend three weekends on what should be a one-week build.

The history: what Google killed and when

For developers who weren't around for the original system, here's what Google deprecated:

Chrome Web Store payments was a built-in payment infrastructure that let Chrome extension developers:

  • Charge an upfront price for their extension (one-time)
  • Run subscription billing (monthly/annual)
  • Sell in-app purchases (google.payments.inapp.buy())
  • Manage free trials
  • Issue licenses tied to the user's Google account
  • Take a 5% transaction fee (paid to Google)

It was the way to monetize a Chrome extension for a decade. Users paid through their Google Wallet, the extension called Google's API to check userLicense, done.

The deprecation timeline:

DateWhat happened
March 27, 2020New paid items temporarily disabled
September 2020Permanent deprecation announced
December 1, 2020Free trials disabled
February 1, 2021All payments disabled
Post-Feb 2021License retrieval API still worked for a while
EventuallyLicensing API fully removed

Google's stated reason: the payment ecosystem evolved, plenty of third-party options exist, in-browser payments never scaled the way they imagined. Translation: Google didn't want to maintain a third payment rail competing with Apple's App Store and Google Play.

The Chrome Web Store still hosts extensions. It just doesn't process money anymore.

What "Google Chrome extension payment" looks like in 2026 (the short answer)

The native system is gone. What exists instead:

  1. Chrome Web Store hosts the extension (free listing — Google sees no money)
  2. Third-party payment processor handles the actual transactions (Stripe + a platform/SDK)
  3. Your backend holds subscription state
  4. Your extension checks entitlement via your backend

The Chrome Web Store has zero involvement in the payment flow. Google doesn't see your revenue, doesn't take a cut, doesn't manage your subscriptions, doesn't issue licenses. Your extension is "free" from Google's perspective; the payment happens entirely outside the store.

This is officially supported — Chrome Web Store policy explicitly allows third-party payment processors. But you must comply with their disclosure rules (more on that below).

The architecture every Chrome extension payment system needs

Regardless of which path you pick below, here are the seven components you're building or buying:

┌──────────────────────┐                ┌──────────────────┐
│  Chrome Extension    │                │   Your Backend   │
│                      │  fetch via SW  │                  │
│  ┌────────────────┐  │  (CORS-safe)   │  ┌────────────┐  │
│  │ Service Worker │◄─┼────────────────┼─►│ /api       │  │
│  │ + signed cache │  │                │  │ entitlement│  │
│  └────────┬───────┘  │                │  └────────────┘  │
│           │          │                │  ┌────────────┐  │
│  ┌────────▼───────┐  │  open new tab  │  │ /webhook   │  │
│  │ Popup / pages  │──┼────────────────┼──┤ Stripe     │◄─┼─── Stripe
│  │ (read cache)   │  │                │  └────────────┘  │
│  └────────────────┘  │                │  ┌────────────┐  │
└──────────────────────┘                │  │ User DB    │  │
         ▲                              │  │ + entitle- │  │
         │                              │  │ ments      │  │
         └──── hosted Stripe Checkout ──┴──┴────────────┘  │
              opens in a new tab                          │

The seven components, none optional:

  1. Chrome extension with popup + MV3 service worker + (optionally) content scripts
  2. Backend with HTTPS endpoint (Cloudflare Workers, Vercel, Railway, Fly — anything serverless)
  3. Stripe Checkout hosted page (never collect cards inside the extension — PCI violation + Chrome Web Store policy violation)
  4. Webhook listener at your backend with signature verification + idempotency
  5. Database for user → Stripe customer → entitlement mapping
  6. Signed entitlement token (HMAC) the extension caches and verifies offline
  7. MV3 service worker with chrome.alarms-based hourly refresh

Build all seven yourself = 3–8 weeks. Use a platform = 5 minutes to 1 hour.

The 4 ways to take payments in a Google Chrome extension

Option 1: DIY with Stripe + your own backend

The maximum-control path.

Stack: Stripe Checkout + Stripe Webhooks + Stripe Billing Portal + your backend + your DB + your own SDK inside the extension.

Fees: Stripe ~2.9% + 30¢. Zero platform fee.

Honest time estimate:

  • First time wiring Stripe webhooks for subscriptions: 3–8 weeks
  • Done it before: 1–2 weeks
  • Plus ongoing maintenance for every webhook schema change and MV3 lifecycle quirk

The "no-server" variation — Stripe Payment Links + Cloudflare Workers + D1 — works fine for one-time purchases. Quietly breaks on subscriptions. You'll need to extend the logic, and you're now building a full subscription state machine on Cloudflare Workers. The blog post that floats around making this look like a weekend project assumes one-time purchases only.

Best fit: Backend-confident teams. Custom pricing models. Extensions at $100K+ ARR where 2–5% in saved fees funds real engineering time.

Option 2: ExtensionPay (ExtPay) — the indie default since 2021

How it works: Drop in ExtPay.js, sign up at extensionpay.com, connect Stripe via Stripe Connect (Standard accounts), call extpay.getUser() to check user.paid.

Fees: 5% platform fee on top of Stripe's ~3%. ~8% total of your revenue.

Pros:

  • Fastest path to first payment (~1 hour)
  • Established platform — helped indie devs earn $500K+ combined since 2021
  • Open-source client-side library
  • Cross-browser (Chrome, Edge, Firefox, Opera, Brave)
  • Multi-device login via email magic link

Cons:

  • Predates Manifest V3. Docs literally instruct you to redeclare ExtPay inside chrome.storage.local.get callbacks because service workers don't preserve state.
  • Single paid boolean. Multi-tier pricing (Pro/Team/Lifetime) requires hacking on top via user.plan.nickname string parsing.
  • No paywall editor — you build the UI yourself in your popup, every paywall iteration is a Chrome Web Store re-publish.
  • No A/B testing.
  • No real analytics dashboard — you cross-reference between ExtensionPay's minimal interface and your Stripe dashboard.

Best fit: Validating whether anyone will pay at all. $0 → ~$2K MRR phase.

Option 3: CRXPay — the modern MV3-native option

The newer entrant rebuilt from scratch around Manifest V3 and the things ExtPay never added.

How it works: CRXPay ships u/crxpay/sdk with three entry points (background, popup, content) mirroring MV3 context separation. Call configure() once in the service worker, call hasEntitlement('pro') anywhere.

Fees: First $2,500 in tracked revenue is free, then 2.5% — half of ExtPay's 5%. On a $10K MRR extension, that's $250/month back versus $500/month. The fee delta alone funds the migration in the first month at most realistic revenue levels.

Pros:

  • MV3-native by design. Background script owns SDK state, chrome.alarms-based refresh (not setInterval), top-level event listener registration, message router with return true documented inline.
  • Multi-tier entitlements. hasEntitlement('pro' | 'team' | 'lifetime') instead of one boolean. Multi-tier pricing works natively.
  • HMAC-signed offline entitlement cache. Pro access survives flaky networks and service-worker registration bugs.
  • Stripe Express Connect-native. Your Stripe account, they never touch your money. One-click Stripe onboarding.
  • No-code paywall editor with 8 templates (games, AI credits, lifetime, trial-first, productivity, etc.).
  • Remote-deploy paywalls. Change a price, every installed extension fetches the new version on next popup open. No Chrome Web Store re-review for copy changes.
  • Bayesian A/B testing built in.
  • Native MRR / trial→paid / churn / LTV dashboard.
  • Self-serve Stripe Billing Portal pre-authed via one link.
  • Webhooks to your stack (Customer.io, Braze, warehouse).

Migration if you're already on ExtPay or DIY Stripe: API-compatible adapter — u/crxpay/compat-extpay keeps your existing extpay.getUser(), onPaid, and openPaymentPage calls working. One import swap, npx crxpay migrate, users stay subscribed.

Time to first payment: ~5 minutes via the quickstart. I timed it on a fresh project.

Best fit: Anyone past the "do users pay" validation phase. Anyone shipping multi-tier pricing. Anyone who wants A/B testing without rebuilding the infrastructure.

Watch out: Newer product than ExtPay. The mitigation is the compat adapter — if it doesn't work out, you leave the way you came in. Stripe Connect across all third-party options means your customer data and revenue history are portable regardless.

Option 4: Merchant of Record (Lemon Squeezy, Paddle, Dodo Payments)

The "they handle global tax compliance" path.

Fees: Lemon Squeezy 5% + 50¢. Paddle 5% + 50¢. Dodo varies.

Pros: EU VAT, UK VAT, US sales tax, GST handled — they're the seller of record. Significant if you sell internationally.

Cons: No Chrome extension SDK. You're still building the entitlement check, the MV3 service-worker plumbing, the message routing, the signed offline cache yourself.

Best fit: Extensions with serious EU/UK/global revenue where tax compliance is the actual headache.

Head-to-head comparison

ApproachSetup timePlatform feeMV3-nativePaywall editorMulti-tier entitlementsA/B testing
DIY Stripe3–8 weeks0%You build itYou build itYou build itYou build it
ExtensionPay~1 hour5%WorkaroundsNoOne boolNo
CRXPay~5 min2.5% (first $2.5K free)YesYes (8 templates)YesYes (Bayesian)
Lemon Squeezy / Paddle~1 day5% + 50¢You build itNoLimitedNo

The 8 MV3 footguns that break Google Chrome extension payments

This is the part nobody documents and the reason 80% of "my payment isn't unlocking" support tickets exist. Test for every one whether you're building yourself or evaluating a platform.

1. Service workers die after ~30 seconds idle. Anything in a global variable is gone. Persist payment state to chrome.storage.local:

// ❌ BREAKS in MV3
let userIsPaid = false;

// ✅ WORKS
async function isPaid() {
  const { sub } = await chrome.storage.local.get('sub');
  return sub?.paid === true;
}

2. setInterval doesn't survive a service worker restart. Use chrome.alarms:

// ❌ BREAKS
setInterval(refreshSub, 3600_000);

// ✅ WORKS
chrome.alarms.create('refreshSub', { periodInMinutes: 60 });
chrome.alarms.onAlarm.addListener((a) => {
  if (a.name === 'refreshSub') refreshSub();
});

3. return true in your async message listener. Without it, Chrome closes the message channel before your async response fires:

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.type === 'CHECK_SUB') {
    checkSub().then(sendResponse);
    return true; // ← THIS LINE OR EVERYTHING BREAKS
  }
});

4. Content scripts cannot fetch your payment API directly. CORS blocks them. Route through the service worker via chrome.runtime.sendMessage.

5. host_permissions must include your payment API domain. Otherwise fetch() silently fails in production but works in dev.

6. Remote code execution is banned in MV3. Can't load Stripe.js from a CDN. Bundle it or redirect to hosted Stripe Checkout in a new tab.

7. Service workers occasionally fail to register. Long-running Chromium bug. A signed offline entitlement cache means Pro access keeps working when the SW is broken.

8. The popup window dies when the user clicks away. Background service worker owns state; popup is the view.

Chrome Web Store policy rules for paid extensions (2026)

Google still controls the listing and has explicit rules for paid extensions. These are the #1 reasons paid extensions get rejected.

  • You must disclose payment requirements on the Chrome Web Store listing. If your extension requires a subscription, that must be in the description prominently. You can't say "Free!" and then paywall the core feature.
  • You must have a privacy policy. Hosted URL, linked from the dashboard. 2026 policy requires granular data type disclosures in the manifest itself.
  • You cannot collect cards inside the extension. PCI compliance violation + Chrome Web Store policy violation. Hosted checkout in a new tab is the only acceptable pattern.
  • You must justify every permission. Including host_permissions for api.stripe.com or your payment API domain.
  • Cancellation must be possible from inside the extension. A "go to our website" link counts. A Stripe Billing Portal link counts. Hiding cancellation gets you 1-star reviews fast.
  • Repetitive content is banned. You cannot ship a "free version" + "paid version" as separate extensions to game the marketplace. Single freemium listing only.

The "can users hack my extension to bypass payment?" question

Short answer: yes, partially. Build for the 99% who don't.

Chrome extension source code is technically open. A determined user can unpack any extension, edit the entitlement check, and grant themselves Pro. There's no perfect DRM.

What you can do:

  • Server-side feature gating for expensive operations. If your extension calls an LLM that costs you real money, gate that call server-side. Even if the user fakes paid: true client-side, your backend refuses to do the work.
  • HMAC-signed entitlement tokens. Backend signs the entitlement payload; extension verifies the signature before unlocking. User can edit chrome.storage.local, but your verification function rejects it.
  • Server-side validation on critical actions. Anything that affects another user, sends an email, or hits a paid API validates on your backend.
  • Don't worry about UI gates for cheap features. The 1% who would unpack and modify the extension wouldn't have paid anyway.

Mozilla's official guidance: "It's better to focus on making a good product for the majority of users that won't hack your extension."

How to actually pick

Stripped of marketing:

  • Validating, $0 MRR? ExtPay. Ship today. Don't optimize for fees on $0 revenue.
  • Past validation, want a real paywall + A/B + analytics? CRXPay. The fee math pays for the migration in month one and the ExtPay-compatible adapter is one import swap.
  • Backend team, $200K+ ARR target, zero lock-in priority? DIY Stripe. Plan 4–6 weeks honestly.
  • Global revenue, tax compliance is the real headache? Lemon Squeezy / Paddle. Build the extension-side plumbing yourself.

Pre-launch checklist

The 14-item list that prevents 90% of post-launch payment failures:

  • [ ] Stripe test card 4242 4242 4242 4242 works end to end
  • [ ] Failed payment card 4000 0000 0000 0341 triggers dunning
  • [ ] 3DS card 4000 0027 6000 3184 works (EU traffic)
  • [ ] Kill the service worker manually in chrome://serviceworker-internals — does state recover?
  • [ ] Reinstall test — does Pro come back via email?
  • [ ] Cancel test — keeps access until period end?
  • [ ] Refund test — entitlement actually revoked, when?
  • [ ] Offline test — DevTools Network → Offline — does Pro still work?
  • [ ] Edge browser test (Chromium too, doubles TAM)
  • [ ] Clean Chrome profile test (no stale chrome.storage.local)
  • [ ] Privacy policy linked in Chrome Web Store dashboard
  • [ ] "Cancel anytime" visible somewhere accessible
  • [ ] Chrome Web Store description discloses paid features
  • [ ] Stripe webhook endpoint signature verified + idempotent

TL;DR

  • "Google Chrome extension payment" means three different things — end-user wallet/payment extensions (MetaMask etc.), merchant payment integration tools (PayJunction etc.), and developers taking payments inside their own extensions. This post is about the third.
  • Chrome Web Store payments died on February 1, 2021. Every paid extension shipping today is on a third-party stack. Google takes zero cut of third-party Stripe revenue — the $5 one-time developer fee is the only money Google sees.
  • Every Chrome extension payment system needs 7 components: extension + service worker + backend + webhook listener + DB + signed entitlement + hosted Stripe Checkout. None optional.
  • DIY Stripe = 3–8 weeks of work, 0% platform fee. Best for backend teams.
  • ExtensionPay (ExtPay) = ~1 hour, 5% fee, predates MV3, no paywall editor / A/B / analytics. Best for validation.
  • CRXPay = ~5 minutes, 2.5% fee with first $2,500 free, MV3-native by design, paywall editor + A/B testing + analytics + multi-tier entitlements included, drop-in ExtPay-compatible migration adapter. Best for anyone past validation.
  • Lemon Squeezy / Paddle = ~1 day, 5% + 50¢, handles global tax. Best for international revenue.
  • 8 MV3 footguns will silently break your payment system: setInterval, missing return true, CORS on content scripts, missing host_permissions, remote code bans, service worker death, registration failures, popup-held state.
  • Chrome Web Store policy requires: clear paid-feature disclosure, privacy policy, hosted checkout (no card collection inside extension), accessible cancellation, justified permissions.
  • Stripe Connect across all third-party options means your customer data and revenue history are portable — you're never locked in.

If you've shipped payments in a Google Chrome extension and your time-to-first-payment was dramatically different from these estimates — especially if you did the DIY Stripe path and finished in under 2 weeks — drop your specifics in the comments. The public data on Chrome extension payment systems is thin, mostly self-reported, and the more real timelines we share the better the next wave of paid extensions can plan.

Posted May 10, 2026, 10:08 PM UTC

10
Loading comments…