Paddle Billing
Search

Build and deploy Next.js app with Vercel and Supabase

Get a step-by-step overview of how to build a Next.js app with Paddle Billing, including a localized pricing page, integrated inline checkout, and screens for customers to manage their payments.

Next.js is an open source web development framework that you can use to create high-quality web apps. It's built on top of React, a popular JavaScript library for building user interfaces, and includes a range of features designed to make building web apps easier.

You can use our Paddle Billing SaaS starter kit to quickly create and deploy a Next.js app that includes everything you need for subscription billing — including a localized pricing page, integrated checkout, auth and user management, and screens for customers to manage their payments.

Grid of logos used in the stater kit: Paddle, Supabase, Next.js, and Vercel.

What are we building?

In this tutorial, we'll create a Next.js app that's integrated with Paddle Billing and deploy it to Vercel. Our app includes:

  • A beautiful, three-tier pricing page that's fully localized for 200+ markets.
  • A high-converting checkout that's fully integrated with your app, built with Paddle Checkout.
  • User management and auth handled by Supabase.
  • Ready-made screens to let customers manage their payments and subscriptions.
  • Automatic syncing of customer and subscription data between Paddle and your app using webhooks.

Check out the demo at paddle-billing.vercel.app.

Illustration showing two screens from the starter kit: the pricing page and a subscription screen. The pricing page has three tiers on it, with a toggle for monthly and annual.

We'll learn how to:

  • Set up Paddle Billing in sandbox.
  • Create a notification destination for syncing data.
  • Create products and prices for our SaaS app.
  • Configure and deploy a Next.js app to Vercel.
  • Take a test payment.
  • Transition from sandbox to live.

Before you begin

Sign up for Paddle

Paddle Billing is a complete digital product sales and subscription management platform, designed for modern software businesses. Our API-first platform takes care of payments, localization, and subscription management for you.

You'll need a Paddle account to get started. There are two kinds of Paddle account:

  • Sandbox — for testing and evaluation
  • Live — for selling to customers

For this tutorial, we recommend signing up for a sandbox account. You can transition to a live account later when you've built your integration and you're ready to start selling.

If you sign up for a live account, you'll need to complete account verification. This is where we ask for some information from you to make sure that we can work together. While we're verifying your account, you can't launch a checkout or sell on the Paddle platform.

Sign up for Vercel and Supabase

As part of our tutorial, we're going to deploy our app to Vercel and use Supabase.

  • Vercel is a developer platform that you can use to host and deploy web apps using serverless technology, designed for Next.js. We'll deploy our app to Vercel.
  • Supabase is a developer platform that includes databases, authentication, and other features. Our app integrates with Supabase to handle user management and authentication, as well as syncing customer data with Paddle Billing using webhooks.

If you don't have Vercel and Supabase accounts, you'll need to sign up — it's free to get started.

You'll also need a Git provider to store the code that powers your app. When deploying to Vercel, the deployment screen walks you through setting up an account with GitHub (recommended), GitLab, or Bitbucket, if you don't already have one.

Set up your local environment

To work on the starter kit locally, you'll need an IDE like Visual Studio Code and:

You don't need to set up your local development environment to get a working demo on Vercel, so you can come back to this later when you're ready to start building.

Overview

Create and deploy a Next.js app integrated with Paddle Billing in four steps:

  1. Start deploy to Vercel

    Clone the Git repo, integrate with Supabase, configure Paddle variables, and deploy.

  2. Set up your products catalog

    Create products and prices in Paddle, then update your app to use them.

  3. Add your website and test

    Add your website to Paddle, then give your app a spin — take a test payment and explore the customer billing screens.

  4. Build your app, then transition to live

    Build your app on top of our starter kit, then transition your Paddle Billing account to live to start selling.

1. Start deploy to Vercel

To create a Vercel project ready for us to set up, click the button to get started:

Create Git repo

