Documentation

Lemon Squeezy Provider

Learn how to integrate Lemon Squeezy as your payment provider.

Lemon Squeezy is a merchant of record platform designed specifically for digital products and SaaS. It handles taxes, VAT, and compliance automatically, making it ideal for selling globally without the hassle.

Setup

1. Create a Lemon Squeezy Account

  1. Sign up at https://lemonsqueezy.com
  2. Complete your account setup and verification
  3. Navigate to the Dashboard

2. Create a Store

  1. Go to SettingsStores
  2. Click New Store
  3. Fill in your store details
  4. Copy your Store ID (you'll need this later)

Where to find Store ID:

  • Settings → Stores → Your store → URL contains the ID
  • Or check the store settings page

3. Get Your API Key

  1. Go to SettingsAPI
  2. Click Create API key
  3. Give it a name (e.g., "Production API Key")
  4. Copy the API key (starts with lemon_)

Important

The API key is only shown once, so save it immediately!

4. Create Products and Variants

  1. Go to ProductsNew Product
  2. Create your product:
    • Set product name and description
    • Upload images if needed
  3. Add Variants (pricing options):
    • For subscriptions: Set recurring interval (monthly/yearly)
    • For one-time: Set as one-time payment
    • Set price and currency
  4. After creating, copy the Variant ID (a numeric ID)

Example Setup:

  • Product: "Pro Plan"
    • Variant 1: Monthly ($19/month) → Variant ID: 123456
    • Variant 2: Yearly ($190/year) → Variant ID: 123457

5. Set Up Webhooks

Webhooks notify your application about payment events.

For Production:

  1. Go to SettingsWebhooks
  2. Click Add endpoint
  3. Set the webhook URL: https://yourdomain.com/api/webhooks/lemonsqueezy
  4. Select events to listen to based on your payment types:

For One-Time Payments:

  • order_created (required) - Records the purchase when order is created

For Subscriptions:

  • subscription_created (required) - Creates subscription record
  • subscription_updated (required) - Updates subscription status/plan
  • subscription_cancelled (required) - Handles cancellation
  • subscription_resumed (required) - Handles resumption after pause
  • subscription_expired (required) - Removes expired subscriptions

If you use both payment types, select all events above.

  1. Copy the Signing secret to your environment variables

For Local Development:

Use a tunneling service like ngrok:

# Using ngrok
ngrok http 3000

# Then use the ngrok URL in webhook settings
https://your-ngrok-url.ngrok.io/api/webhooks/lemonsqueezy

6. Configure Environment Variables

Add these variables to your .env.local file:

.env.local
# Lemon Squeezy API Key
LEMONSQUEEZY_API_KEY=lemon_xxxxxxxxxxxxx

# Lemon Squeezy Store ID
LEMONSQUEEZY_STORE_ID=12345

# Lemon Squeezy Webhook Secret
LEMONSQUEEZY_WEBHOOK_SECRET=your_webhook_secret

# Your Price IDs (use Lemon Squeezy Variant IDs)
NEXT_PUBLIC_PRICE_ID_LIFETIME=123456
NEXT_PUBLIC_PRICE_ID_PRO_MONTHLY=123457
NEXT_PUBLIC_PRICE_ID_PRO_YEARLY=123458

Where to find these:

  • API Key: Settings → API → Create/copy API key
  • Store ID: Settings → Stores → Your store ID in URL
  • Webhook Secret: Settings → Webhooks → Copy signing secret (from step 5)
  • Price IDs: Products → Click product → Copy variant IDs (use as Price IDs)

Configuration

Set Lemon Squeezy as your payment provider in config/index.ts:

config/index.ts
export const config = {
  payments: {
    provider: "lemonsqueezy",
    plans: {
      lifetime: {
        recommended: true,
        prices: [
          {
            type: "one-time",
            productId: process.env.NEXT_PUBLIC_PRICE_ID_LIFETIME as string,
            amount: 199,
            currency: "USD",
          },
        ],
      },
      pro: {
        recommended: false,
        prices: [
          {
            type: "subscription",
            productId: process.env.NEXT_PUBLIC_PRICE_ID_PRO_MONTHLY as string,
            amount: 19,
            currency: "USD",
            interval: "month",
          },
          {
            type: "subscription",
            productId: process.env.NEXT_PUBLIC_PRICE_ID_PRO_YEARLY as string,
            amount: 190,
            currency: "USD",
            interval: "year",
          },
        ],
      },
    },
  },
};

Note: Use Variant IDs (not Product IDs) in your configuration.

Multi-Currency Support

Lemon Squeezy supports multiple currencies:

  1. Set up variants for different currencies in your Lemon Squeezy dashboard
  2. Configure multiple prices in your config:
pro: {
  recommended: false,
  prices: [
    {
      type: "subscription",
      productId: process.env.NEXT_PUBLIC_PRICE_ID_PRO_USD as string,
      amount: 19,
      currency: "USD",
      interval: "month",
    },
    {
      type: "subscription",
      productId: process.env.NEXT_PUBLIC_PRICE_ID_PRO_EUR as string,
      amount: 17,
      currency: "EUR",
      interval: "month",
    },
  ],
}

Advanced Features

Seat-Based Billing

Enable quantity-based pricing for team plans:

{
  type: "subscription",
  productId: process.env.NEXT_PUBLIC_PRICE_ID_ENTERPRISE as string,
  amount: 99,
  currency: "USD",
  interval: "month",
  seats: {
    min: 5,
    max: 100,
  },
}