Get NextJet

Lemon Squeezy

Learn how to configure subscription based payments with Lemon Squeezy for local development.

Getting started

Change the payment service provider to Lemon Squeezy

Navigate to packages/utils/src/constants/featureFlags.ts

Change the payments property in the featureFlags object to PaymentProviderType.LemonSqueezy.

export const featureFlags: FeatureFlags = {
  payments: PaymentProviderType.LemonSqueezy, 
}

Create an account

Create an account, login on Lemon Squeezy. and complete the onboarding process to create a store.

Activate test mode

Make sure you are in test mode at the bottom left corner of the dashboard.

Get the API keys

Click on the Settings tab and then click on the Stores tab.

Copy the Store ID next to your store url, it begins with # followed by a number, and paste it beside the LEMONSQUEEZY_STORE_ID in the .env.

Click on the API tab and then click the plus icon to create a new API key.

Copy the API key and paste it beside the LEMONSQUEEZY_API_KEY in the .env.

In the terminal, run the following command to generate a random string and paste it beside the LEMONSQUEEZY_WEBHOOK_SECRET in the .env.

openssl rand -base64 32

This secret is used to verify the webhooks sent by Lemon Squeezy.

We are going to need this secret again in the next steps.

Install Ngrok

In order to test the Lemon Squeezy webhooks locally, you need to install Ngrok.

With Ngrok we can create a secure tunnel to our local server and get a public URL that Lemon Squeezy can use to send webhooks.

Sign up for a free account on Ngrok and then download & install it.

On the dashboard page, go to the Your Authtoken tab.

Below the Command Line section, click the Show Authtoken text to reveal your authtoken.

Copy the command and paste it in the terminal.

Now you can start Ngrok by running the following command:

ngrok http 3000

This will create a secure tunnel to your local server and give you a public URL that you can use to receive webhooks.

You can find the public url beside the Forwarding label in the terminal output.

We are going to use this URL to configure the Lemon Squeezy webhooks in the next step.

Make sure to keep the Ngrok process running while developing locally.

Configure the webhooks

Under the Settings tab click the Webhooks tab.

Create a new webhook by clicking the plus icon to the right.

The callback url is the Ngrok URL you got in the previous step followed by /api/lemonsqueezy/webhook.

Keep in mind that the Ngrok URL changes every time you restart it, so you need to update the webhook URL in the Lemon Squeezy dashboard every time you restart Ngrok.

The signing secret is the random string you generated in the previous step i.e the LEMONSQUEEZY_WEBHOOK_SECRET in the .env.

Lastly, select the following events:

  • subscription_created
  • subscription_updated

Save the webhook.

Create the Subscription Plans

I have pre-configured three plans in the project:

  • Basic
  • Pro
  • Premium

You can customize everything as you see fit, reducing or increasing the number of plans, and even changing the names.

You can find the subscription plan configuration object in the packages/utils/src/constants/subscriptionPlans.ts file.

Create a product

Click on the Store tab on the left sidebar followed by the Products tab.

Click on the New product button.

Fill in the product details

  • Fill in the name (e.g. Basic, Pro, Premium)
  • Provide a description
  • Choose subscription as the pricing type
  • Scroll down and click on thFe Add variant button
  • Enter Monthly as the variant name
  • Choose subscription as the pricing type
  • Enter the amount and repeat payment every month
  • Fill in the rest of the details as you see fit

Don't choose subscription has free trial, as we are going to handle the trial period in the app. If we configure the trial period in Lemon Squeezy, the customers will be required to enter their card details in order to start the trial, which is not the behavior we want.

Click on the Save and add another button.

Now do the same for the yearly variant except this time name the variant to Yearly and choose Year as the billing period.

Click on the Save and go back button.

Copy the Variant IDs

You should now have two variants for the product, one for monthly and one for yearly billing.

Below the Variants section you can click on the ... icon beside the variant and then click on Copy ID to copy the variant ID.

Go to the packages/utils/src/constants/subscriptionPlans.ts file and update the lookup keys with the corresponding variant ID you just copied.

Make sure you update the lookup keys for the development environment, right after the isDevelopment variable.

Repeat this for the other variant as well.

Lastly, fill in the rest of the details on Lemon Squeezy and then click the Publish product button.

Repeat the same process for the other plans

At this point we have created one plan (Basic plan), repeat the same process for the other plans (Pro and Premium, or call them whatever you want).

You may choose how many plans you want to create, but make sure to update the subscriptionPlans.ts configuration object with the new lookup keys/Variant IDs and subscription plan name.

Configure the Customer Portal

The customer billing portal allows your customers to manage their subscriptions and can be accessed through the billing page in your app.

You won't be able to see the Manage Subscription button in the billing page if you are trialing, make sure to subscribe to a plan first.

However, we need to activate it first in the Lemon Squeezy dashboard.

Setup the customer portal

Click on the Design tab.

Click on Portal and then enable the Customer portal option.

Beneath subscriptions enable:

  • Cancel subscriptions
  • Update subscriptions

and select all your products/plans.

Click on the Publish button when you are happy with the changes.

Theming

Play around with the theming options in the different tabs to match the customer portal with your app's design.

Test the integration

You can now test the integration by subscribing to a plan and checking if the webhook is working properly.

Run the app

In the root of your project, run the following command:

pnpm dev

In another terminal window, run the following command to start the Ngrok tunnel:

ngrok http 3000

Remember to update the webhook URL in the Lemon Squeezy dashboard with the new Ngrok URL.

Navigate to http://localhost:3000 in your browser and login using any provider.

Subscribe to a plan

Complete the onboarding flow, choose a plan and it will create a free trial in the database.

The free trial period is set to 14 days by default, you can change this though in the lemonSqueezy.service.ts file.

The free trial is solely being managed in the app/database, not through Lemon Squeezy.

Go to the Billing page

In your app, navigate to the billing page.

Upgrade to a plan, go through the checkout process and complete the payment.

You can use the test card number 4242 4242 4242 4242 with any future expiration date and any CVC code to test the payment functionality.

Manage the subscription

After subscribing to a plan, you should see a Manage Subscription button in the billing page.

The Subscription data should also be updated in the database through the webhook.

You can click on the Manage Subscription button to see the customer portal in action and try to update or cancel the subscription.

The changes should be reflected in the database as well as the billing page when you are redirected back to the app if everything is working correctly.

You can also check if a subscription has been created in the Lemon Squeezy dashboard under the Store > Subscriptions tab.

Production Configuration

In the Lemon Squeezy deployment section, I will walk you through the steps to configure Lemon Squeezy for production.

Last updated on