Your code deserves a paycheck.
One integration. Offline validation. Email recovery handled.
The Problem
You finished the hard part. Now this?
Integration
Point your "Buy" button at Paycheck. We redirect to Stripe or LemonSqueezy, handle the webhook, create the license.
Exchange activation code for a signed JWT. Web apps can auto-activate on callback—no code entry needed.
Verify the JWT locally with your public key. No server call. Your app doesn't depend on our uptime.
Features
Simple enough for Claude to implement. Robust enough for your 10,000th customer.
Ed25519 signed JWTs validate locally. Your app works in airplane mode, behind firewalls, forever. Our downtime isn't your downtime.
No permanent license keys to lose. Your users recover access with their purchase email—self-service, no intervention needed.
Web apps auto-activate on payment callback. Desktop apps use short-lived activation codes. Same API, both workflows.
Set device limits per product. Users can self-deactivate old devices. You can revoke remotely when needed.
Define products with different tiers and features. License expiration, update expiration, feature gates—all in the JWT.
Use Stripe, LemonSqueezy, or both. Route per-product or per-transaction. Pick the cheaper option for each sale.
We store email hashes, not emails. No PII in our database. Your customers' data stays with your payment provider.
Simple REST endpoints. Clear request/response patterns. Claude, Cursor, Copilot—any AI assistant can implement this.
Implementation
The entire client integration is a few dozen lines. Fetch your public key once, embed it at build time, validate forever.
No SDK lock-in. No runtime dependencies. Just JWT verification—use any library in any language.
import { verify } from 'jose'; // Public key embedded at build time const PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- MCowBQYDK2VwAyEAx8Js4D... -----END PUBLIC KEY-----`; export async function validateLicense(jwt: string) { const { payload } = await verify(jwt, PUBLIC_KEY); // Check expiration if not perpetual if (payload.license_exp && Date.now() > payload.license_exp) { throw new Error('License expired'); } return { tier: payload.tier, features: payload.features, updatesUntil: payload.updates_exp, }; }
Pricing
Start free for 14 days. Upgrade when you're ready.
Dream and build. For side projects under $500/mo revenue.
Ship and sell. For products making real money.
Scale and automate. API access, unlimited products.
All plans include a 14-day free trial.
Need revocation, audit logs, or SSO? Business starts at $499/mo.
Want to self-host? Paycheck is open source.
You built something worth paying for. Setup takes 15 minutes.