crxpaydocs

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

  1. 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?)

  2. 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).

  3. 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.

  4. 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.

  5. 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 integrationQuickstart
Setting up manifest.jsonManifest V3 setup
Wiring up Stripe + creating productsStripe Connect setup
Migrating an existing ExtPay extensionMigrate from ExtPay
Looking up a specific SDK methodSDK reference
Wondering about MV3 weirdnessManifest V3 guide
Wondering what the catch isPricing · Security & trust

Was this page helpful?

Your feedback shapes what we document next.