For AI agents and LLMs: a structured documentation index is available at /llms.txt. Every page has a Markdown sibling — append .md to any URL.

Skip to content
Docs

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.

AI summary

Deploy the Paddle Next.js SaaS starter kit to Vercel with Supabase auth in four steps: configure Paddle environment variables, create your product catalog, update price IDs in the app, then take a test payment.

  • • Set four env vars: PADDLE_API_KEY, NEXT_PUBLIC_PADDLE_CLIENT_TOKEN, PADDLE_NOTIFICATION_WEBHOOK_SECRET, and NEXT_PUBLIC_PADDLE_ENV.
  • • After deployment, update src/constants/pricing-tier.ts with your actual price IDs — the app won't display prices or open checkouts until the placeholder pri_ IDs are replaced.
  • • You must add your Vercel deploy URL to Paddle > Checkout > Website approval and set it as the default payment link before checkouts will open successfully.

This tutorial walks through deploying the Paddle Next.js SaaS starter kit to Vercel, hooking it up to your Paddle account, and taking a test payment. By the end, you'll have a working three-tier subscription app integrated with Supabase for auth and Paddle webhooks for syncing customer data.

For a quick overview of what's in the kit before you dive in, see the Next.js starter kit reference.

Check out the live demo of the starter kit to explore how it works

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

By the end of this tutorial you'll have:

  • Set up Paddle Billing in sandbox.
  • Created a notification destination for syncing data.
  • Created products and prices for a SaaS app.
  • Deployed a Next.js app to Vercel.
  • Taken a test payment.
  • Learned how to transition from sandbox to live.

Before you begin

Sign up for Paddle

Paddle is a complete merchant-of-record platform for modern software businesses. Our API-first platform takes care of payments, localization, and subscription management for you.

Sign up for a sandbox account for this tutorial at sandbox-login.paddle.com/signup. You can transition to a live account later when you're ready to sell.

Sign up for Vercel and Supabase

  • Vercel hosts and deploys web apps using serverless infrastructure, designed for Next.js.
  • Supabase provides databases, authentication, and other backend features. The starter kit uses Supabase for user management and for syncing customer data with Paddle via webhooks.

You'll also need a Git provider to store your code. Vercel's deploy flow walks you through setting up an account with GitHub (recommended), GitLab, or Bitbucket.

Set up your local environment

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

You don't need a local environment to get a working demo on Vercel — 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 repo, integrate with Supabase, configure Paddle variables, and deploy.
  2. Set up your 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 and take a test payment.
  4. Build your app, then transition to live
    Build on top of the starter kit, then switch to a live account.

Start deploy to Vercel

Deploy the starter kit to Vercel to create a project ready to configure:

Deploy Paddle.js SaaS starter kit to Vercel

Create Git repo

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

Click Continue with GitHub, Continue with GitLab, or Continue with Bitbucket to connect your Git provider to Vercel, then enter a name for your repo.

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

The repo name becomes the name of your project in Vercel and is used for deploy preview URLs. If the name is taken, Vercel appends characters to your project name when creating the 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.

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

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

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

Configure Paddle variables

Supply variables so the app can interact with your Paddle account.

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

VariablePurpose
PADDLE_API_KEYAPI key for backend interaction — syncing customer and subscription data with Supabase.
NEXT_PUBLIC_PADDLE_CLIENT_TOKENClient-side token for frontend interaction — localized prices and opening checkouts.
PADDLE_NOTIFICATION_WEBHOOK_SECRETSecret key for verifying that webhooks came from Paddle and haven't been tampered with.
NEXT_PUBLIC_PADDLE_ENVsandbox 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. Even if you already have them, create new ones for this app.

API keys need permissions to perform actions. For this app, you need Subscription: Write to read and cancel subscriptions, and Transaction: Read to access transactions.

  1. Go to Paddle > Developer tools > Authentication.
  2. Click New API key .
  3. Fill in the details, then select the Subscription: Write permission.
  4. Click Save , then Copy key .
  5. Paste your key as PADDLE_API_KEY on the Vercel deploy screen.
  6. On the authentication screen in Paddle, click the Client-side tokens tab.
  7. Click New client-side token .
  8. Give the token a name and description.
  9. Click Save , then Copy key .
  10. Paste the token as NEXT_PUBLIC_PADDLE_CLIENT_TOKEN.

Illustration of the create API key drawer in Paddle.

Illustration of the copy API key modal.

As you extend your app, your API key may need more permissions. You can edit the API key to add them.

Create a webhook destination

Paddle sends webhooks when something important happens in your account — a customer is updated, a new subscription is created, and so on. The starter kit uses webhooks to keep the app in sync with Paddle.

  1. Go to Paddle > Developer tools > Notifications.
  2. Click New destination .
  3. Give the destination a name.
  4. Keep notification type as webhook (the default).
  5. Enter https://<PROJECTNAME>.vercel.app/api/webhook as the URL, replacing <PROJECTNAME> with your Vercel project name.
  6. Check Select all events.
  7. Click Save destination .
  8. From the destinations list, click next to your destination, then Edit destination .
  9. Copy the secret key and paste it as PADDLE_NOTIFICATION_WEBHOOK_SECRET.

Illustration of the new destination drawer in Paddle.

Illustration of the edit destination drawer with the secret key field highlighted.

See create a notification destination for more.

Set your environment

For NEXT_PUBLIC_PADDLE_ENV:

  • sandbox for a sandbox account.
  • production for a live account.

Review and deploy

Review your settings, then click Deploy. Wait for Vercel to build.

Screenshot of the complete screen for the deploy to Vercel workflow.

Your deploy preview won't work end-to-end yet — the pricing page doesn't display prices and the get-started buttons don't open checkouts. You'll fix these in the next step.

Set up your product catalog

Specify how products in your app map to products in Paddle.

Model your pricing

A product in Paddle has:

  • A product entity describing the item — name, description, image.
  • At least one related price entity describing how much and how often it's billed.

The template's three-tier pricing page has Free, Basic, and Pro, each with monthly and annual options. Mirror this in Paddle as three products with two prices each.

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, then Save .
  4. Under Prices, click New price .
  5. Enter details. Set billing period to Monthly for a monthly price.
  6. Click Save .
  7. Repeat for an Annually price.

Illustration showing the new product drawer in Paddle.

Repeat for each product until you have three products with two prices each.

Update pricing constants

Update the app with your new price IDs. Clone your Git repo locally and open src/constants/pricing-tier.ts — or edit directly on your Git platform.

pricing-tier.ts contains constants used in the pricing page and checkout. Swap each pri_ ID with one of your new price IDs:

TypeScript
export interface Tier {
name: string;
id: 'starter' | 'pro' | 'advanced';
icon: string;
description: string;
features: string[];
featured: boolean;
priceId: Record<string, string>;
}
export const PricingTier: Tier[] = [
{
name: 'Starter',
id: 'starter',
icon: '/assets/icons/price-tiers/free-icon.svg',
description: 'Ideal for individuals who want to get started with simple design tasks.',
features: ['1 workspace', 'Limited collaboration', 'Export to PNG and SVG'],
featured: false,
priceId: { month: 'pri_01hsxyh9txq4rzbrhbyngkhy46', year: 'pri_01hsxyh9txq4rzbrhbyngkhy46' },
},
{
name: 'Pro',
id: 'pro',
icon: '/assets/icons/price-tiers/basic-icon.svg',
description: 'Enhanced design tools for scaling teams who need more flexibility.',
features: ['Integrations', 'Unlimited workspaces', 'Advanced editing tools', 'Everything in Starter'],
featured: true,
priceId: { month: 'pri_01hsxycme6m95sejkz7sbz5e9g', year: 'pri_01hsxyeb2bmrg618bzwcwvdd6q' },
},
{
name: 'Advanced',
id: 'advanced',
icon: '/assets/icons/price-tiers/pro-icon.svg',
description: 'Powerful tools designed for extensive collaboration and customization.',
features: [
'Single sign on (SSO)',
'Advanced version control',
'Assets library',
'Guest accounts',
'Everything in Pro',
],
featured: false,
priceId: { month: 'pri_01hsxyff091kyc9rjzx7zm6yqh', year: 'pri_01hsxyfysbzf90tkh2wqbfxwa5' },
},
];

