Docs menu: Connect Lemon Squeezy

Payments

Connect Lemon Squeezy

Create licenses automatically from Lemon Squeezy orders and subscriptions, with offline certificates.

Lemon Squeezy can issue its own license keys, validated online through its API. Connecting it to Keyrail instead gives you signed certificates verified offline, per-product machine fingerprints, the same SDKs and API as with Paddle, and a single place for all your licenses.

1. Create the integration#

In the dashboard: your product, then Integrations → Connect Lemon Squeezy. Or with the vendor API:

bash
curl https://api.keyrail.tech/v1/integrations \
  -H "Authorization: Bearer $KEYRAIL_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "lemonsqueezy",
    "product": "prd_7k2m9q4x1c8d3f6h0j5n",
    "priceMap": { "412345": "pro", "412346": "lifetime" },
    "webhookSecret": "a-long-random-string-you-choose"
  }'

priceMap keys are Lemon Squeezy variant IDs, values are plan codes. The response contains the webhookUrl: https://api.keyrail.tech/v1/webhooks/lemonsqueezy/int_….

2. Add the webhook in Lemon Squeezy#

In Lemon Squeezy, Settings → Webhooks → +:

  • Callback URL: the webhookUrl.
  • Signing secret: the same webhookSecret you sent to Keyrail.
  • Events: order_created, order_refunded, subscription_created, subscription_updated, subscription_payment_success.

3. Test#

Enable test mode in Lemon Squeezy and buy with a test card. The license appears in the dashboard and the customer receives the key.

Test-mode events (meta.test_mode: true) are only processed by an integration whose environment is sandbox; a live integration acknowledges them and ignores them (the audit log says test mode event on a live integration), so test orders never create real licenses. Likewise a sandbox integration ignores live events. Create one integration per environment, each with the signing secret of the matching webhook.

What each event does#

Lemon Squeezy eventEffect on the license
order_created with a non-subscription variantA perpetual license.
subscription_created, subscription_payment_successpaidUntil = renews_at; status active.
subscription_updatedStatus mapped from the subscription status (below).
order_refundedStatus refunded.
Lemon Squeezy subscription statusLicense status
active, on_trialactive
past_due, unpaidpast_due
cancelledcanceled
expiredexpired
pausedsuspended

The customer is matched by email, or created. One customer with one subscription to a plan has one license, reused if they subscribe again later.

Signature verification#

The X-Signature header must be the hex HMAC-SHA256 of the raw request body with your signing secret. Otherwise Keyrail answers 401. See webhooks.

View as Markdown