Skip to main content
Lemon Squeezy is a payment platform designed for digital products and SaaS. Its standout feature is acting as a Merchant of Record (MoR), handling VAT and sales tax compliance globally.

Prerequisites

  • A Lemon Squeezy account (sign up here)
  • Your ShipFree application running locally or deployed
  • A verified store in Lemon Squeezy

What is Merchant of Record?

As a Merchant of Record, Lemon Squeezy:
  • Handles all tax compliance: VAT, sales tax, GST worldwide
  • Is the seller of record: Your customers buy from Lemon Squeezy, not you
  • Manages invoicing: Generates proper tax invoices
  • Handles refunds and chargebacks: Takes on the liability
This simplifies your business but means Lemon Squeezy takes a higher fee (5% + payment processing).

Setup Instructions

Step 1: Set Up Your Store

  1. Log in to Lemon Squeezy
  2. Complete store verification (required for payouts)
  3. Set up your payout method
  4. Configure tax settings (automatically handled as MoR)

Step 2: Get Your API Key and Store ID

  1. Go to Settings → API
  2. Click Create API Key
  3. Copy your API key (starts with eyJ0eXAiOi...)
  4. Note your Store ID (found in Settings)

Step 3: Create Products and Variants

Lemon Squeezy uses products and variants for pricing.
  1. Go to Products in your dashboard
  2. Click Create Product
  3. For each plan (Starter, Pro, Enterprise):
    • Set product name and description
    • Set product type to Subscription
    • Add product image (optional)
    • Click Create Product
  4. Create variants for each billing interval:
    • Click Add Variant
    • Set variant name (e.g., “Monthly”)
    • Set price (e.g., $9.90)
    • Set billing interval: Monthly or Yearly
    • Enable Subscription
    • Save and copy the Variant ID (numeric ID)
In Lemon Squeezy, you use Variant IDs (not Product IDs) when creating checkouts. Each variant represents a specific price point and billing interval.

Step 4: Configure Environment Variables

Add these variables to your .env file:
In ShipFree’s config, these are named PRODUCT_* but actually contain Variant IDs for Lemon Squeezy. This maintains consistency across providers.

Step 5: Set Up Webhooks

Lemon Squeezy uses webhooks to notify your application about subscription events.

For Local Development