To get a price ID:

  1. Go to Paddle > Catalog > Products and click a product.
  2. Click next to a price, then Copy price ID .
  3. Paste the ID as priceId.month or priceId.year.

Add all your price IDs, then commit and push to main. Vercel rebuilds automatically.

When the build's done, your pricing page should display prices — but you can't checkout yet. That's the next step.

Add your website to Paddle and test

To keep the Paddle platform safe, you must add your website to Paddle before launching a checkout from it. This protects you as a seller — only you can sell your products.

Get your website approved

Website approval makes sure you own the domains where you use Paddle Checkout and that your products meet Paddle's acceptable use policy.

  1. Go to Paddle > Checkout > Website approval.
  2. Click Add a new domain , enter your Vercel demo app URL, then Submit for Approval .
  3. Wait for approval.

For sandbox, you'll see a green "Approved" status immediately. Live accounts may take a few days while the Paddle verification team reviews your site.

See website verification on the Paddle help center

Your default payment link opens Paddle Checkout for a transaction. It's also used in emails from Paddle that let customers manage their subscription.

  1. Go to Paddle > Checkout > Checkout settings.
  2. Enter your Vercel deploy URL under Default payment link.
  3. Click Save .

Checkout settings screen with the default payment URL field highlighted.

See set your default payment link.

Check your notification destination endpoint

If your project name was taken, Vercel appended characters to your deploy URL. If that URL doesn't match https://<PROJECTNAME>.vercel.app, update the notification destination URL in Paddle. You can find your deploy URL in the Vercel dashboard.

Test

Open your Vercel demo site. Prices should now render on the pricing page.

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

Click Get started to launch a checkout. Use test card details for sandbox:

Email address

An email address you own

Country

Any valid country supported by Paddle

ZIP code (if required)

Any valid ZIP or postal code

Card number

4242 4242 4242 4242

Name on card

Any name

Expiration date

Any valid date in the future.

Security code

100

After checkout, click Sign in. The subscriptions and payments pages pull information from Paddle about the customer's subscriptions and transactions.

Troubleshoot

If prices don't appear, the checkout doesn't load, or you see "Something went wrong," open your browser console for specific error messages from Paddle.js. On macOS Chrome, ⌘ + ⌥ + J opens it.

Check that:

  • You pushed all changes to main and Vercel deployed successfully.
  • Products and prices are created correctly. Prices should be recurring so Paddle creates a subscription when checkout completes.
  • Your pri_ IDs are correct. Sandbox and live IDs don't cross environments.
  • Your default payment link matches the domain you're testing on.
  • Your notification destination URL is https://<YOUR-VERCEL-URL>/api/webhook.
  • NEXT_PUBLIC_PADDLE_CLIENT_TOKEN is a valid token (starts with test_ for sandbox, live_ for live).
  • NEXT_PUBLIC_PADDLE_ENV is sandbox or production to match your account.
  • PADDLE_API_KEY is valid.
  • Supabase tables were created successfully.

Use the Vercel or Supabase docs for platform-specific issues.

Build your app, then go live

You're done. Use this starter kit as a basis for building a SaaS app on Paddle Billing. When you're ready to take real payments:

  1. Sign up for a live account, then follow the go-live checklist.
  2. Update Vercel environment variables for your live account.
  3. Create new schemas in Supabase for live data.
  4. Set up Paddle Retain to recover failed payments.

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. Paddle.js includes a bunch of properties and settings you can pass 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 supports flexible subscription workflows: pause and resume, change billing dates, offer trials, and more.

Integrate with Paddle Retain

Paddle Retain combines subscription expertise with algorithms trained on billions of datapoints to recover failed payments, reduce churn, and proactively upgrade plans.

Was this page helpful?