Does NestJS Work With Paddle?

Fully CompatibleLast verified: 2026-02-20

NestJS and Paddle integrate seamlessly for building SaaS backends with subscription billing and tax compliance handled by Paddle.

Quick Facts

Compatibility
full
Setup Difficulty
Easy
Official Integration
No — community maintained
Confidence
high
Minimum Versions
NestJS: 9.0.0

How NestJS Works With Paddle

NestJS works excellently with Paddle's payment infrastructure because Paddle provides REST APIs and webhooks that integrate naturally into NestJS's controller and service architecture. You'll create NestJS controllers to handle Paddle webhook events (subscription created, payment succeeded, etc.), validate signatures using Paddle's API, and manage your subscription state in your database. The framework's dependency injection system makes it trivial to create a Paddle service that wraps their API client, handling authentication and providing reusable methods for creating checkouts, managing subscriptions, and retrieving transaction data.

The typical flow: your NestJS backend creates a Paddle checkout URL via their API, your frontend redirects users to complete payment, then Paddle sends signed webhooks back to your backend confirming the transaction. NestJS's guard system is perfect for verifying webhook signatures before processing events. You'll store subscription metadata (customer ID, plan details, renewal dates) in your own database for application logic, while Paddle remains the source of truth for billing state. This separation of concerns keeps your architecture clean—NestJS handles your domain logic, Paddle handles compliance and payments.

The developer experience is smooth: install the Paddle SDK, create a service wrapper, set up webhook routes, and you're handling production payments with PCI compliance and tax calculations out of the box. No custom tax logic needed, no PCI liability—just business logic.

Best Use Cases

SaaS platform with tiered subscription plans where NestJS manages user accounts and Paddle manages recurring billing and tax
Marketplace or plugin platform where creators need per-transaction payouts, using Paddle's native split payments with NestJS order orchestration
Global B2B software with complex tax requirements, where Paddle handles VAT/GST compliance while NestJS enforces business rules and feature access
Freemium product with upgrade flows, where NestJS controls feature toggles based on subscription status synced from Paddle webhooks

Quick Setup

bash
npm install @paddle/paddle-node-sdk
typescript
import { Injectable } from '@nestjs/common';
import { Client } from '@paddle/paddle-node-sdk';

@Injectable()
export class PaddleService {
  private client: Client;

  constructor() {
    this.client = new Client({
      token: process.env.PADDLE_API_KEY,
      environment: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
    });
  }

  async createCheckout(priceId: string, customerId: string) {
    return this.client.checkouts.create({
      items: [{ priceId }],
      customData: { customerId },
    });
  }

  async getSubscription(subscriptionId: string) {
    return this.client.subscriptions.get(subscriptionId);
  }
}

// In your webhook controller:
@Post('/webhooks/paddle')
async handlePaddleWebhook(@Body() event: any, @Headers() headers: any) {
  const isValid = this.verifySignature(event, headers['x-paddle-signature']);
  if (!isValid) throw new BadRequestException('Invalid signature');
  
  if (event.type === 'subscription.created') {
    await this.handleSubscriptionCreated(event.data);
  }
  return { success: true };
}

Known Issues & Gotchas

critical

Webhook signature verification is mandatory in production but easy to skip during development

Fix: Always verify `X-Paddle-Signature` headers using Paddle's public key. Use environment variables to toggle strict verification in dev. Never process unverified webhooks in production.

warning

Paddle uses webhook event IDs and requires idempotent processing since webhooks can be delivered multiple times

Fix: Store processed webhook IDs in your database and skip events you've already handled. Wrap webhook handlers in try-catch and return 200 OK even if processing fails—Paddle will retry.

warning

API rate limits (100 requests/sec) can be hit during bulk operations or high-concurrency scenarios

Fix: Implement exponential backoff retry logic in your Paddle service. Queue bulk operations asynchronously with BullMQ or similar.

critical

Paddle's test mode and live mode use different API keys and have separate data—easy to accidentally test against production

Fix: Use strict environment configuration validation. Fail fast if PADDLE_API_KEY is undefined. Keep test and prod credentials in separate .env files with CI/CD safeguards.

Alternatives

  • Stripe + NestJS: Industry-standard payment processor with more marketplace features, but less built-in tax/VAT compliance
  • Supabase + Stripe: Serverless alternative with Auth + Database included, but requires managing webhooks across multiple services
  • Lemon Squeezy + Node.js Express: Simpler alternative focused on creators/indie developers, fewer enterprise features than Paddle

Resources

Related Compatibility Guides

Explore more compatibility guides