This guide walks you through configuring Lemon Squeezy as your payment provider. By the end, you will have a working checkout flow with webhook processing. The setup takes approximately 20 minutes.
Before starting, make sure you have completed the Getting Started setup and have your application running locally.
Account & Store Setup
1
Create a Lemon Squeezy account
Go to lemonsqueezy.com and create an account. Lemon Squeezy acts as your Merchant of Record — they handle all tax calculation, collection, and remittance across jurisdictions.
2
Create a store
After registration, create a new store from the dashboard. Choose a store name that matches your product. Note the Store ID from the store settings — you will need it for the environment variables.
3
Enable test mode
Toggle Test Mode in the Lemon Squeezy dashboard (top-right switch). All products, variants, and webhooks you create in test mode are isolated from production data. This allows you to test the full payment flow without real charges.
Creating Products
Create one product for each subscription tier in your Lemon Squeezy dashboard. Kit uses three paid tiers — Basic, Pro, and Enterprise.
1
Navigate to Products
In the Lemon Squeezy dashboard, go to Store > Products and click New Product.
2
Create the Basic product
Set the product name (e.g., "Basic Plan"), add a description, and configure the pricing. Repeat for Pro and Enterprise.
Use clear, descriptive product names. Lemon Squeezy shows these names on the checkout page and in customer emails. You can customize the checkout appearance in the store settings.
Bonus Credit Products (Credit-Based Model Only)
If you use the credit-based pricing model and want to offer bonus credit top-ups, create additional products for each tier's bonus packages. These must be one-time purchase products (not subscriptions):
1
Create bonus credit products
For each paid tier (Basic, Pro, Enterprise), create up to 2 products representing the credit packages. Set the payment type to one-time (not recurring). For example:
| Product Name | Payment Type | Price | Credits |
|---|---|---|---|
| Basic 500 Credits | One-time | €4.99 | 500 |
| Basic 1200 Credits | One-time | €9.99 | 1,200 |
| Pro 2000 Credits | One-time | €9.99 | 2,000 |
| Pro 5000 Credits | One-time | €19.99 | 5,000 |
| Enterprise 8000 Credits | One-time | €19.99 | 8,000 |
| Enterprise 20000 Credits | One-time | €39.99 | 20,000 |
Each product needs exactly one variant. Adjust prices and credit amounts to match your business model.
2
Note the variant IDs
Copy each variant ID from the Lemon Squeezy dashboard. You will add these to your environment variables as
NEXT_PUBLIC_BONUS_{TIER}_PACKAGE{N}_VARIANT_ID. See Environment Variables for the full list of bonus credit configuration variables.Bonus credit products must be configured as one-time purchases in Lemon Squeezy. They are processed through the
order_created webhook event, not subscription events. Using recurring billing for bonus credits will cause incorrect webhook processing.Creating Variants
Variants represent the specific pricing options within each product. The number of variants depends on your pricing model.
Classic SaaS (6 Variants)
Classic SaaS requires 6 variants — monthly and yearly billing for each paid tier:
| Product | Variant | Billing | Example Price |
|---|---|---|---|
| Basic | Basic Monthly | Monthly | $9.99/mo |
| Basic | Basic Yearly | Yearly | $99.99/yr |
| Pro | Pro Monthly | Monthly | $29.99/mo |
| Pro | Pro Yearly | Yearly | $299.99/yr |
| Enterprise | Enterprise Monthly | Monthly | $99.99/mo |
| Enterprise | Enterprise Yearly | Yearly | Contact only |
For each product, click Add Variant and configure the billing period and price. Note down each variant's Variant ID — visible in the variant settings URL or the API tab.
Enterprise tier is typically contact-only (no self-service checkout). You can still create the variant for API-based provisioning, or skip the yearly Enterprise variant entirely.
Credit-Based (3 Variants)
Credit-based pricing requires 3 variants — monthly billing only for each paid tier:
| Product | Variant | Billing | Example Price | Credits/Month |
|---|---|---|---|---|
| Basic | Basic Monthly | Monthly | €9.90/mo | 1,500 |
| Pro | Pro Monthly | Monthly | €19.90/mo | 5,000 |
| Enterprise | Enterprise Monthly | Monthly | €39.90/mo | 15,000 |
Credit-based pricing does not support yearly billing — all subscriptions renew monthly with credit resets aligned to the billing cycle.
API Key Configuration
1
Generate an API key
In the Lemon Squeezy dashboard, go to Settings > API and click Generate API Key. Give it a descriptive name like "Kit Production" or "Kit Development".
2
Copy the API key
Copy the generated key immediately — Lemon Squeezy only shows it once. Store it securely.
3
Add to environment variables
Add the API key to your
apps/boilerplate/.env.local file:bash
LEMONSQUEEZY_API_KEY="your_api_key_here"
The
LEMONSQUEEZY_API_KEY is a server-side secret. Never commit it to version control, expose it in client-side code, or share it publicly. Use apps/boilerplate/.env.local (which is gitignored) for local development and your hosting provider's environment variable settings for production.Webhook Configuration
Webhooks are how Lemon Squeezy notifies your application about subscription events. Kit processes 11 different event types through a single endpoint.
1
Create a webhook endpoint
In the Lemon Squeezy dashboard, go to Settings > Webhooks and click Add Endpoint.
Set the webhook URL to:
https://your-domain.com/api/webhooks/lemonsqueezy
For local development, you need a publicly accessible URL. Use a tunneling service like ngrok:
bash
ngrok http 3000
Then use the generated ngrok URL:
https://abc123.ngrok.io/api/webhooks/lemonsqueezy2
Generate a webhook secret
Lemon Squeezy generates a signing secret for each webhook endpoint. Copy this secret — it is used for HMAC-SHA256 signature verification to ensure webhooks are authentic.
Add it to your
apps/boilerplate/.env.local:bash
LEMONSQUEEZY_WEBHOOK_SECRET="your_webhook_secret_here"
3
Select webhook events
Enable all 11 events that Kit handles:
subscription_created, subscription_updated, subscription_cancelled, subscription_resumed, subscription_expired, subscription_paused, subscription_unpaused, subscription_payment_success, subscription_payment_failed, subscription_payment_recovered, and order_created. See Webhooks & Portal for details on each event.The
LEMONSQUEEZY_WEBHOOK_SECRET in your apps/boilerplate/.env.local must exactly match the signing secret from the Lemon Squeezy dashboard. If they do not match, all webhook requests will fail signature verification and return 401 errors. Kit verifies every webhook with HMAC-SHA256 before processing.Environment Variables Checklist
Here is the complete set of payment-related environment variables. Copy this block into your
apps/boilerplate/.env.local and fill in the values from your Lemon Squeezy dashboard:# === Lemon Squeezy Core ===
LEMONSQUEEZY_API_KEY="lmsq_..."
LEMONSQUEEZY_STORE_ID="12345"
LEMONSQUEEZY_WEBHOOK_SECRET="whsec_..."
# === Pricing Model ===
NEXT_PUBLIC_PRICING_MODEL="classic_saas"
CURRENCY="EUR"
# === Classic SaaS Variant IDs ===
NEXT_PUBLIC_LEMONSQUEEZY_BASIC_MONTHLY_VARIANT_ID="123456"
NEXT_PUBLIC_LEMONSQUEEZY_BASIC_YEARLY_VARIANT_ID="123457"
NEXT_PUBLIC_LEMONSQUEEZY_PRO_MONTHLY_VARIANT_ID="123458"
NEXT_PUBLIC_LEMONSQUEEZY_PRO_YEARLY_VARIANT_ID="123459"
NEXT_PUBLIC_LEMONSQUEEZY_ENTERPRISE_MONTHLY_VARIANT_ID="123460"
# === Trial (Optional) ===
TRIAL_DAYS="14"
Test Mode
Lemon Squeezy provides a full test environment. All test data (products, subscriptions, webhooks) is completely isolated from production.
Test Credit Cards
Use these card numbers in test mode:
| Card | Number | Result |
|---|---|---|
| Visa | 4242 4242 4242 4242 | Successful payment |
| Visa | 4000 0000 0000 0002 | Declined payment |
| Mastercard | 5555 5555 5555 4444 | Successful payment |
Use any future expiry date and any 3-digit CVC.
Verify Webhook Delivery
After creating a test subscription, check the Lemon Squeezy dashboard under Settings > Webhooks. Each endpoint shows a delivery log with:
- HTTP status code (should be
200) - Response body
- Retry attempts (if the endpoint was unreachable)
Kit returns
200 for all successfully received webhooks, even if the handler encounters an internal error. This prevents Lemon Squeezy from retrying webhooks that were received but failed to process.Verification
After completing the setup, verify everything works end-to-end:
1
Start your development server
bash
pnpm dev:boilerplate
2
Start the tunnel (if testing webhooks locally)
bash
ngrok http 3000
Update the webhook URL in the Lemon Squeezy dashboard to your ngrok URL.
3
Create a test subscription
Navigate to the billing page in your application, select a plan, and complete the checkout using a test credit card. After payment, you should see:
- A
subscription_createdwebhook in the Lemon Squeezy delivery log - A new
Subscriptionrecord in your database - The user's tier updated in the
Usertable - Credits initialized (if using credit-based model)
4
Check application state
Verify the billing page reflects the active subscription. The user should see their current plan, next billing date, and a link to the customer portal.
If webhooks are not arriving, check: (1) the webhook URL is correct and publicly accessible, (2) the signing secret matches your
apps/boilerplate/.env.local, (3) all 11 events are selected in the dashboard. Kit logs all webhook events to the console — check your terminal output for detailed debugging information.