• Blog
  • Documentation
  • Courses
  • Changelog
  • AI Starters
  • UI Kit
  • FAQ
  • Supamode
    New
  • Pricing

Launch your next SaaS in record time with Makerkit, a React SaaS Boilerplate for Next.js and Supabase.

Makerkit is a product of Makerkit Pte Ltd (registered in the Republic of Singapore)Company Registration No: 202407149CFor support or inquiries, please contact us

About
  • FAQ
  • Contact
  • Verify your Discord
  • Consultation
  • Open Source
  • Become an Affiliate
Product
  • Documentation
  • Blog
  • Changelog
  • UI Blocks
  • Figma UI Kit
  • AI SaaS Starters
License
  • Activate License
  • Upgrade License
  • Invite Member
Legal
  • Terms of License
    • How Billing Works
    • Billing Schema
    • Stripe
    • Lemon Squeezy
    • Paddle
    • Metered Usage
    • Per Seat Billing
    • Credits Based Billing
    • One Off Payments
    • Handling Webhooks
    • Billing API
    • Custom Integration

Configuring Paddle Billing | Next.js Supabase SaaS Kit Turbo

Complete guide to integrating Paddle billing with your Next.js Supabase SaaS application. Learn how to set up payment processing, webhooks, and subscription management with Paddle as your Merchant of Record.

Paddle is a comprehensive billing solution that acts as a Merchant of Record (MoR), handling all payment processing, tax calculations, compliance, and regulatory requirements for your SaaS business.

This integration eliminates the complexity of managing global tax compliance, PCI requirements, and payment processing infrastructure.

Overview

This guide will walk you through:

  • Setting up Paddle for development and production
  • Configuring webhooks for real-time billing events
  • Creating and managing subscription products
  • Testing the complete billing flow
  • Deploying to production

Prerequisites

Before starting, ensure you have:

  • A Paddle account (sandbox for development, live for production)
  • Access to your application's environment configuration
  • A method to expose your local development server (ngrok, LocalTunnel, Localcan, etc.)

Step 0: Fetch the Paddle package from the plugins repository

The Paddle package is released as a plugin in the Plugins repository. You can fetch it by running the following command:

npx @makerkit/cli@latest plugins install

Please choose the Paddle plugin from the list of available plugins.

Step 1: Registering Paddle

Now we need to register the services from the Paddle plugin.

Install the Paddle package

Run the following command to add the Paddle package to our billing package:

pnpm --filter "@kit/billing-gateway" add "@kit/paddle"

Registering the Checkout component

Update the function loadCheckoutComponent to include the paddle block, which will dynamically import the Paddle checkout component:

packages/billing/gateway/src/components/embedded-checkout.tsx

function loadCheckoutComponent(provider: BillingProvider) {
switch (provider) {
case 'stripe': {
return buildLazyComponent(() => {
return import('@kit/stripe/components').then(({ StripeCheckout }) => {
return {
default: StripeCheckout,
};
});
});
}
case 'lemon-squeezy': {
return buildLazyComponent(() => {
return import('@kit/lemon-squeezy/components').then(
({ LemonSqueezyEmbeddedCheckout }) => {
return {
default: LemonSqueezyEmbeddedCheckout,
};
},
);
});
}
case 'paddle': {
return buildLazyComponent(() => {
return import('@kit/paddle/components').then(
({ PaddleCheckout }) => {
return {
default: PaddleCheckout,
};
},
);
});
}
default:
throw new Error(`Unsupported provider: ${provider as string}`);
}
}

Registering the Webhook handler

At packages/billing/gateway/src/server/services/billing-event-handler /billing-event-handler-factory.service.ts, add the snippet below at the bottom of the file:

packages/billing/gateway/src/server/services/billing-event-handler/billing-event-handler-factory.service.ts

// Register Paddle webhook handler
billingWebhookHandlerRegistry.register('paddle', async () => {
const { PaddleWebhookHandlerService } = await import('@kit/paddle');
return new PaddleWebhookHandlerService(planTypesMap);
});

Registering the Billing service

Finally, at packages/billing/gateway/src/server/services/billing-event-handler /billing-gateway-registry.ts, add the snippet below at the bottom of the file:

packages/billing/gateway/src/server/services/billing-gateway/billing-gateway-registry.ts

// Register Paddle billing strategy
billingStrategyRegistry.register('paddle', async () => {
const { PaddleBillingStrategyService } = await import('@kit/paddle');
return new PaddleBillingStrategyService();
});

Step 2: Create Paddle Account

