Chrome Extension Payments
ASecurityAdd real payments to a Chrome MV3 extension — monthly/yearly subscriptions, a lifetime one-time purchase, PayPal (Subscriptions + Orders API) and USDT/BEP20 crypto payments, server-derived entitlements, plan changes, discount codes, an affiliate program, and an admin dashboard. Trigger for "add payments to chrome extension", "subscription extension", "paypal subscription", "accept USDT", "crypto payments", "lifetime license", "paywall", "pro plan", "monetize my extension". Ported from a shipp...
- 2 stars
- 0 votes
- 0 copies
- 1 view
- Added September 24, 2026
Works with
Security analysis
100/100Pro scans all 8 files and shows the line behind each finding
npx -y skills add thomaslimited/chrome-extension-skills --skill chrome-extension-payments --agent claude-codeAre you the author of Chrome Extension Payments?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/thomaslimited-chrome-extension-payments)---
name: chrome-extension-payments
description: Add real payments to a Chrome MV3 extension — monthly/yearly subscriptions, a lifetime one-time purchase, PayPal (Subscriptions + Orders API) and USDT/BEP20 crypto payments, server-derived entitlements, plan changes, discount codes, an affiliate program, and an admin dashboard. Trigger for "add payments to chrome extension", "subscription extension", "paypal subscription", "accept USDT", "crypto payments", "lifetime license", "paywall", "pro plan", "monetize my extension". Ported from a shipped MV3 + Hono/Postgres backend: verified webhooks, idempotent settlement, exact-amount crypto invoices, reconciliation jobs — not a theoretical sketch.
license: MIT
---
# Chrome Extension Payments
Monetize a Chrome MV3 extension with a real backend: subscriptions, a lifetime purchase, two payment
rails (PayPal + USDT/BEP20), server-derived entitlements, and the admin/affiliate/discount machinery
around them. Every pattern here shipped in production; alternatives are noted, not built out.
## Scope — read this first
This skill does **not** cover:
- **Login / accounts** — sessions, Google SSO, email/password. Use `chrome-extension-auth` first; this
skill assumes `requireAuth` middleware and a `users` table already exist.
- **Chrome Web Store listing, permission justifications, screenshots** — use `chrome-web-store-listing`.
- **Deploying the backend, TLS, CI/CD** — use `chrome-extension-deploy`.
- **MV3 basics** (WXT, messaging, storage/sync, build tooling) — use `chrome-extension-dev`.
Assumed stack: Hono (Node) API, raw `pg` (no ORM), Postgres, a WXT/React extension with a background
script that is the only holder of the session token. Swap the framework; keep the shape.
## 1. Choose your payment providers
| Provider | Fee | Merchant of record (tax) | Chargebacks | Works where Stripe doesn't | Setup cost |
|---|---|---|---|---|---|
| **PayPal** (Subscriptions + Orders API) | ~4.4% + $0.30 | No — you owe your own sales tax/VAT | Yes, PayPal-mediated | Yes | Low — product/plan API + one webhook |
| **USDT (BEP20)** | Network gas only (~$0.10–0.30), no processor fee | No — you are the merchant | No — on-chain is final | Yes, anywhere crypto is legal | Medium — RPC reads, address-activity webhook |
| Stripe | ~2.9% + $0.30 | No | Yes | No — blocked/unavailable in many countries, and Chrome Web Store extension billing has its own restrictions | Low, best DX |
| Paddle / Lemon Squeezy | ~5% flat | **Yes** — they collect and remit tax as merchant of record | Handled by them | Yes | Low, but you give up direct control of checkout UI and payout timing |
**Decision**: this skill implements **PayPal + USDT** — the proven path when Stripe is unavailable or
undesirable and you want to keep 100% of a crypto sale with no chargeback risk. If you have US/EU
customers and want tax handled for you, evaluate Paddle or Lemon Squeezy instead (their hosted-checkout
docs cover that path; do not hand-roll it here). If Stripe is available in your market and you don't
need a crypto rail, Stripe's Billing + Checkout Session APIs are simpler than PayPal's — this skill does
not template it, but the entitlement/webhook-idempotency patterns below transfer directly.
## 2. Entitlement model
- Tiers are `free | pro` (or your tier set). One column, `users.tier`, is the fast-read projection —
never the source of truth.
- Source of truth is derived server-side from three places, in this priority: `users.lifetime_at` (set,
never unset except on refund) OR `users.comp_access` (admin-granted) OR the newest row in
`subscriptions` with `status = 'active'` AND `current_period_end > now()`.
- **Never trust the client for entitlement.** `GET /v1/me` returns `{ tier, lifetime, subscription }`;
the extension caches this response and gates features off the cache, but every privileged API call
re-checks the database, not the cached flag.
- The extension caches `/me` in `storage.local`, refreshes it on a daily `alarms` tick (re-armed on
`onStartup` — Chrome can drop alarms across a browser restart), and immediately after any checkout,
claim, or cancel action resolves.
- Client-side "is this still Pro" also compares the cached `current_period_end` against `Date.now()` so
a lapsed plan doesn't read as Pro for up to a day between refreshes.
- **Graceful downgrade**: losing Pro never deletes data. Existing saved items stay readable and
editable; only the "create new" action is gated behind the entitlement check.
Full code (types, `isProFromMe`, `useEntitlement`, alarm wiring, message-passing contract) in
`references/entitlements-and-checkout.md`.
## 3. Data model
Postgres, raw SQL, no ORM. Every `CREATE TABLE`/`ALTER TABLE` is `IF NOT EXISTS` so the same script
runs safely on every boot — this is your only migration system. Money as `NUMERIC(10,2)` (USD) or
`NUMERIC(20,8)` (USDT); every purchase row carries `created_at`, and cancellable rows carry
`cancelled_at` + `cancelled_by`. See `references/data-model.md` and `assets/schema-template.sql`.
## 4. Numbered workflow
1. **Define the catalog** — plan codes, prices, tiers, one lifetime item — in one server-side module
(`plans.ts`). The client never sends a price; it sends a plan *code*.
2. **Apply the schema** (`assets/schema-template.sql`) — users, subscriptions, webhook_events,
one_time_purchases, crypto_invoices, crypto_transfers, discount_codes, affiliate tables.
3. **Wire PayPal**: create the product + plans once with a setup script, implement
`createCheckout` / `createOrder` / `captureOrder` / `verifyWebhook` / `parseWebhook`, mount the
webhook route. See `references/paypal.md`.
4. **Wire USDT/BEP20**: exact-amount invoices, a minimal JSON-RPC reader with failover, the
Alchemy address-activity webhook, and the manual tx-hash claim fallback. See
`references/usdt-bep20.md`.
5. **Build the in-popup checkout UX**: plan picker → PayPal approval opens a new tab (never an embedded
SDK) → static return/cancel pages served by the API → popup polls invoice/subscription status. See
`references/entitlements-and-checkout.md`.
6. **Apply billing events idempotently**: claim the webhook event id before processing, release the
claim on failure so the provider's retry gets a real attempt, mark it processed only after every
side effect (tier write, discount redemption, commission) has committed.
7. **Add plan changes**: upgrade-only in an MVP (bigger interval/tier), prorate on PayPal, no proration
on the crypto rail (a new full-price pass stacks onto the end of the current one). See
`references/plan-changes-discounts-affiliate.md`.
8. **Add discount codes and affiliate**: first-charge-only discounts with redemption limits; referral
codes discount the referee and pay the referrer a commission held for N days before payout. Rates
live in a `app_settings` DB row, editable at runtime, not in env vars.
9. **Build the admin API**: overview/revenue/users/orders/withdrawals endpoints behind a single shared
secret compared in constant time. Never behind the same auth as customers.
10. **Run maintenance jobs**: a scheduler tick that matures commissions, expires lapsed subscriptions
(with a grace check so cancellation never revokes an already-paid period), sweeps confirmed crypto
invoices, expires stale ones, and reconciles any invoice that reached `paid` but never got its
entitlement applied (crash recovery).
11. **Test before going live**: a `paypal:check` style script that verifies credentials, webhook
subscriptions, and plan pricing without charging anything; a `crypto:simulate` script against a
faked chain and a scratch database; manual webhook replay. See `references/testing-and-operations.md`.
## 5. Plan-change quick table
| From → To | Same provider | Cross-provider |
|---|---|---|
| Month → Year (PayPal) | Prorated new subscription, charged the difference now | n/a |
| Month → Year (crypto) | New full-price pass stacks onto the end of the current one — no proration | n/a |
| Year → Month | **Not supported in an MVP** — no clean way to apply it without re-billing or a manual revise call; let it run out | Same |
| Any plan → Lifetime | Always allowed. **Buying Lifetime auto-cancels every live subscription** so the customer is never billed again for something Lifetime already covers | Same |
| Lifetime → anything | Blocked — no further purchase is offered once Lifetime is granted | — |
## 6. Security checklist
- [ ] **Verify every webhook signature** before parsing the body as trusted: PayPal via
`/v1/notifications/verify-webhook-signature`, Alchemy (or your chain provider) via HMAC-SHA256
over the raw body with `timingSafeEqual`. An unverified webhook is a free-tier endpoint.
- [ ] **Never trust a client-supplied amount or price.** The client sends a plan *code*; the server
looks up the price. A discount is priced server-side from the code, not from a client-sent
percentage.
- [ ] **Idempotency everywhere money moves**: webhook event id claimed via `INSERT ... ON CONFLICT`,
capture/settle writes guarded by a conditional `UPDATE ... WHERE status <> 'paid'`, and any
insert that could double-credit backed by a real unique constraint (not just an application check).
- [ ] **Secrets stay server-side only** — API keys, webhook signing keys, the admin secret. Nothing
payment-related belongs in the extension bundle; it is publicly downloadable.
- [ ] **Compare secrets in constant time** (`crypto.timingSafeEqual` over a hash, not `===`) for the
admin secret and any webhook HMAC check.
- [ ] **Grant access only after money actually moved.** PayPal order *approval* is not payment —
capture it and check the capture's own status is `COMPLETED` before granting anything.
- [ ] **Rate-limit checkout, discount lookup, and crypto claim endpoints** — a discount/claim endpoint
is a guessing oracle otherwise.
- [ ] **Log every refund/chargeback and act on repetition** — disable the account outright on a
chargeback; flag after N ordinary refunds.
- [ ] **Refuse to boot in production with placeholder secrets** (default session secret, missing admin
secret, missing allowed-origins list, `.env.example` values still in place).
## 7. References
- `references/entitlements-and-checkout.md` — tier model, caching, alarms, feature gating, popup checkout flow, message-passing contract.
- `references/paypal.md` — catalog setup script, Subscriptions + Orders API, webhook verification and idempotent event handling, reconciliation, sandbox vs live.
- `references/usdt-bep20.md` — exact-amount invoices, RPC reader with failover, Alchemy webhook, manual claim, confirmations/expiry, stacking, crypto discount, simulation.
- `references/plan-changes-discounts-affiliate.md` — upgrade/downgrade rules, discount code validation, affiliate rates/attribution/payouts, admin auth.
- `references/data-model.md` — schema walkthrough, money representation, audit fields, key relationships.
- `references/testing-and-operations.md` — verification scripts, webhook replay, maintenance jobs, production checklist.
- `assets/schema-template.sql` — generic, trimmed, idempotent Postgres schema to start from.
Files in this skill
- SKILL.md
- assets/schema-template.sql
- references/data-model.md
- references/entitlements-and-checkout.md
- references/paypal.md
- references/plan-changes-discounts-affiliate.md
- references/testing-and-operations.md
- references/usdt-bep20.md
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.