Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Ready to squeeze some payments into your Next.js 14 app? Let’s integrate Lemon Squeezy and make your app router application as fresh as a citrus grove. 🍋
Lemon Squeezy is the hip new kid on the block for handling payments. It’s simple, developer-friendly, and perfect for SaaS products. Plus, it plays nice with Next.js. Win-win!
Before we dive in, make sure you’ve got:
Got all that? Let’s juice this lemon! 🍋💦
First, let’s add the Lemon Squeezy SDK to our project:
npm install @lemonsqueezy/lemonsqueezy.js
Create a .env.local
file in your project root and add your Lemon Squeezy API key:
LEMONSQUEEZY_API_KEY=your_api_key_here
Next.js Configuration
/** @type {import('next').NextConfig} */
const nextConfig = {
env: {
LEMONSQUEEZY_API_KEY: process.env.LEMONSQUEEZY_API_KEY,
},
};
module.exports = nextConfig;
Let’s create a utility file to initialize our Lemon Squeezy client:
Lemon Squeezy Client Utility
import { LemonSqueezy } from '@lemonsqueezy/lemonsqueezy.js';
const lemonSqueezy = new LemonSqueezy(process.env.LEMONSQUEEZY_API_KEY);
export default lemonSqueezy;
Now, let’s create a React component to handle our payment button:
Payment Button Component
'use client';
import { useState } from 'react';
import lemonSqueezy from '../utils/lemonSqueezyClient';
export default function PaymentButton({ productId }) {
const [isLoading, setIsLoading] = useState(false);
const handlePayment = async () => {
setIsLoading(true);
try {
const checkout = await lemonSqueezy.createCheckout({
productId: productId,
checkoutOptions: {
embed: true,
},
});
window.location.href = checkout.data.attributes.url;
} catch (error) {
console.error('Payment error:', error);
} finally {
setIsLoading(false);
}
};
return (
<button
onClick={handlePayment}
disabled={isLoading}
className="bg-yellow-400 hover:bg-yellow-500 text-black font-bold py-2 px-4 rounded"
>
{isLoading ? 'Processing...' : 'Buy Now'}
</button>
);
}
Now, let’s use our PaymentButton
component in a page:
Product Page Component
import PaymentButton from '../components/PaymentButton';
export default function ProductPage() {
return (
<div className="container mx-auto px-4 py-8">
<h1 className="text-3xl font-bold mb-4">Awesome Product</h1>
<p className="mb-4">This product will change your life!</p>
<PaymentButton productId="your_product_id_here" />
</div>
);
}
To keep your app in sync with Lemon Squeezy events (like successful payments), you’ll want to set up a webhook endpoint:
Webhook Handler
import { NextResponse } from 'next/server';
import lemonSqueezy from '../../../utils/lemonSqueezyClient';
export async function POST(req) {
const body = await req.json();
const signature = req.headers.get('x-signature');
if (!signature) {
return NextResponse.json({ error: 'No signature provided' }, { status: 400 });
}
try {
const event = await lemonSqueezy.verifyWebhook({
body: JSON.stringify(body),
signature,
});
// Handle different event types
switch (event.type) {
case 'order_created':
// Handle new order
break;
case 'subscription_created':
// Handle new subscription
break;
// Add more cases as needed
}
return NextResponse.json({ received: true }, { status: 200 });
} catch (err) {
console.error('Webhook error:', err);
return NextResponse.json({ error: 'Webhook error' }, { status: 400 });
}
}
Place this file in app/api/webhooks/route.js
to create a /api/webhooks
endpoint.
And there you have it! You’ve just integrated Lemon Squeezy payments into your Next.js 14 app. Your users can now make payments smoother than a freshly squeezed lemonade. 🍋
Remember to:
Now go forth and monetize your Next.js app like a boss! 💰
Want to level up your Next.js skills even more? Check out these juicy articles: