Seven steps, the least work. Three are clicks in your vendor console, three are copy-paste on your machine, one proves it end to end. Nothing here is a guess - every route and command is live today.
Sign in and turn your account into a seller at Become a vendor. This provisions your signing keys (used to mint and verify licences) behind the scenes - you don't touch them.
The free Dev tier is enough to complete every step below and sell in test mode. Real customers need a paid plan - see pricing.
In Products, add a product. Give it a short product code (e.g. acme-pro) - you'll use that exact code in your app and in the Protect CLI. Add at least one plan (a price). That's all a licence needs to exist.
Open Getting paid and connect Stripe (and/or PayPal) in test mode. Nothing is charged for real. When a test payment succeeds, Key-Warden issues the licence automatically - you don't write any fulfilment code.
Don't know what to type into the card form? The exact test card numbers / sandbox logins appear inline on your Get started checklist at the moment you need them.
Install the SDK for your stack and validate the customer's key at startup. Read your two gateway keys from the environment - never hard-code them. Get them from SDK & Tools.
✓ At this point you already have a sellable product. Steps 5 and 6 harden it so your code can't simply be copied and run without a licence - strongly recommended, not mandatory to sell.
Enable protection for your product at Protect your code and click Reveal key to copy your product's base-64 content key. Then run the Protect CLI in your build. It obfuscates your build (mandatory - it can't be turned off), seals your licensed files with AES-256-GCM, embeds your public key, watermarks the build, and verifies the result - all locally. Your source never leaves your machine.
Ship the produced *.sealed files plus dist/kw-public-key.txt. Gate your CI with npx @key-warden/protect check - it exits non-zero if anything (including obfuscation) is missing.
The content key is never stored in kw-protect.json - only in the KW_CONTENT_KEY environment variable, so it stays out of your repo.
The sealed files only decrypt once Key-Warden hands the content key to a valid, activated licence - bound to that machine. Add three lines after your validate() call:
Prefer real-time revocation over offline? Swap unlockFromToken + unseal for unsealOnline(), which fetches the key live so a revoked licence stops working immediately.
Buy your own product once in test mode - the single best check that everything is wired: payment → licence issued → your app validates → sealed code unseals. Your Get started checklist ticks the test-sale step when it sees a real end-to-end purchase.
When that's green, switch the payment connection to live (and make sure you're on a paid plan for production customers). You're selling.
On any plan you can set a Trial (days) value (1-60) in your dashboard. Customers then get a self-serve, no-card trial at key-warden.com/trial?plan=<plan-code> - the buy page also shows a Start N-day free trial button automatically. Key-Warden emails them a licence key that is node-locked to one device and expires when the trial ends.
A trial key validates exactly like a paid one - your validate()/verifyToken() call already refuses it once it expires (reason expired). The 1.3.0 SDKs add trialInfo(), isTrial() and daysRemaining() so you can show a countdown and an expired state:
These helpers are for display only - always gate access on validate()/verifyToken() first. daysRemaining rounds up (the last partial day still reads "1 day left") and is 0 once expired. Trial keys are node-locked, so pass the same machineId you use for validate().
Console: become a vendor → product & plan → test payments. Machine: validate → protect → unseal. Then a test purchase and flip to live.