LemonSqueezy is used to handle payments. It has built-in VAT/sales tax
compliance, affiliates & marketing tools.
Set up LemonSqueezy
First, create an LemonSqueezy account or sign in. Create a store & add your digital products. It usually takes 1-2 days for it to get verified. Once that is ready, we’ll set up the app to handle webhooks from LemonSqueezy:-
Go to
Settings -> Webhooks
and add a new WebhookAdd a new webhook to LemonSqueezy
-
Fill in Callback URL with
https://yourwebsite.com/api/payments/lemonsqueezy
& select all events. -
Add your defined
LEMON_SQUEEZY_WEBHOOK_SECRET
to your.env
file.Select all events & specify your LEMON_SQUEEZY_WEBHOOK_SECRET
Handling webhooks
Underapp/api/payments/lemonsqueezy/route.ts
you’ll find an API route that handles both one-time-payments and subscriptions from LemonSqueezy.
It will do the following:
- Verify if the request is legitimate by matching
LEMON_SQUEEZY_WEBHOOK_SECRET
- Get purchased product, based on the
variant_id
- Match the user email with our
profiles
table- If there is a matching user, it will edit
purchase
column of the matching user in theprofiles
table based on the logic you specify in the webhook. Feel free to add any logic here you’ll use in your app to handle page access. - If no matching user is found, it will simply update the
purchases
table with a new entry
- If there is a matching user, it will edit
Storing webhook data
We’ll store all webhook data coming from LemonSqueezy in our own database as
well.
purchases
table should already exist if you followed the Quick Setup guide and ran the Supabase migrations using the CLI:
supabase/migrations/20240000000007_purchases.sql
Make sure RLS is turned on. We don’t need to add any rules as we’ll be using the service key for to interact with this table.
Set up paywall
All demo apps include a paywall using a credit system. You can modify the logic inapp/api/payments/lemonsqueezy/route.ts
to add more credits after a succesfull purchase.
You can adjust the code to handle access based on the
purchase
column having
a specific value. This allows for handling lifetime access systems or
subscriptions.Logic flow
The codebase includes a credit-based paywall system that uses cached queries for better performance. Here’s how it works:- Check if the demo app is paywalled (specified in
toolConfig.ts
). - Uses cached queries to efficiently verify user credit balance:
- If yes, grant access.
- If no, display the
PaymentModal
component.
The cached queries system helps reduce database load and improve performance
compared to direct Supabase queries.