Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

Integrate Lemon Squeezy Payments in Next.js 14: A Zesty Guide

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. 🍋

Why Lemon Squeezy?

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!

Prerequisites

Before we dive in, make sure you’ve got:

  • A Next.js 14 app using the App Router
  • A Lemon Squeezy account
  • Node.js and npm installed

Got all that? Let’s juice this lemon! 🍋💦

Step 1: Install the Lemon Squeezy SDK

First, let’s add the Lemon Squeezy SDK to our project:

npm install @lemonsqueezy/lemonsqueezy.js

Step 2: Set Up Environment Variables

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;

Step 3: Create a Lemon Squeezy Client

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;

Step 4: Create a Payment Component

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>
  );
}

Step 5: Implement the Payment Flow

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>
  );
}

Step 6: Handle Webhooks (Optional, but Recommended)

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.

Conclusion

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:

  • Keep your API keys secret
  • Test thoroughly in Lemon Squeezy’s sandbox environment
  • Handle errors gracefully
  • Implement proper security measures for your webhook endpoint

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:

Leave a Reply

Your email address will not be published. Required fields are marked *