Comprehensive guide for integrating Dodo Payments - the all-in-one payment and billing platform for SaaS and AI products.
Dodo Payments Integration Guide
Always consult docs.dodopayments.com for the latest API reference and code examples.
Dodo Payments is the all-in-one engine to launch, scale, and monetize worldwide. Designed for SaaS and AI products, it handles payments, billing, subscriptions, and distribution without extra engineering.
Quick Reference
Environment Variables
DODO_PAYMENTS_API_KEY- Your API key from the dashboardDODO_PAYMENTS_WEBHOOK_SECRET- Webhook signing secret for verification
API Environments
- Live Mode:
https://api.dodopayments.com(default) - Test Mode:
https://api.dodopayments.comwithenvironment: 'test_mode'
Dashboard URLs
- Main Dashboard: app.dodopayments.com
- API Keys: Dashboard → Developer → API
- Webhooks: Dashboard → Developer → Webhooks
- Products: Dashboard → Products
SDK Installation
TypeScript/JavaScript
npm install dodopayments
# or
yarn add dodopayments
# or
pnpm add dodopayments
import DodoPayments from 'dodopayments';
const client = new DodoPayments({
bearerToken: process.env.DODO_PAYMENTS_API_KEY,
environment: 'live_mode', // or 'test_mode'
});
Python
pip install dodopayments
from dodopayments import DodoPayments
client = DodoPayments(bearer_token=os.environ["DODO_PAYMENTS_API_KEY"])
Go
go get github.com/dodopayments/dodopayments-go
import "github.com/dodopayments/dodopayments-go"
client := dodopayments.NewClient(
option.WithBearerToken(os.Getenv("DODO_PAYMENTS_API_KEY")),
)
PHP
composer require dodopayments/client
use Dodopayments\Client;
$client = new Client(bearerToken: getenv('DODO_PAYMENTS_API_KEY'));
Core Concepts
Products
Products are the items you sell. Create them in the dashboard or via API:
- One-time: Single purchase products
- Subscription: Recurring billing products
Checkout Sessions
The primary way to collect payments. Create a checkout session and redirect customers:
const session = await client.checkoutSessions.create({
product_cart: [
{ product_id: 'prod_xxxxx', quantity: 1 }
],
customer: {
email: 'customer@example.com',
name: 'John Doe',
},
return_url: 'https://yoursite.com/success',
});
// Redirect customer to: session.checkout_url
Webhooks
Listen to events for real-time updates:
payment.succeeded- Payment completedpayment.failed- Payment failedsubscription.active- Subscription activatedsubscription.cancelled- Subscription cancelledrefund.succeeded- Refund processeddispute.opened- Dispute receivedlicense_key.created- License key generated
Common Integration Patterns
One-Time Payment Flow
- Create product in dashboard
- Create checkout session with product ID
- Redirect customer to checkout URL
- Handle
payment.succeededwebhook - Fulfill order / grant access
// Create checkout for one-time payment
const session = await client.checkoutSessions.create({
product_cart: [{ product_id: 'prod_one_time_product', quantity: 1 }],
customer: { email: 'customer@example.com' },
return_url: 'https://yoursite.com/success',
});
Subscription Flow
- Create subscription product in dashboard
- Create checkout session
- Handle
subscription.activewebhook to grant access - Handle
subscription.cancelledto revoke access
// Create checkout for subscription
const session = await client.checkoutSessions.create({
product_cart: [{ product_id: 'prod_monthly_subscription', quantity: 1 }],
subscription_data: { trial_period_days: 14 }, // Optional trial
customer: { email: 'customer@example.com' },
return_url: 'https://yoursite.com/success',
});
Webhook Verification
Always verify webhook signatures:
import crypto from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string): boolean {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
API Key Management
Generation
- Navigate to Dashboard → Developer → API
- Click "Create API Key"
- Copy and securely store the key
Security Best Practices
- Never expose API keys in client-side code
- Use environment variables
- Rotate keys periodically
- Use test mode keys for development
Customer Portal
Allow customers to manage their subscriptions:
const portal = await client.customers.createPortalSession({
customer_id: 'cust_xxxxx',
return_url: 'https://yoursite.com/account',
});
// Redirect to: portal.url
Error Handling
Handle API errors gracefully:
try {
const session = await client.checkoutSessions.create({...});
} catch (error) {
if (error.status === 400) {
// Invalid request - check parameters
} else if (error.status === 401) {
// Invalid API key
} else if (error.status === 429) {
// Rate limited - implement backoff
}
}
Testing
Test Mode
- Use test API keys (start with
sk_test_) - Test webhooks with dashboard tools
- Use test card numbers:
4242 4242 4242 4242- Success4000 0000 0000 0002- Decline
Local Development
Use ngrok or similar for webhook testing:
ngrok http 3000
Then configure the ngrok URL as your webhook endpoint in the dashboard.
Framework Integration
Next.js
Use API routes for server-side operations:
// app/api/checkout/route.ts
import { NextResponse } from 'next/server';
import DodoPayments from 'dodopayments';
const client = new DodoPayments({
bearerToken: process.env.DODO_PAYMENTS_API_KEY!,
});
export async function POST(req: Request) {
const { productId, email } = await req.json();
const session = await client.checkoutSessions.create({
product_cart: [{ product_id: productId, quantity: 1 }],
customer: { email },
return_url: `${process.env.NEXT_PUBLIC_URL}/success`,
});
return NextResponse.json({ url: session.checkout_url });
}
Express.js
import express from 'express';
import DodoPayments from 'dodopayments';
const app = express();
const client = new DodoPayments({ bearerToken: process.env.DODO_PAYMENTS_API_KEY! });
app.post('/create-checkout', async (req, res) => {
const session = await client.checkoutSessions.create({
product_cart: [{ product_id: req.body.productId, quantity: 1 }],
customer: { email: req.body.email },
return_url: 'https://yoursite.com/success',
});
res.json({ url: session.checkout_url });
});
Resources
You Might Also Like
Related Skills

gog
Google Workspace CLI for Gmail, Calendar, Drive, Contacts, Sheets, and Docs.
openclaw
orpc-contract-first
Guide for implementing oRPC contract-first API patterns in Dify frontend. Triggers when creating new API contracts, adding service endpoints, integrating TanStack Query with typed contracts, or migrating legacy service calls to oRPC. Use for all API layer work in web/contract and web/service directories.
langgenius

