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 -> Webhooksand add a new Webhook
Add 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_SECRETto your.envfile.
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
profilestable- If there is a matching user, it will edit
purchasecolumn of the matching user in theprofilestable 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
purchasestable 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
PaymentModalcomponent.
The cached queries system helps reduce database load and improve performance
compared to direct Supabase queries.
