DEV Community

Aaron K Saunders
Aaron K Saunders

Posted on

A Complete Guide to Building a Payment System with Payload CMS and Lemon Squeezy

Learn how to build a full payment system using the modern stack of Payload CMS, Next.js API Routes, and Lemon Squeezy, including a deep dive into debugging common API errors.

Integrating payments into an application can be a complex task, especially when you're working with a modern headless stack. How do you handle server-side logic securely when your CMS is embedded in a Next.js app?

In this guide (and the embedded video), we'll build a complete, production-ready payment system from start to finish using Payload CMS, Lemon Squeezy, and the power of Next.js API Routes.

The Architectural Shift: Why Next.js API Routes?

If you've used older versions of Payload, you might be familiar with creating custom endpoints directly within the CMS config. The game has changed. With Payload's deep integration into Next.js, the modern, recommended approach is to handle all custom server-side logic using Next.js API Routes.

This gives you:

  • Seamless Integration: Your backend logic lives alongside your frontend code in a familiar structure (/pages/api or /app/api).
  • Serverless-Ready: Perfectly aligns with deploying on serverless platforms like Vercel.
  • Unified Tooling: No need to context-switch. You're in a Next.js environment from top to bottom.

The Full Video Tutorial

This video is a comprehensive walkthrough of the entire process. I cover everything from the initial setup to handling the final webhook confirmation.

What We'll Cover in the Video

I've structured the tutorial to be a step-by-step guide, covering every critical stage:

  • โœ… Initial Setup: Configuring products in Lemon Squeezy and collections in Payload CMS.
  • ๐Ÿ‘จโ€๐Ÿ’ป Building the Client: Creating a reusable client to communicate with the Lemon Squeezy API.
  • ๐Ÿš€ Coding the API Routes: We'll build two key serverless functions in Next.js:
    1. A Checkout API Route to generate payment links.
    2. A Webhook Handler API Route to process order confirmations from Lemon Squeezy.
  • ๐ŸŒ Testing Locally: Using ngrok to expose our local API routes to the internet so Lemon Squeezy can send webhooks to our machine.
  • ๐Ÿ› Real-World Debugging: I hit real errors during the recording, and I'll show you exactly how to fix them.

Don't Skip the Debugging Chapter!

Things rarely work perfectly the first time. Instead of editing it out, I dedicated a full chapter to troubleshooting the integration. We'll fix frustrating, real-world errors related to:

  • Missing Store ID parameters.
  • Incorrect custom data types (the classic string vs. number issue).
  • Other common API request errors that can leave you stuck for hours.

Wrapping Up

By the end of this tutorial, you'll not only have a functional payment system but also a solid understanding of the modern architecture for building server-side logic with Payload CMS and Next.js.

I hope this helps you out! If you have any questions, drop a comment below or on the video. Happy coding!

๐Ÿ“š USEFUL RESOURCES

GitHub Repository: https://github.com/aaronksaunders/payload-lemon-1
Payload CMS Documentation: https://payloadcms.com/docs
Lemon Squeezy API Docs: https://docs.lemonsqueezy.com
ngrok Setup Guide: https://ngrok.com/docs

Source Code

GitHub logo aaronksaunders / payload-lemon-1

Payload CMS + LemonSqueezy Integration Example

Payload Lemon - E-commerce with Payload CMS & Lemon Squeezy

A modern e-commerce solution built with Payload CMS 3.x and Lemon Squeezy payment processing, featuring custom checkout creation and webhook handling.

๐Ÿš€ Features

  • Payload CMS 3.x - Headless CMS with Next.js integration
  • Lemon Squeezy Integration - Payment processing and checkout creation
  • Custom API Routes - Next.js API routes for checkout and webhook handling
  • TypeScript - Full type safety throughout the application
  • SQLite Database - Local development with easy deployment options
  • Webhook Support - Handle Lemon Squeezy order events

๐Ÿ“‹ Prerequisites

  • Node.js 18.20.2 or higher
  • pnpm 9 or higher
  • Lemon Squeezy account
  • ngrok account (for webhook testing)

๐Ÿ› ๏ธ Installation

1. Clone and Install Dependencies

git clone <your-repo-url>
cd payload-lemon
pnpm install
Enter fullscreen mode Exit fullscreen mode

2. Environment Setup

Create a .env.local file in the project root:

# Payload CMS Configuration
PAYLOAD_SECRET=your-super-secret-payload-key-here
DATABASE_URI=file:./payload-lemon.db
# Lemon Squeezy Configuration
LEMON_SQUEEZY_API_KEY=your-lemon-squeezy-api-key
LEMON_SQUEEZY_STORE_ID=your-store-id
LEMON_SQUEEZY_WEBHOOK_SECRET=your-webhook-secret

# Next.js Configuration
NEXT_PUBLIC_SERVER_URL=http://localhost:3000

โ€ฆ
Enter fullscreen mode Exit fullscreen mode

Top comments (0)