Overview
The Easy Way: Direct Linking
The easiest and fastest way to start accepting payments with Lemon Squeezy is to simply link your customers directly to your Lemon Squeezy store or specific product checkout pages. With this simple link, people can browse and buy all your products directly from Lemon Squeezy's hosted pages.
If you're aiming for something simple, like selling a one-time download (e.g., a database, an ebook, a template), this method can be perfectly sufficient. You can easily attach your digital product files within Lemon Squeezy, and they handle the delivery upon successful payment.
However, this method is quickly limited if you need tighter integration with your own application. Since the payment process happens entirely on Lemon Squeezy, it's completely decoupled from your app. Your application won't automatically know if a purchase was made or who made it without manual checks or more complex workarounds.
The Full Integration (The Rest of This Guide)
For a seamless user experience where payments unlock features or content within your own application, a deeper integration is required. This is what the rest of this guide covers. Integrating Lemon Squeezy fully into your SaaS requires three main components:
- Setting up the LemonSqueezy SDK (your backend)
- Implementing the checkout flow (your frontend)
- Configuring webhooks for real-time updates (your backend)
So let's get straight to the point: integrating LemonSqueezy into your SaaS requires three main components:
- Setting up the LemonSqueezy SDK (your backend)
- Implementing the checkout flow (your frontend)
- Configuring webhooks for real-time updates (your backend)
Frontend Integration
First, you need to add the LemonSqueezy script to your frontend. You can drop this script somewhere in your layout.tsx or app.tsx.
<Script
src="[https://app.lemonsqueezy.com/js/lemon.js](https://app.lemonsqueezy.com/js/lemon.js)"
strategy="beforeInteractive"
/>
And this is basically it for the frontend!
Backend Setup
On the backend, you can now install the LemonSqueezy SDK:
pnpm install @lemonsqueezy/lemonsqueezy.js
On LemonSqueezy, create a store and grab your store ID as well as your API key. Make sure to never expose your API key in the frontend.
The Checkout Flow
The main flow goes like this:
- Your user clicks somewhere on your frontend, calling your backend or server action to generate a checkout URL
- The server action uses the LemonSqueezy SDK to generate a checkout URL
- The checkout URL is returned to the frontend
- The frontend redirects the user to the checkout URL (or embeds it in a modal)
For reference, here's the server action that I use:
export async function getCheckoutURL(variantId: number) {
// We run that `configureLemonSqueezy` function every time we need the backend SDK
configureLemonSqueezy();
// You can do an auth check here
// The create checkout function is provided by the LemonSqueezy SDK
// We can configure a few options, here we are choosing to embed it
const checkout = await createCheckout(
process.env.LEMONSQUEEZY_STORE_ID!,
variantId,
{
checkoutOptions: {
embed,
media: false,
logo: !embed,
},
checkoutData: {
email: session.user.email ?? undefined,
custom: {
// You can add any custom data you need here
user_id: session.user.id,
},
},
productOptions: {
enabledVariants: [variantId],
redirectUrl: url,
receiptButtonText: "",
receiptThankYouNote: "",
},
}
);
return checkout.data?.data.attributes.url;
}
With that method set up in your backend, you can now call it from your frontend. This will generate a checkout, open it in a modal, and prefill it with the correct info about your product
Setting Up Webhooks
Now that we have both the frontend and backend setup, we need to set up webhooks. Webhooks are crucial for keeping your application in sync with LemonSqueezy events. At this stage, your backend only generated a checkout URL but has no idea if the purchase went through or not.
Here, you could technically use the LemonSqueezy SDK to check if you can find a subscription or payment with the user's id we saved earlier, but :
- It's super inefficient (You don't want to call the LemonSqueezy API every time a user make an action)
- It's not very secured either
We need a way for our backend to be notified when a purchase is made and update our database accordingly.
Entering webhooks! You can enable them directly in your LemonSqueezy dashboard. An important note is that you will need to set up an ngrok tunnel during development, as you can't directly send webhooks to your http localhost.
Here's how to do it:
- Go to your LemonSqueezy dashboard
- Navigate to Settings > Webhooks
- Add a new webhook
- Select the events you want to monitor, such as:
- Order created
- Subscription created
- Subscription updated
- Subscription cancelled
Every time LemonSqueezy receive a payment from one of your user, it will send a request to your backend with informations (eg: userId: 123 just purchased a product with id: 456, cancelled his subscription or upgraded it) This is the part where you need to set up a webhook endpoint in your backend. If you're using Next.js, you can create a new API route.
You will need to handle every event you selected in the previous steps. If you're building a SaaS, this is the part where you unlock your content after a purchase or update the user's subscription status. LemonSqueezy will also send you webhook if a client cancels their subscription, upgrade, if a payment fails, etc...
Time Investment
Even though we're using a payment processor that comes with webhooks, integrated checkout, and subscription management, you can quickly see that piecing all of this together in your app is not easy, and it can take days to get it right.
There are multiple caveats to handle. For example, LemonSqueezy does not prevent a user from subscribing to a plan multiple times. If you're not careful, the same user could be billed multiple times a month.
As a general overview, here are all the steps you'll need to handle for a complete integration:
- Sync up the LemonSqueezy products/subscriptions with your database, making sure to use the SDK so that the products/subscriptions are up to date (price, duration, etc.)
- Handle the checkout flow
- Identify and handle every webhook event type your app might need (Order created, Subscription created, Subscription updated, Subscription cancelled)
- Handle the subscription management (renewal, cancellation, etc.)
Save Time with Hyperlaunch
The main idea is really just to let you focus on building your actual idea. Hyperlaunch takes care of the necessary but repetitive parts – the landing page, payment integration, user profiles. This saves you days of development time you'd otherwise spend setting those basics up again, freeing you to build something unique and start growing your SaaS.
Ready to save time and launch smarter? Check out Hyperlaunch here.