First, create a clone of our starter kit repo. This creates a copy of the code in a repo in your Git provider account, so you can build your app on top of our project.

Click the Continue with GitHub, Continue with GitLab, or Continue with Bitbucket buttons to connect your Git provider to Vercel, if you haven't already. Then, enter a name for your repo.

Screenshot of the deploy to Vercel workflow, showing the Get started section. There are three buttons to continue with GitHub, GitLab, and Bitbucket.

The repo name becomes the name of your project in Vercel, and it's also used for deploy preview URLs. If the name is taken, Vercel appends some characters to your project name when creating a deploy preview URL.

Integrate with Supabase

Next, click Add to walk through integrating with Supabase.

Screenshot of the deploy to Vercel workflow, showing the add integration section. It shows Supabase with an Add button.

You can give your project any name. We recommend using a password manager to generate and store a secure password.

Make sure the Create sample tables with seed data box is checked. This creates tables in Supabase to store customer and subscription data for our app.

Screenshot of the new project modal in Supabase. It shows fields for project name, password, and region. There is a checkbox that says 'create sample tables with seed data' that's checked.

Configure Paddle variables

We need to supply some variables so that our app can interact with our Paddle account.

Screenshot of the deploy to Vercel workflow, showing the configure project section. It shows four required environment variables.

There are four variables that we need:

PADDLE_API_KEYAn API key, used for interacting with Paddle data in the backend. For example, syncing customer and subscription data with Supabase.
NEXT_PUBLIC_PADDLE_CLIENT_TOKENA client-side key, used for interacting with Paddle in the frontend. For example, getting localized prices for pricing pages and opening a checkout.
PADDLE_NOTIFICATION_WEBHOOK_SECRETA secret key used for verifying that webhooks came from Paddle and haven't been tampered with in transit. Important for security.
NEXT_PUBLIC_PADDLE_ENVEnvironment for our Paddle account. sandbox for sandbox accounts; production for live accounts.

Get an API key and client-side token

Client-side tokens and API keys are used for authentication. Paddle creates a default client-side token and API key when you sign up, but we recommend generating separate ones for our app.

  1. Go Paddle > Developer tools > Authentication

  2. Click Generate API key under the API keys section.

  3. Give your key a name and description, then click Generate.

  4. From the list of API keys, click the action menu next to the key you just created, then choose Copy key from the menu.

  5. Paste your key as PADDLE_API_KEY in the Deploy to Vercel screen.

  6. Head back to the authentication screen in Paddle, then click Generate client-side token under the Client-side tokens section.

  7. Give your client-side token a name and description, then click Generate.

  8. From the list of client-side tokens, click the action menu next to the client-side token you just created, then choose Copy token from the menu.

  9. Paste your key as NEXT_PUBLIC_PADDLE_CLIENT_TOKEN in the Deploy to Vercel screen.

Illustration of the generate API key drawer in Paddle. There are fields for name and description.

Illustration of the list of API keys in Paddle. There are columns for name, description, and key. The action menu is open for the first item, showing options for show key, copy key, and revoke.

To learn more about client-side tokens and API keys, see: Authentication

Treat your API key like a password. Keep it safe and never share it with apps or people you don't trust.

Create a webhook destination

You can use notifications to get webhooks from Paddle when something important happens in your Paddle system, like a customer is updated or a new subscription is created. We use webhooks in our app to keep our app in sync with Paddle, letting customers see and manage their subscriptions and payments.

To start receiving webhooks, create a notification destination. This is where you can tell Paddle which events you want to receive and where to deliver them to.

  1. Go to Paddle > Developer Tools > Notifications.

  2. Click New destination.

  3. Give your destination a name.

  4. Make sure notification type is set to webhook — this is the default.

  5. Enter https://<PROJECTNAME>.vercel.app/api/webhook as your URL, where <PROJECTNAME> is the name of your Vercel project. You can always rename this later. For example: https://paddle-billing.vercel.app/api/webhook.

  6. Check the select all events box.

  7. Click Save destination when you're done.

  8. From the list of notification destinations, click the action menu next to the notification destination you just created, then choose Edit destination from the menu.

  9. Copy the secret key and paste it as PADDLE_NOTIFICATION_WEBHOOK_SECRET.

