Introduction
Subscriptions for Chrome extensions. Drop-in SDK + Stripe Connect + dashboard.
What is crxpay?
crxpay is a paid subscription stack for Chrome extensions. Drop in our SDK, connect your Stripe account, and start billing — without writing a server, configuring webhooks, or building a customer portal yourself.
If you've used RevenueCat for mobile apps, that's the closest analogy. If you've used ExtPay, crxpay is what you graduate to when ExtPay's offline cache failures and missing analytics become a problem.
How the pieces fit together
┌───────────────────────────────────────────────────────────────┐
│ Your Chrome Extension (Manifest V3) │
│ │
│ popup.js ──┐ │
│ content.js ─┤── chrome.runtime.sendMessage │
│ ▼ │
│ background.js ──── @crxpay/sdk/background │
│ │ owns: signed cache, network, state machine │
└────────────┼───────────────────────────────────────────────────┘
│ HTTPS
▼
┌───────────────────────────────────────────────────────────────┐
│ crxpay API ─── Cloudflare Workers (D1, KV, R2, Queues) │
│ ├─ Authenticates the public API key │
│ ├─ Reads/writes customer + subscription state │
│ └─ Receives Stripe webhooks → updates DB → notifies SDKs │
└───────────────────────────────────────────────────────────────┘
▲
│ webhook
│
┌───────────────────────────────────────────────────────────────┐
│ Stripe (your Connected Express Account) │
│ ├─ Hosts checkout, billing portal, dunning emails │
│ ├─ Handles tax, fraud, 3DS, wallets (Apple/Google Pay/Link) │
│ └─ Pays you out directly, minus our 2.5% application fee │
└───────────────────────────────────────────────────────────────┘
Three boxes, one mental model:
- The SDK is the only thing that lives inside your extension. It's small (~14KB gzipped), has zero runtime dependencies, and never throws.
- The crxpay API is the only thing that talks to Stripe. Your extension never sees a Stripe key.
- Stripe holds the money. We don't. That's by design — it means we can't lose your revenue, freeze your account, or ship a bug that double-charges your customers.
The 30-second integration
import { CrxPay } from '@crxpay/sdk/background';
const client = CrxPay.configure({
apiKey: 'crxpay_pub_...', // copy from your dashboard
});
chrome.runtime.onMessage.addListener((msg, sender, send) => {
if (msg.type?.startsWith('CRXPAY_')) {
client.handleMessage(msg, sender).then(send);
return true;
}
});
import { CrxPay } from '@crxpay/sdk';
const result = await CrxPay.getSubscription();
if (result.ok && result.data.hasEntitlement('pro')) {
unlockProFeatures();
} else {
document.getElementById('upgrade').onclick = () => CrxPay.openCheckout();
}
That's a complete paid extension. From here, Quickstart walks you through installing, registering an extension, and taking your first test payment.
The five concepts you need to know
Public API key
Identifies your extension to the SDK. Starts with
crxpay_pub_. Safe to ship in your bundle — it can only read offerings and create checkout sessions for your extension. There is no private key. (Why?)Customer
A person who installed your extension and gave us their email. Created automatically the first time you call
CrxPay.identify(email), or implicitly when they pay (Stripe collects their email at checkout).Product → Price
A product is "what you sell" (e.g. Pro). A price is "how much, how often" (e.g. $9.99/month). One product can have many prices (monthly, annual, lifetime). crxpay creates both in your Stripe account on your behalf — you never touch the Stripe dashboard.
Entitlement
A capability flag the SDK checks. You write
subscription.hasEntitlement('pro'), you map products → entitlements in the dashboard, and you can swap pricing structures later without touching extension code.Offering
A bundle of prices the SDK shows on your paywall. The default offering is what
CrxPay.openCheckout()(no args) opens. You can have many offerings for A/B tests, geo-pricing, or campaign-specific pages.
Where to go next
| If you're… | Go to |
|---|---|
| New here, want a working integration | Quickstart |
Setting up manifest.json | Manifest V3 setup |
| Wiring up Stripe + creating products | Stripe Connect setup |
| Migrating an existing ExtPay extension | Migrate from ExtPay |
| Looking up a specific SDK method | SDK reference |
| Wondering about MV3 weirdness | Manifest V3 guide |
| Wondering what the catch is | Pricing · Security & trust |
Was this page helpful?
Your feedback shapes what we document next.