Lemon Squeezy setup
Keylight integrates with Lemon Squeezy through a one-way signed webhook: every order, subscription state change, and refund hits Keylight, and Keylight mints, renews, or refunds the matching license. There is no OAuth and no outbound API call from Keylight — just the signed webhook with a shared HMAC secret.
1. Enable Lemon Squeezy in the dashboard
Section titled “1. Enable Lemon Squeezy in the dashboard”From your dashboard, go to Settings → Integrations → Lemon Squeezy and click Enable Lemon Squeezy. Keylight reveals the webhook URL:
https://api.keylight.dev/webhooks/lemonsqueezy/<your-tenant-id>Copy it — you’ll paste it into Lemon Squeezy’s webhook settings in step 3.
2. Map Lemon Squeezy Variant IDs to Keylight apps
Section titled “2. Map Lemon Squeezy Variant IDs to Keylight apps”In Settings → Integrations → Lemon Squeezy, add one row per variant.
| Lemon Squeezy Variant ID | Keylight app | Key type |
|---|---|---|
123456 | myapp | pro-monthly |
123457 | myapp | pro-annual |
Keylight reads data.attributes.first_order_item.variant_id from each order_created event to pick the row. Unmapped variants are rejected with 400 unmapped_variant instead of being minted against an unknown app.
3. Configure the webhook in Lemon Squeezy
Section titled “3. Configure the webhook in Lemon Squeezy”In the Lemon Squeezy dashboard:
- Go to Settings → Webhooks.
- Click + Create new webhook.
- Paste the Keylight URL from step 1 into Callback URL.
- Set a Signing secret of your choice (any random string — copy it).
- Check these event types:
order_createdorder_refundedsubscription_payment_successsubscription_payment_failedsubscription_payment_recoveredsubscription_updatedsubscription_resumedsubscription_pausedsubscription_cancelledsubscription_expired
- Save.
Back in Keylight (Settings → Integrations → Lemon Squeezy), paste the signing secret into Webhook signing secret and save. Keylight uses it to verify the X-Signature HMAC-SHA256 header on every delivery.
4. Test the connection
Section titled “4. Test the connection”Lemon Squeezy’s webhook editor has a Send test dropdown — pick order_created.
200 OKfrom Keylight with a new license record in Dashboard → Licenses means signature, variant map, and routing all work.400 invalid_signature→ secret mismatch; re-copy from Lemon Squeezy.400 unmapped_variant→ the test variant ID isn’t in your map; add a row.
What happens on a real sale
Section titled “What happens on a real sale”When a customer checks out, Lemon Squeezy fires order_created. Keylight verifies X-Signature, looks up the Keylight app + key type from the variant ID, mints a license, and records the payment. For subscriptions: the first order arrives as order_created (that’s when provisioning happens — not subscription_created, which Keylight deliberately ignores). Renewals come as subscription_payment_success and re-extend the license. subscription_cancelled flips it to cancelled at period end.
Upgrades
Section titled “Upgrades”Upgrades are brokered through Lemon Squeezy’s Checkout API, so they need a Lemon Squeezy API key on the Live slot under Settings → Integrations → Lemon Squeezy. Selling needs only the signing secret.
With a key saved, Keylight creates the upgrade checkout itself, putting the customer’s current license key in checkout_data.custom. Lemon Squeezy echoes it back as meta.custom_data, and Keylight raises the existing license instead of issuing a second one. The key type’s Upgrade checkout URL is not used — leave it blank.
| Upgrade path | Supported |
|---|---|
| One-time license → one-time license | Yes, through a checkout created by Keylight. |
| One-time license → subscription | No. |
| Subscription → one-time license | No. |
| Subscription → subscription | No. |
After paying, the customer is returned to the license they just upgraded rather than left on your store’s generic confirmation. That redirect (product_options.redirect_url) can only be set on a checkout created through the API — Lemon Squeezy has an open feature request for a query-parameter equivalent, so a plain checkout link can’t do it.
Disconnecting
Section titled “Disconnecting”Settings → Integrations → Lemon Squeezy → Disconnect clears the signing secret and the variant map. Existing licenses are untouched — only new webhook deliveries stop minting.