Use ngrok to expose your local server:
  1. Install ngrok:
  2. Start your development server:
  3. In another terminal, start ngrok:
  4. Copy the HTTPS URL (e.g., https://abc123.ngrok.io)
  5. In Lemon Squeezy dashboard, go to Settings → Webhooks
  6. Click Add Webhook:
    • URL: https://abc123.ngrok.io/api/webhooks/payments
    • Signing Secret: Generate a random string (save this!)
    • Events: Select all subscription and order events
  7. Add the signing secret to your .env:

For Production

  1. Go to Settings → Webhooks
  2. Click Add Webhook
  3. Set webhook URL: https://yourdomain.com/api/webhooks/payments
  4. Generate and save a signing secret
  5. Select events:
    • subscription_created
    • subscription_updated
    • subscription_cancelled
    • subscription_expired
    • subscription_payment_success
    • order_created
  6. Add signing secret to production environment variables

Testing in Development

Test Mode

Lemon Squeezy provides test mode for development:
  1. In your dashboard, toggle Test Mode (top right)
  2. Create test products and variants
  3. Use test checkout flows

Test Checkout

Lemon Squeezy provides test card numbers:
  • Use any future expiration date
  • Use any 3-digit CVC

Testing Subscriptions

  1. Start your development server and ngrok:
  2. Configure webhook in Lemon Squeezy with your ngrok URL
  3. Create a checkout:
  4. Complete the test checkout
  5. Verify webhook events in your application logs

Lemon Squeezy Implementation Details

The Lemon Squeezy adapter is implemented in src/lib/payments/providers/lemonsqueezy.ts.

Key Features

Checkout Sessions

Creates Lemon Squeezy checkouts with:
  • Variant-based pricing (not product-based)
  • Customer metadata
  • Custom redirect URLs
  • Trial periods (if configured)

Customer Management

Lemon Squeezy creates customers automatically during checkout:
  • Customers are created on first purchase
  • Customer data includes email and metadata
  • Uses customer lookup by email

Subscription Handling

Provides:
  • Subscription retrieval by ID
  • Status mapping to unified format
  • Cancellation support (always at period end)

Webhook Processing

Processes these events:
  • subscription_created, subscription_updated, subscription_cancelled, subscription_expired
  • order_created
Webhook validation using HMAC:

Customer Portal

Lemon Squeezy provides a customer portal accessible via magic link:
The portal allows customers to:
  • Update payment methods
  • View invoices and receipts
  • Cancel subscriptions
  • Download tax invoices

Custom Data and Metadata

You can pass custom data in checkouts to track users:
This data is returned in webhook events as meta.custom_data.

Going Live

Pre-Launch Checklist

  • Complete store verification in Lemon Squeezy
  • Set up payout method
  • Turn off Test Mode
  • Create live products and variants
  • Update environment variables with live variant IDs
  • Configure production webhook endpoint
  • Set up webhook signing secret
  • Test complete checkout flow with real card
  • Verify tax handling and invoicing
  • Test subscription management portal

Tax Compliance

As a Merchant of Record, Lemon Squeezy handles:
  • EU VAT: All 27 EU countries
  • US Sales Tax: All applicable states
  • UK VAT
  • Canadian GST/HST/PST
  • Australian GST
  • And more: Check Lemon Squeezy tax coverage
You don’t need to:
  • Register for tax IDs in different countries
  • Calculate tax rates
  • File tax returns
  • Generate compliant invoices

Security Best Practices

  1. Protect API keys: Keep LEMONSQUEEZY_API_KEY server-side only
  2. Validate webhooks: Always verify HMAC signatures
  3. Use HTTPS: Required for production webhooks
  4. Secure webhook secret: Use a strong random string
  5. Monitor webhook logs: Check for failed events

Troubleshooting

Webhook Not Received

  1. Verify ngrok is running (local dev)
  2. Check webhook endpoint is accessible
  3. Review webhook logs in Lemon Squeezy dashboard
  4. Ensure LEMONSQUEEZY_WEBHOOK_SECRET matches dashboard
  5. Check signature validation logic

Checkout Session Fails

  1. Verify LEMONSQUEEZY_API_KEY is set
  2. Check LEMONSQUEEZY_STORE_ID is correct
  3. Ensure variant IDs exist and are active
  4. Check that products are published
  5. Review error response from Lemon Squeezy API

Subscription Not Created

  1. Check webhook was sent (Lemon Squeezy dashboard)
  2. Verify webhook signature validation passes
  3. Review application logs for errors
  4. Ensure custom_data includes userId
  5. Check database for subscription records

Customer Portal Issues

  1. Ensure customer email is correct
  2. Verify customer exists in Lemon Squeezy
  3. Check customer has active subscription
  4. Try accessing portal directly from Lemon Squeezy dashboard

Lemon Squeezy vs Other Providers

When to Choose Lemon Squeezy

✅ Choose Lemon Squeezy if you:
  • Want hassle-free global tax compliance
  • Are selling digital products or SaaS
  • Don’t want to deal with tax registrations
  • Prefer simple setup and pricing
  • Are a solo founder or small team
  • Want Lemon Squeezy to handle refunds/chargebacks
❌ Avoid Lemon Squeezy if you:
  • Need to be the merchant of record (legal/branding reasons)
  • Want maximum control over payment flow
  • Need extensive payment methods
  • Require advanced billing features (metered usage, etc.)
  • Want lowest possible fees

Feature Comparison

Additional Resources

Support

For Lemon Squeezy-specific issues: For ShipFree integration issues:
  • Check the source code in src/lib/payments/providers/lemonsqueezy.ts
  • Review webhook handling in src/app/api/webhooks/payments/route.ts