A minimal Nextjs boilerplate for integrating Dodo Payments into your Next.js application.
- Quick Setup - Get started in under 5 minutes
- Payment Integration - Pre-configured checkout flow using
@dodopayments/nextjs - Modern UI - Clean, dark-themed pricing page with Tailwind CSS
- Webhook Handler - Ready-to-use webhook endpoint for payment events
- Customer Portal - One-click subscription management
- TypeScript - Fully typed with minimal, focused types
- Pre-filled Checkout - Demonstrates passing customer data to improve UX
Before you begin, make sure you have:
- Node.js 20.9+ (required for Next.js 16)
- Dodo Payments account (to access API and Webhook Keys from dashboard)
git clone https://github.com/Lupleg/dodo-payment-nextjs.git
cd dodo-payment-nextjsnpm installor use pnpm:
pnpm installSign up at Dodo Payments and get your credentials from the dashboard:
- API Key: Dashboard → Developer → API Keys
- Webhook Key: Dashboard → Developer → Webhooks
Make sure you're in Test Mode while developing!
Create a .env file in the root directory:
cp .env.example .envUpdate the values with your Dodo Payments credentials:
DODO_PAYMENTS_API_KEY=your_api_key_here
DODO_PAYMENTS_WEBHOOK_KEY=your_webhook_signing_key_here
DODO_PAYMENTS_RETURN_URL=http://localhost:3000
DODO_PAYMENTS_ENVIRONMENT=test_modeUpdate src/lib/products.ts with your actual product IDs from Dodo Payments:
export const products: Product[] = [
{
product_id: "pdt_001", // Replace with your product ID
name: "Basic Plan",
description: "Get access to basic features and support",
price: 9999, // in cents
features: [
"Access to basic features",
"Email support",
"1 Team member",
"Basic analytics",
],
},
// ... add more products
];npm run devOpen http://localhost:3000 to see your pricing page!
src/
├── app/
│ ├── api/
│ │ ├── checkout/ # Checkout session handler
│ │ ├── customer-portal/ # Customer portal redirect
│ │ └── webhook/ # Webhook event handler
│ ├── components/
│ │ ├── Footer.tsx # Reusable footer
│ │ ├── Header.tsx # Navigation header
│ │ └── ProductCard.tsx # Product pricing card
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout
│ └── page.tsx # Pricing page (home)
└── lib/
└── products.ts # Product definitions
Edit src/lib/products.ts to modify:
- Product IDs (from your Dodo dashboard)
- Pricing
- Features
- Descriptions
In src/app/components/ProductCard.tsx, replace the hardcoded values with your actual user data:
customer: {
name: "John Doe",
email: "john@example.com",
},In src/app/components/Header.tsx, replace the hardcoded customer ID:
const CUSTOMER_ID = "cus_001"; // Replace with actual customer IDThe boilerplate demonstrates handling two webhook events in src/app/api/webhook/route.ts:
onSubscriptionActive- Triggered when a subscription becomes activeonPaymentSucceeded- Triggered when a payment is successful
Add your business logic inside these handlers:
onSubscriptionActive: async (payload) => {
// Grant access to your product
// Update user database
// Send welcome email
},Add more webhook events as needed.
For local development, you can use tools like ngrok to create a secure tunnel to your local server and use it as your webhook URL. Remember to update your .env file with the correct webhook verification key.
npm run build
npm startDon't forget to add your environment variables in the Vercel dashboard!
After deploying, update your webhook URL in the Dodo Payments Dashboard:
https://example.com/api/webhook
Need help? Reach out: