Integrating Paddle Checkout with Next.js App Router

A step-by-step guide to integrating Paddle Checkout with your Next.js app router.


Prerequisites

  • A Paddle account in sandbox mode with at least one product set up.
  • A Next.js project already initialized. If you don't have one, you can create a new Next.js project by following the Next.js Getting Started Guide.

Getting Our Tokens

After setting up your Paddle account, you need to obtain the necessary tokens to use Paddle Checkout. Navigate to the Authentication section under Developer Tools.

  1. Create a Client-side token and copy its value.
  2. Open your .env file in your Next.js project and add the following lines:
NEXT_PUBLIC_PADDLE_CLIENT_TOKEN=test_XXXXXX
NEXT_PUBLIC_PADDLE_ENV=sandbox

Here, the NEXT_PUBLIC_PADDLE_CLIENT_TOKEN is your client-side token, and the NEXT_PUBLIC_PADDLE_ENV variable indicates whether you are in sandbox or production mode.


Installing Paddle.js

With everything set up on Paddle, we can move on to integrating it with our Next.js project. Install the Paddle SDK using the following command:

pnpm add @paddle/paddlejs

If you are using npm or yarn, use the equivalent commands:

npm install @paddle/paddlejs
yarn add @paddle/paddlejs

Creating the hook

Now, we need to create a hook that will handle the checkout process. Create a new file in your hooks directory and name it usePaddle.ts

// hooks/usePaddle.ts
"use client";
import {
  initializePaddle,
  InitializePaddleOptions,
  Paddle,
} from "@paddle/paddle-js";
import { useEffect, useState } from "react";
 
export default function usePaddle(): Paddle | undefined {
  const [paddle, setPaddle] = useState<Paddle>();
 
  useEffect(() => {
    const environment =
      process.env.NEXT_PUBLIC_PADDLE_ENV === "production"
        ? "production"
        : "sandbox";
    const token = process.env.NEXT_PUBLIC_PADDLE_CLIENT_TOKEN;
 
    if (!token) {
      console.error("Paddle client token is not defined.");
      return;
    }
 
    initializePaddle({
      environment,
      token,
    } as InitializePaddleOptions)
      .then((paddleInstance) => {
        if (paddleInstance) {
          setPaddle(paddleInstance);
        } else {
          console.error("Failed to initialize Paddle.");
        }
      })
      .catch((error) => {
        console.error("Error initializing Paddle:", error);
      });
  }, []);
 
  return paddle;
}

Create a checkout button

Now that we have created the hook, we can create a button to trigger the checkout process. Create a new file in your components directory and name it PaddleCheckoutButton.tsx:

// components/PaddleCheckoutButton.tsx
"use client";
import usePaddle from "@/hooks/usePaddle";
 
export function PaddleCheckoutButton() {
  const paddle = usePaddle();
 
  const openPaddleCheckout = () => {
    paddle?.Checkout.open({
      items: [
        {
          priceId: "pri_XXXXXXX", // Replace with your product ID
          quantity: 1,
        },
      ],
    });
  };
 
  return (
    <button onClick={openPaddleCheckout} >
      Checkout
    </button>
  );
}

Make sure to replace pri_XXXXXXX with your product id.


Conclusion

That's it! You have successfully integrated Paddle Checkout with your Next.js app. You can now test the checkout process by clicking the button you created. To get notified when a purchase is made, consider using the Paddle Webhooks feature (a guide for this will be coming soon).

For further improvements, you might want to:

  • Implement additional checkout options and customizations.
  • Add error handling and user notifications for a better user experience.
  • Explore more advanced features of Paddle and Next.js to enhance your application.

Thank you for following along. Stay tuned for more tutorials and updates!