Skip to content

Upgrades

Customers upgrade their license through the customer portal:

  1. They sign in at https://portal.keylight.dev (magic link to the email on their license).
  2. They open the license and tap Upgrade, then pick a higher tier — no key or email re-entry, since the session already identifies them.

Keylight validates the upgrade, charges through your existing payment provider, and swaps the license’s key type in place. The license key string never changes. (In-app upgrade UI via the SDK is on the roadmap — see below.)

Section titled “Stripe (Connect, override key, or Payment Link)”

Nothing to configure. Keylight uses your existing Stripe integration to create checkout sessions with the upgrade metadata attached.

Merchant-of-Record providers (Polar, Paddle, Lemon Squeezy, Creem, Gumroad, Shopify)

Section titled “Merchant-of-Record providers (Polar, Paddle, Lemon Squeezy, Creem, Gumroad, Shopify)”

For each key type your customers can upgrade to, paste the hosted-checkout URL from your provider’s dashboard into the Upgrade checkout URL field on the Apps page in Keylight. Example:

ProviderURL pattern
Polarhttps://polar.sh/<org>/<product>
Lemon Squeezyhttps://<store>.lemonsqueezy.com/checkout/<variant>
Paddlehttps://buy.paddle.com/checkout/<price>
Creemhttps://creem.io/payment/<product>
Gumroadhttps://<user>.gumroad.com/l/<product>
Shopifyhttps://<store>.myshopify.com/products/<product>

Keylight will append the customer’s license key as metadata in the provider-specific URL format when redirecting them.

Paddle’s webhooks don’t include customer email, so Keylight needs to fetch it via Paddle’s API. Add your Paddle API key (Paddle dashboard → Developer Tools → Authentication) on the Integrations card. Existing Paddle customers issued before this was set up can be backfilled — contact Keylight support if you’d like us to run the resolver for you.

To offer an upgrade at no cost, set the target key type’s price to 0 and enable it as an upgrade target (upgradeEnabled). A free upgrade:

  • requires no payment provider — it works even if the product has no Stripe or merchant-of-record integration configured;
  • is applied instantly when the customer selects it in the portal (no checkout step) — their license switches to the new key type’s device limit and entitlements immediately;
  • is only available for one-time tiers. A tier billed as a subscription can’t be granted for free, because there is no subscription to attach.

Any non-zero price keeps the normal checkout flow.

In-app upgrade UI is on the roadmap: the SDK will let you render the upgrade flow inside your own app instead of sending customers to the portal. The backend it builds on — POST /upgrade-session, which validates the intent and returns a provider checkout URL — already exists. Until the SDK ships this, send customers to the customer portal to upgrade.

After a customer upgrades, call licenseManager.refresh(force: true) from your scene-foreground hook so the new tier appears without a relaunch.

Customers who lose their key sign in to the customer portal at https://portal.keylight.dev — they enter the email on their license, click the magic link, and their keys are listed in the dashboard with copy and “email me this key” options. There’s no separate recovery page: signing in needs only the email already on the license. Link your support pages to https://portal.keylight.dev.

  • Same-product upgrades (any key type → any other key type within the same Keylight product).
  • Both upgrades (lower-tier → higher-tier) and “side-grades” — as long as the target tier’s seat count is ≥ your customer’s current active devices.
  • Cross-product upgrades (V1 modeled as Product A → V2 modeled as Product B) are not supported. Workaround: model V2 as a new key type under your existing product.
  • Proration when transitioning from a one-time key type to a subscription key type is not automatic. The new subscription’s billing cycle starts fresh.
  • Automatic refunds on downgrades are not included. Issue refunds yourself on the payment platform.