General

Paycheck is licensing infrastructure for indie developers. It handles checkout, activation, and license recovery so you can focus on building your product.

Unlike traditional licensing systems that require constant server validation, Paycheck uses cryptographically signed JWTs that validate offline. Your app works in airplane mode, behind firewalls, forever.

Yes. The entire Paycheck codebase is source-available under the Elastic License and hosted on GitHub. You can self-host it on your own infrastructure.

The hosted service at paycheck.dev is a convenience option for those who don't want to manage servers.

Offline-first: Most licensing systems require constant server pings. Paycheck validates locally using Ed25519 signatures. Your app doesn't depend on our uptime.

No license keys: Users activate via email, not by copying 32-character strings. Recovery is self-service—no "I lost my key" support tickets.

Privacy-focused: We store email hashes, not emails. Audit logs auto-purge. Your customers' PII stays with your payment provider.

Technical

When a user activates, Paycheck issues a JWT (JSON Web Token) signed with your project's Ed25519 private key. Your app embeds the corresponding public key at build time.

To validate, your app just verifies the JWT signature locally—no network call needed. The JWT contains the user's tier, enabled features, and expiration dates.

Paycheck integrates with Stripe and LemonSqueezy. You can use either or both—even route different products to different providers.

You keep your existing payment provider account. Paycheck handles the webhooks and creates licenses automatically when payments complete.

Users enter their purchase email in your app. Paycheck sends them a short-lived activation code (30 min TTL). They enter the code, and the new device is activated.

This is fully self-service—no support ticket required. Device limits are enforced server-side, and users can deactivate old devices themselves.

For apps that do periodic online checks (via /validate), yes—revocation takes effect immediately.

For purely offline apps, no. The JWT validates locally with no server contact, which means there's no channel to communicate "this license is revoked." This is the tradeoff for offline-first: your app works without depending on anyone's servers, but you can't remotely disable it either.

If revocation is critical for your use case, design your app to check /validate periodically when online. Most apps can do this naturally—on startup if network is available, or during sync operations.

Any language that can verify Ed25519 signatures—which is all of them. We provide SDKs for TypeScript and Rust, but the protocol is simple enough to implement with any JWT library.

The entire client integration is a few dozen lines. No SDK lock-in, no runtime dependencies.

Pricing & Plans

All plans include a 14-day free trial. If you want free forever, you can self-host—the entire codebase is source-available.

The revenue cap is based on the gross revenue processed through Paycheck's payment integrations each month. This is the total before payment provider fees.

Revenue from other sources (consulting, services, products not using Paycheck) doesn't count.

We'll notify you and give you time to upgrade. We won't cut off your customers or break your app. Growing pains are a good problem—we want to help you scale, not punish you for success.

No. Paycheck charges a flat monthly fee. Your payment provider (Stripe, LemonSqueezy) charges their standard processing fees, but Paycheck doesn't take any cut of your revenue.

But why not...

Stripe is excellent at collecting payments. But "customer paid" and "customer can use my software" are two very different problems.

After payment, you're on your own. Customer buys your desktop app, Stripe sends a webhook—now what? You have a customer ID and a receipt, but no license key, no activation system, no way for your app to verify the purchase offline. You need to generate something, store it somewhere, and build endpoints your app can call. That's a licensing system you're building from scratch.

Desktop apps can't just "check with Stripe." Web apps can hit your server on every page load, but native apps need to work offline. Your customer downloads your Mac app and enters... what exactly? Their receipt number? You'd need to build license key generation, an activation API, local storage, and offline verification. Stripe has no opinion on any of this.

Recovery and device management don't exist. Customer reformats their computer. With just Stripe, they have a payment receipt and nothing else. You need to build email-based recovery, purchase lookups, device tracking with limits, and deactivation flows. Want a 3-device limit? That's a database, enforcement logic, and an admin UI for when customers lock themselves out.

Webhook reliability is its own problem. Stripe retries failed webhooks, but what happens when your server is down? When you get duplicate events? When a customer pays but your webhook handler throws an exception? Each edge case generates a "I paid but can't access" support ticket. You're building retry logic, idempotency handling, and reconciliation—or spending hours manually fixing license states.

Subscriptions get messy fast. When a subscription renews, Stripe sends a webhook. But your license JWT still shows the old expiration date. You need to catch the renewal, update your database, and somehow get fresh tokens to every activated device—devices that might not check in for days if they work offline.

Paycheck uses Stripe for payments, then handles everything after: activation codes, signed JWTs, device tracking, offline validation, email recovery, subscription sync. You get Stripe's payment processing without building the licensing system yourself.

LemonSqueezy is genuinely excellent—merchant of record, built-in license keys, handles VAT/sales tax in 100+ countries. For a simple SaaS where users are always online, it might be all you need. But there are real gaps as your software business matures.

Online validation is a dependency. LemonSqueezy's licensing requires your app to call their servers. When their API has outages, your paying customers can't use software they own. Corporate firewalls routinely block validation calls to third-party domains—you'll field tickets from IT admins asking you to whitelist api.lemonsqueezy.com, or lose enterprise deals entirely. With Paycheck, the signed JWT is the license. Your app validates the Ed25519 signature locally. The server could be offline for a week and your customers wouldn't notice.

