Overview

aSaaSin integrates Lemon Squeezy for subscriptions and billing. You will set environment variables, create product variants, and configure a webhook that keeps Supabase in sync.

Add to env

# Lemon Squeezy
LEMON_SQUEEZY_API_KEY=
LEMON_SQUEEZY_STORE_ID=
LEMON_SQUEEZY_WEBHOOK_SECRET=
LEMON_SQUEEZY_VARIANT_ID_STARTER=
LEMON_SQUEEZY_VARIANT_ID_ULTIMATE=

Save the file, then restart the dev server if it was running.

Create store & API key

  1. Sign in at Lemon Squeezy.
  2. Go to Settings → API and create an API key.
  3. Copy the Store ID from your store settings.
  4. Add the values to your .env as LEMON_SQUEEZY_API_KEY and LEMON_SQUEEZY_STORE_ID.

Products & variants

  1. In your store, create a Product.
  2. Add Variants for your plans (e.g., Starter, Ultimate).
  3. Open each variant in the dashboard and copy its Variant ID.
  4. Add them to .env as LEMON_SQUEEZY_VARIANT_ID_STARTER and LEMON_SQUEEZY_VARIANT_ID_ULTIMATE.

These IDs are used to map Lemon Squeezy plans to your internal plans in Supabase.

Configure webhook

  1. In your store go to Settings → Webhooks.
  2. Endpoint URL: https://YOUR_DOMAIN/api/webhooks/lemon-squeezy
  3. Events: enable subscription-related events (created, updated, canceled, expired).
  4. Secret: copy the generated secret and set it as LEMON_SQUEEZY_WEBHOOK_SECRET in .env.

The webhook will post JSON payloads to your Next.js API route.
Your app uses a Supabase admin client to update subscription state.

How the webhook is used

The handler at app/api/webhooks/lemon-squeezy/route.ts:

  • Parses the incoming JSON and extracts subscription details.
  • Looks up the user in Supabase by email.
  • Resolves your internal subscription_plan_id by matching variant_id.
  • Updates the subscriptions table with plan, status, customer ID, and expiry.
  • Returns 200 on success, or error codes if something is missing.

This keeps Supabase subscriptions in sync with Lemon Squeezy events.

Security note

  • Ensure your webhook route validates requests with the shared secret.
  • Keep LEMON_SQUEEZY_WEBHOOK_SECRET server-only.
  • Use your service role Supabase client only on the server (as in the webhook route).