Illustration of the new destination drawer in Paddle. There are fields for description, type, URL, and version. Under those fields, there's a section called events with a checkbox that says 'select all events'

Illustration of the edit destination drawer in Paddle. The secret key field is called out.

To learn more about webhooks and notification destinations, see: Create a notification destination

Set your environment

For NEXT_PUBLIC_PADDLE_ENV, enter:

  • sandbox if you're working with a sandbox account
  • production if you're working with a live account

We recommend working with a sandbox account for this tutorial. Sandbox accounts are designed for testing and evaluation. Live accounts must be approved by Paddle before you can open checkouts for them.

Review and deploy

At this point, we've done everything that we need to deploy. Review your settings, then click Deploy.

Wait for Vercel to build. If everything went well, our build should complete successfully!

Screenshot of the complete screen for the deploy to Vercel workflow. It says 'congratulations!' and there's a preview of our app.

However, if we open our deploy preview link then our integration isn't ready yet — our pricing page doesn't display and prices and the buttons to get started don't work. We'll fix these in the next step.

2. Set up your product catalog

To make our app work properly with Paddle, we need to specify how products in our app map to products in Paddle.

Model your products and prices

A complete product in Paddle is made up of two parts:

  • A product entity that describes the item, like its name, description, and an image.
  • At least one related price entity that describes how much and how often a product is billed.

You can create as many prices for a product as you want to describe all the ways you bill for it.

Our template comes with a three tier pricing page, with plans for Free, Basic, and Pro. For each of these plans, there are monthly and annual options.

We can mirror this in Paddle, modeling this as three products with two prices for monthly and annual:

Product: Free

  • Price: Free (monthly)
  • Price: Free (yearly)

Product: Basic

  • Price: Basic (monthly)
  • Price: Basic (yearly)

Product: Pro

  • Price: Pro (monthly)
  • Price: Pro (yearly)

Create products and prices

You can create products and prices using the Paddle dashboard or the API.

  1. Go to Paddle > Catalog > Products.

  2. Click New product.

  3. Enter details for your new product, then click Save when you're done.

  4. Under the Prices section on the page for your product, click New price.

  5. Enter details for your new price. Set the billing period to Monthly to create a monthly price.

  6. Click Save when you're done.

  7. Create another price, setting the billing period to Annually and Save.

Illustration showing the new product drawer in Paddle. There are fields for product name, tax category, and description

Repeat for each of your products, until you have three products with two prices each.

To learn more products and prices, see: Create products and prices

Update pricing constants

Now we've created products and prices, we need to update our app with details of our new prices.

Clone your Git repo locally, then open src/constants/pricing-tier.ts in your IDE. If you're using GitHub, you can use GitHub Desktop to clone a repo locally if you're not familiar with Git.

pricing-tier.ts contains constants that we use in our pricing page and checkout. Swap the Price IDs starting with pri_ with price IDs for the prices we just created.

You can also edit src/constants/pricing-tier.ts directly on your Git platform if you've not set up your local development environment.

For example:

You can get Paddle IDs for your prices using the Paddle dashboard:

  1. Go to Paddle > Catalog > Products, then click the product you want to get a price ID for in the list.

  2. Click the action menu next to a price in the list, then choose Copy price ID from the menu.

  3. Paste the ID as the value for priceId.month or priceId.year in src/constants/pricing-tier.ts.

Add all your price IDs, then commit and push your changes to the main branch on Git.

Vercel automatically rebuilds your site at this point. You can hop over the Vercel dashboard to check on the build progress.

Screenshot of the project page in Vercel. It shows that our site is building.