License key UX creates support burden. LemonSqueezy generates 32-character keys users need to copy, paste correctly, and never lose. Keys copied with trailing spaces. Keys lost when switching machines. "I bought this two years ago and can't find my license" emails. Paycheck eliminates permanent keys entirely—users get short-lived activation codes that expire in 30 minutes. Lost access? Enter your purchase email, get a new code. No key management, no digging through old inboxes.

Vendor lock-in is real. LemonSqueezy's license keys are tied to their infrastructure. Want to switch to Stripe for better rates? Every existing customer needs a new key. All your documentation references the old system. With Paycheck, your payment provider is just a payment provider—switch whenever you want, your licenses are yours, signed with your keys.

Rate limits bite at scale. LemonSqueezy's API has rate limits (120 requests/minute). Every app launch that validates online counts against it. 10,000 active users opening your app throughout the day means tens of thousands of validation calls. Hit the limit and license checks start failing. Paycheck's offline validation has no rate limits—there's no server involved.

What if LemonSqueezy changes or disappears? Your license validation depends on their servers staying up and their API staying compatible. Paycheck's licenses are cryptographically signed JWTs that validate offline. Even if our hosted service vanished, every license you've issued keeps working forever.

Keygen is a solid, well-engineered licensing platform. For enterprises with complex requirements—floating licenses, policy engines, machine quotas—it's a reasonable choice. But that power comes with trade-offs.

Complexity is the feature and the cost. Before you issue your first license, you're navigating policies, entitlements, machines, components, fingerprint strategies, and policy schemes. Their documentation is thorough—perhaps too thorough. Budget a day or two just to understand their model. For most indie developers shipping a desktop app, it's overkill that adds cognitive load without clear benefit. Paycheck is deliberately opinionated: one activation flow, email-based recovery, signed JWTs. Fewer decisions means you ship faster.

Usage-based pricing can surprise you. Keygen charges based on license validations and API calls. A successful launch that brings thousands of new users also brings thousands of validation requests—and a proportionally larger bill. Paycheck's hosted service has flat monthly pricing, and self-hosting costs just your server (a $5 VPS handles most indie apps).

Closed source means dependency. You can't run Keygen on your own infrastructure, inspect the code, or modify it. If they raise prices, change terms, or shut down, you're along for the ride. Paycheck is source-available under the Elastic License and designed to be self-hosted from day one.

No integrated payments. Keygen handles licensing but not payments. You still need to integrate Stripe or Paddle separately, wire up webhooks, handle the handoff from "customer paid" to "license issued," and keep everything in sync. That's real integration work. Paycheck treats payment and licensing as one flow—webhook fires, license exists.

License keys are still a UX liability. Keygen gives you keys that users store somewhere, copy-paste correctly, and inevitably lose. "I bought this three years ago and can't find my key" is still your support ticket. Paycheck's email-based recovery eliminates key management entirely.

You absolutely can, and many developers do. If your needs are simple—single product, perpetual licenses, no device limits—a weekend project might genuinely be enough. But licensing has a way of accumulating edge cases that aren't obvious until you're debugging them at 2am.

Webhook handling is deceptively tricky. Stripe retries failed webhooks for up to 3 days with exponential backoff—your endpoint needs to be idempotent. You need signature verification to prevent spoofed requests. You need to handle out-of-order delivery. And you need to decide what happens when your server is down during a webhook: poll for missed events? Reconciliation job? Each missed webhook is a "I paid but can't access" ticket.

Key generation and storage is its own rabbit hole. How much entropy? What format balances readability with uniqueness? You can't store keys in plaintext, so you're hashing them—but then you can't show them again. If you're signing JWTs, you need secure key storage with envelope encryption, because a database breach shouldn't compromise every license you've issued.

Device fingerprinting sounds simple until you think about it. What constitutes a "device"? Machine IDs work for desktop apps, but VMs clone trivially. Browser fingerprints drift over time. UUIDs in localStorage get cleared. You need a strategy for "my device changed but I'm the same person" that doesn't also enable "I'll share my license with everyone."

Recovery flows are where licensing systems die. User reformatted, lost their email, changed jobs, bought through a reseller. How do they prove they paid? You need purchase email linked to licenses, secure credential issuance without enabling hijacking, rate limiting against enumeration attacks. What does "proof of ownership" even mean when payment happened through Stripe?

Maintenance never stops. Cryptographic libraries need updates when vulnerabilities are discovered. Edge cases emerge over time: chargebacks, timezone bugs, unicode in emails. Every hour debugging licensing is an hour not spent on your actual product.

If you want full control, Paycheck's source-available codebase is a head start on all these edge cases. Fork it, deploy it, modify anything you need. The goal isn't to lock you in—it's to let you focus on building your product while standing on shoulders.

Security & Privacy

Paycheck stores email hashes (SHA-256), not plain emails. This enables license recovery while keeping PII minimal. Your customers' actual email addresses stay with your payment provider.

Private keys and payment credentials are encrypted at rest using envelope encryption (AES-256-GCM with HKDF-derived keys). Audit logs auto-purge after 90 days.

No. Paycheck is a payment flow with cryptographic receipts, not copy protection. We design for the honest majority—the 95% who just need a convenient way to pay and prove it.

We don't do anti-tampering, obfuscation, or phone-home requirements. That's security theater that hurts legitimate users more than it stops determined pirates.

Back to homepage