Development Account (Sandbox)

  1. Visit Paddle Developer Console
  2. Complete the registration process
  3. Verify your email address
  4. Navigate to your sandbox dashboard

Important Notes

  • The sandbox environment allows unlimited testing without processing real payments
  • All transactions in sandbox mode use test card numbers
  • Webhooks and API calls work identically to production
  • The Paddle payment provider currently only supports flat and per-seat plans (metered subscriptions are not supported)

Step 3: Configure Billing Provider

Database Configuration

Set Paddle as your billing provider in the database:

-- Update the billing provider in your configuration table
UPDATE public.config
set billing_provider = 'paddle';

Environment Configuration

Add the following to your .env.local file:

# Set Paddle as the active billing provider
NEXT_PUBLIC_BILLING_PROVIDER=paddle

This environment variable tells your application to use Paddle-specific components and API endpoints for billing operations.

Step 4: API Key Configuration

Paddle requires two types of API keys for complete integration:

Server-Side API Key (Required)

  1. In your Paddle dashboard, navigate to Developer Tools → Authentication
  2. Click Generate New API Key
  3. Give it a descriptive name (e.g., "Production API Key" or "Development API Key")
  4. Configure the required permissions for your API key:
    • Write Customer Portal Sessions - For managing customer billing portals
    • Read Customers - For retrieving customer information
    • Read Prices - For displaying pricing information
    • Read Products - For product catalog access
    • Read/Write Subscriptions - For subscription management
    • Read Transactions - For payment and transaction tracking
  5. Copy the generated key immediately (it won't be shown again)
  6. Add to your .env.local:
PADDLE_API_KEY=your_server_api_key_here

Security Note: This key has access to the specified Paddle account permissions and should never be exposed to the client-side code. Only grant the minimum permissions required for your integration.

Client-Side Token (Required)

  1. In the same Authentication section, look for Client-side tokens
  2. Click Generate New Token
  3. Configure the allowed domains (for development, add https://localhost:3000)
  4. Copy the client token
  5. Add to your .env.local:
NEXT_PUBLIC_PADDLE_CLIENT_TOKEN=your_client_token_here

Important: This token is safe to expose in client-side code but should be restricted to your specific domains.

Step 5: Webhook Configuration

Webhooks enable real-time synchronization between Paddle and your application for events like successful payments, subscription changes, and cancellations.

Set Up Local Development Tunnel

First, expose your local development server to the internet:

Using ngrok (Recommended)

# Install ngrok if not already installed
npm install -g ngrok
# Expose port 3000 (default Next.js port)
ngrok http 3000

Using LocalTunnel

# Install localtunnel
npm install -g localtunnel
# Expose port 3000
lt --port 3000

Configure Webhook Destination

  1. In Paddle dashboard, go to Developer Tools → Notifications
  2. Click New Destination
  3. Configure the destination:
    • Destination URL: https://your-tunnel-url.ngrok.io/api/billing/webhook
    • Description: "Local Development Webhook"
    • Active: ✅ Checked

Select Webhook Events

Enable these essential events for proper billing integration:

Retrieve Webhook Secret

  1. After creating the destination, click on it to view details
  2. Copy the Endpoint Secret (used to verify webhook authenticity)
  3. Add to your .env.local:
PADDLE_WEBHOOK_SECRET_KEY=your_webhook_secret_here

Test Webhook Connection

You can test the webhook endpoint by making a GET request to verify it's accessible:

curl https://your-tunnel-url.ngrok.io/api/billing/webhook

Expected response: 200 OK with a message indicating the webhook endpoint is active.

Step 6: Product and Pricing Configuration

Create Products in Paddle

  1. Navigate to Catalog → Products in your Paddle dashboard
  2. Click Create Product
  3. Configure your product:

Basic Information:

  • Product Name: "Starter Plan", "Pro Plan", etc.
  • Description: Detailed description of the plan features
  • Tax Category: Select appropriate category (usually "Software")

Pricing Configuration:

  • Billing Interval: Monthly, Yearly, or Custom
  • Price: Set in your primary currency
  • Trial Period: Optional free trial duration

Configure Billing Settings

Update your billing configuration file with the Paddle product IDs:

// apps/web/config/billing.config.ts
export const billingConfig = {
provider: 'paddle',
products: [
{
id: 'starter',
name: 'Starter Plan',
description: 'Perfect for individuals and small teams',
badge: 'Most Popular',
features: [
'Up to 5 projects',
'Basic support',
'1GB storage'
],
plans: [
{
id: 'pri_starter_monthly_001', // Paddle Price ID
paymentType: 'recurring',
interval: 'month',
intervalCount: 1,
price: 900, // Price in cents
currency: 'USD'
}
]
}
// Add more products...
]
};

Step 7: Checkout Configuration

Default Payment Link Configuration

  1. Go to Checkout → Checkout Settings in Paddle dashboard
  2. Configure Default Payment Link:
    • Success URL: http://localhost:3000/home/billing/success
    • Cancel URL: http://localhost:3000/home/billing/cancel
  3. Save the configuration

Step 8: Testing the Integration

Development Testing Checklist

Environment Verification:

  • [ ] All environment variables are set correctly
  • [ ] Webhook tunnel is active and accessible
  • [ ] Destination was defined using the correct URL
  • [ ] Database billing provider is set to 'paddle' in both DB and ENV

Subscription Flow Testing:

  1. Navigate to your billing/pricing page (/home/billing or equivalent)
  2. Click on a subscription plan
  3. Complete the checkout flow using Paddle test cards
  4. Verify successful redirect to success page
  5. Check that subscription appears in user dashboard
  6. Verify webhook events are received in your application logs

You can also test cancellation flows:

  • cancel the subscription from the billing portal
  • delete the account and verify the subscription is cancelled as well

Test Card Numbers

Follow this link to get the test card numbers

Webhook Testing

Monitor webhook delivery in your application logs:

# Watch your development logs
pnpm dev
# In another terminal, monitor webhook requests
tail -f logs/webhook.log

Step 9 (Optional)

If you are using Per Seat pricing plans, you should intoroduce an Invitation Feature Policy in order to block invitations being sent while in a trial. This is because Paddle doesn't support updating the quantity of a subscription during a trial period.

NB: this requires version 2.16.0, which introduced Feature Policies.

Please update the packages/features/team-accounts/src/server/policies/policies.ts file to include the following policy:

packages/features/team-accounts/src/server/policies/policies.ts

invitationPolicyRegistry.registerPolicy(paddleBillingInvitationsPolicy);

Step 10: Production Deployment

Apply for Live Paddle Account

  1. In your Paddle dashboard, click Go Live
  2. Complete the application process:
    • Business information and verification
    • Tax information and documentation
    • Banking details for payouts
    • Identity verification for key personnel

Timeline: Live account approval typically takes 1-3 business days.

Production Environment Setup

Create production-specific configuration:

# Production environment variables
NEXT_PUBLIC_BILLING_PROVIDER=paddle
PADDLE_API_KEY=your_production_api_key
NEXT_PUBLIC_PADDLE_CLIENT_TOKEN=your_production_client_token
PADDLE_WEBHOOK_SECRET_KEY=your_production_webhook_secret

Production Webhook Configuration

  1. Create a new webhook destination for production
  2. Set the destination URL to your production domain:
    https://yourdomain.com/api/billing/webhook
  3. Enable the same events as configured for development
  4. Update your production environment with the new webhook secret

Production Products and Pricing

  1. Create production versions of your products in the live environment
  2. Update your production billing configuration with live Price IDs
  3. Test the complete flow on production with small-amount transactions

Support Resources

Refer to the Paddle Documentation for more information:

  • Paddle Documentation: https://developer.paddle.com
  • Status Page: https://status.paddle.com
On this page
  1. Overview
    1. Prerequisites
      1. Step 0: Fetch the Paddle package from the plugins repository
        1. Step 1: Registering Paddle
          1. Install the Paddle package
          2. Registering the Checkout component
          3. Registering the Webhook handler
          4. Registering the Billing service
        2. Step 2: Create Paddle Account
          1. Development Account (Sandbox)
          2. Important Notes
        3. Step 3: Configure Billing Provider
          1. Database Configuration
          2. Environment Configuration
        4. Step 4: API Key Configuration
          1. Server-Side API Key (Required)
          2. Client-Side Token (Required)
        5. Step 5: Webhook Configuration
          1. Set Up Local Development Tunnel
          2. Configure Webhook Destination
          3. Select Webhook Events
          4. Retrieve Webhook Secret
          5. Test Webhook Connection
        6. Step 6: Product and Pricing Configuration
          1. Create Products in Paddle
          2. Configure Billing Settings
        7. Step 7: Checkout Configuration
          1. Default Payment Link Configuration
        8. Step 8: Testing the Integration
          1. Development Testing Checklist
          2. Test Card Numbers
          3. Webhook Testing
        9. Step 9 (Optional)
          1. Step 10: Production Deployment
            1. Apply for Live Paddle Account
            2. Production Environment Setup
            3. Production Webhook Configuration
            4. Production Products and Pricing
            5. Support Resources