Subscriptions
Start earning recurring revenue with subscriptions - monthly, yearly, and trial periods out of the box.
Subscriptions
Start earning recurring revenue with subscriptions! Support monthly, yearly, and trial periods out of the box.
Prerequisites
Set up Dodo, Stripe, or LemonSqueezy, then create subscription plans in super admin.
Video Walkthrough
Setup Your Plans
Step 1: Create Subscription Plans
Navigate to /super-admin/plans and configure:
- Enable subscription types - Monthly, yearly, or both
- Set prices - Amount in cents (2900 = $29/month)
- Add price/product IDs - From your payment provider (Dodo, Stripe, etc.)
- Configure features - What subscribers get
- Set quotas - Usage limits per plan
Offer Both Options
Enable both monthly and yearly pricing! Offer 15-20% discount on yearly plans to incentivize annual subscriptions.
Step 2: Generate Subscription Links
Use the getSubscribeUrl helper:
import getSubscribeUrl, { PlanType, PlanProvider } from '@/lib/plans/getSubscribeUrl'
// Monthly subscription (Dodo)
const monthlyUrl = getSubscribeUrl({
codename: "pro",
type: PlanType.MONTHLY,
provider: PlanProvider.DODO,
})
// Yearly subscription with discount
const yearlyUrl = getSubscribeUrl({
codename: "pro",
type: PlanType.YEARLY,
provider: PlanProvider.DODO,
})
// With free trial
const trialUrl = getSubscribeUrl({
codename: "pro",
type: PlanType.MONTHLY,
provider: PlanProvider.DODO,
trialPeriodDays: 14, // 14-day free trial
})Parameters:
codename- Plan identifier from your databasetype-PlanType.MONTHLY,PlanType.YEARLY, orPlanType.ONETIMEprovider-PlanProvider.DODO, STRIPE, LEMON_SQUEEZY, or PAYPALtrialPeriodDays- Optional free trial (7 or 14 days)
Free Trials Convert Better
Adding a 7-14 day trial can increase conversions by 20-30%! Let users experience value before paying.
Complete Pricing Page Example
Build a pricing page with billing toggle:
'use client'
import { useState } from 'react'
import Link from 'next/link'
import { Button } from '@/components/ui/button'
import { Check } from 'lucide-react'
import getSubscribeUrl, { PlanType, PlanProvider } from '@/lib/plans/getSubscribeUrl'
function PricingPage({ plans }) {
const [billingPeriod, setBillingPeriod] = useState<'monthly' | 'yearly'>('monthly')
return (
<div>
<div className="flex items-center justify-center gap-4 mb-8">
<button onClick={() => setBillingPeriod('monthly')}>Monthly</button>
<button onClick={() => setBillingPeriod('yearly')}>
Yearly <span className="badge">Save 20%</span>
</button>
</div>
<div className="grid md:grid-cols-3 gap-6">
{plans.map(plan => (
<PricingCard key={plan.id} plan={plan} billingPeriod={billingPeriod} />
))}
</div>
</div>
)
}
function PricingCard({ plan, billingPeriod }) {
const isMonthly = billingPeriod === 'monthly'
const price = isMonthly ? plan.monthlyPrice : plan.yearlyPrice
const priceDisplay = (price || 0) / 100
const period = isMonthly ? 'month' : 'year'
return (
<div className="p-6 border rounded-lg">
<h3 className="text-2xl font-bold mb-2">{plan.name}</h3>
<div className="mb-6">
<span className="text-4xl font-bold">${priceDisplay}</span>
<span className="text-muted-foreground">/{period}</span>
</div>
<Link href={getSubscribeUrl({
codename: plan.codename,
type: isMonthly ? PlanType.MONTHLY : PlanType.YEARLY,
provider: PlanProvider.DODO,
trialPeriodDays: 14,
})}>
<Button className="w-full" size="lg">Start 14-Day Free Trial</Button>
</Link>
</div>
)
}Subscription Lifecycle
- Payment processed - User charged (or after trial)
- Webhook received - Your app gets notified
- Plan assigned - User gets access
- Recurring billing - Auto-charged monthly/yearly
- Access managed - Features gated by subscription status
Testing
- Use test keys in development (e.g. Dodo test mode)
- Test: new subscription, trial expiry, renewal, cancellation
- Verify webhooks work before going live
Troubleshooting
Subscription not activating? Check webhook, verify price/product IDs match, review logs.
User not seeing features? Check plan assignment, subscription status, webhook processing.
Related
- Plan-Based Rendering - Gate features by plan
- Dodo Setup - Configure Dodo Payments