When it's done, your pricing page should display prices, but you won't be able to checkout just yet. This is our next step.

3. Add your website to Paddle and test

To keep the Paddle platform safe for everyone, you must add your website to Paddle before you can launch a checkout from it. This protects you as a seller, making sure that only you are able to sell your products.

Get your website approved

If you're using a sandbox account, website approval is instant. You'll need to add your domain, but our seller verification team don't check your website.

Website approval makes sure you own the domains where you use Paddle Checkout, and that the products sold meet the Paddle acceptable use policy.

Get your website approved using the Paddle dashboard:

  1. Go to Paddle > Checkout > Website approval.

  2. Click Add a new domain, enter your Vercel demo app link, then click Submit for Approval.

  3. Wait for approval.

If you're using a sandbox account, your website is automatically approved right away. You should see a green status symbol that says "Approved."

For live accounts, website approval may take a few days while the Paddle seller verification team check your website to make sure you're able to sell with Paddle. For more information, see: Website verification FAQs

Set your default payment link

Your default payment link is a quick way to open Paddle Checkout for a transaction. It's also used in emails from Paddle that let customers manage their subscription. It's typically your checkout page, or another page that includes Paddle.js.

We'll set our default payment link to the checkout page in our starter kit.

  1. Go to Paddle > Checkout > Checkout settings.

  2. Enter your Vercel demo app link under the Default payment link heading.

  3. Click Save when you're done.

To learn more about what a default payment link is for, see: Set your default payment link

Check your notification destination endpoint

If the name of our project name in Vercel is taken, Vercel appends some characters to your project name when creating a deploy preview URL.

Earlier, we entered https://<PROJECTNAME>.vercel.app/api/webhook as the endpoint for our notification destination. If your deploy preview URL doesn't match your project name, update this URL in Paddle. You can find your deploy URL in your Vercel dashboard.

Test!

We're now ready to take a test payment! Open your Vercel demo site. You should notice that Paddle returns the prices you entered for each of your plans on your pricing page.

Screenshot of the pricing page from our app. It shows three tiers, which show prices, with a toggle to switch from monthly to annual.

Click Get started to launch a checkout for a plan, then take a test payment.

If you're using a sandbox account, you can take a test payment using our test card details:

Email addressAn email address you own
CountryAny valid country supported by Paddle
ZIP code (if required)Any valid ZIP or postal code
Card number4242 4242 4242 4242
Name on cardAny name
Expiration dateAny valid date in the future.
Security code100

After checkout is completed, head back to the homepage and click Sign in. Have a look at the subscriptions and payments pages. They pull information from Paddle about a customer's subscriptions and transactions.

4. Build your app, then go to live

You're done! You can use this starter kit as a basis for building a SaaS app on Paddle Billing.

Once you've built your app, transition to a live account to start taking real payments.

  1. Sign up for a live account, then follow our go-live checklist to transition from sandbox to live.

  2. Update your Vercel environment variables so they're for your live account.

  3. Create new schemas in Supabase for your live data.

  4. Set up Paddle Retain to handle payment recovery.

Next steps

That's it! Now you've built a Next.js app with Paddle Billing and deployed it to Vercel, you might like to hook into other features of the Paddle platform.

Do more with Paddle.js

Our starter kit passes prices to Paddle.js to display localized pricing on our pricing page and open a checkout to create subscriptions. There are a bunch of properties and settings you can pass to Paddle.js that give you more control over how opened checkouts work.

For example, you can prepopulate a discount, set the language that Paddle Checkout uses, or restrict payment options shown to customers.

Build advanced subscription functionality

Paddle Billing is designed for modern SaaS businesses, letting you build workflows to pause and resume subscriptions, flexibly change billing dates, and offer trials.

Integrate with Paddle Retain

Paddle Retain combines world-class subscription expertise with algorithms that use millions of data points to recover failed payments, reduce churn, and proactively upgrade plans.