crxpay
Migration · ExtPay → crxpay

Migrate from ExtPay in an afternoon.

A drop-in, API-compatible adapter keeps every extpay.getUser() call working — while you unlock entitlements, paywalls, analytics, and a 2.5% fee(half of ExtPay’s 5%).

2–4 hrsTypical migration
ZeroUser downtime
50%Fee savings

Why switch

Everything ExtPay does — plus what it doesn’t.

crxpay covers the same subscription primitives you already rely on, then layers the pieces ExtPay asks you to build yourself.

5%
ExtPay
2.5%
crxpay

Keep 2.5% more of every sale. ExtPay takes 5% flat. crxpay is 2.5% — and your first $2,500 in tracked revenue is free.

Pro entitlement · active
HMAC-verified · offline-ok
Network: offline
sub.hasEntitlement('pro')
// → true

No more ‘subscription disappeared’ tickets. HMAC-signed local cache keeps entitlements valid on flaky networks. ExtPay re-fetches on every check.

service-worker.ts
// MV3-native, CORS-safe
await crxpay.ready();
const pro = sub.hasEntitlement(‘pro’);
0 CORS errors · 0 workarounds

Built for MV3 service workers, not against them. Every SDK call is CORS-safe in Manifest V3. No background-page workarounds, no re-auth loops.

v1 · $9.99
v2 · $7.99
+18% CVR

Ship a paywall update without a store re-review. No-code editor, remote deploy, targeting, and A/B out of the box. ExtPay stops at the payment link.

Migrate in an afternoon. One adapter package, one import swap, then run the CLI. Users stay signed in, subscriptions stay active.

See the migration guide →
1
Install
2
Swap import
3
Run migrate
Ship

Feature-by-feature, side by side.

The honest version. Built for Chrome extension devs evaluating their next few years.

ExtPay
crxpay
Platform fee
5%
2.5%+ first $2,500 free
MV3 service-worker support
Workarounds
Native
Offline-signed entitlement cache
Entitlements (Pro / Team / etc.)
No-code paywall editor
A/B testing & remote deploy
Customer dashboard & analytics
Basic
Cohorts + charts
Stripe Connect (your own account)
Webhook dispatch to your stack
Migration adapter
@crxpay/compat-extpay

How it works

Three steps. One afternoon.

1
Step 01

Install the compat layer

One package replaces ExtPay. Drop in the adapter and your existing extpay.* calls continue to resolve — now against crxpay.

pnpm add @crxpay/sdk @crxpay/compat-extpay
2
Step 02

Swap one import

Change a single line in your background service worker. All your existing user-check branches keep working untouched.

// was:
import ExtPay from 'extpay';
// now:
import { ExtPay } from '@crxpay/compat-extpay';
3
Step 03

Mirror your users, then flip the switch

Run crxpay migrate once — it imports every ExtPay user and links Stripe customers. Publish, and the next paywall check reads from crxpay.

npx crxpay migrate \
  --from extpay \
  --api-key <your-extpay-key>

Drop-in compatible

Your old code doesn’t need to change.

extpay.getUser(), onPaid, and openPaymentPage all keep their signatures. The adapter forwards them to crxpay, returns the exact shape ExtPay returned, and unlocks entitlements behind the scenes.

  • Zero rewrite — 1 import change
  • Same user IDs, same install dates
  • Entitlements available when you want them
background.ts
+import { ExtPay } from '@crxpay/compat-extpay';
· 
·const extpay = ExtPay('my-ext');
·extpay.startBackground();
· 
·extpay.onPaid.addListener(async (user) => {
· // works exactly as before
· if (user.paid) state.set('pro', true);
·});
· 
·// unlock the new stuff when you want it:
+const sub = extpay.asCrxpay();
+if (sub.hasEntitlement('team-seat'))
+ showTeamUi();

The questions we always get.

Ready to grow?

Our entire suite of features comes standard — and your first $2,500 in tracked revenue is free.