Documentation
Billing Overview
Learn how to manage subscriptions and billing in your application.
Page type
Product documentation
Best for
Setup, workflow, and implementation details
Next action
Copy, export, or continue deeper into the doc tree
Note: This is mock/placeholder content for demonstration purposes.
The billing system supports subscription-based pricing with multiple tiers and payment providers.
Supported Providers
Stripe
Industry-standard payment processing with comprehensive features:
- Credit card payments
- Subscription management
- Invoice generation
- Tax calculation
- Customer portal
Paddle
Merchant of record solution that handles:
- Global tax compliance
- Payment processing
- Subscription billing
- Revenue recovery
Subscription Tiers
Define your subscription tiers in the billing configuration:
export const plans = [
{
id: 'free',
name: 'Free',
price: 0,
features: ['Feature 1', 'Feature 2'],
},
{
id: 'pro',
name: 'Professional',
price: 29,
interval: 'month',
features: ['All Free features', 'Feature 3', 'Feature 4'],
},
{
id: 'enterprise',
name: 'Enterprise',
price: 99,
interval: 'month',
features: ['All Pro features', 'Feature 5', 'Priority support'],
},
];
Subscription Lifecycle
- Customer selects plan - User chooses subscription tier
- Payment processed - Provider handles payment collection
- Webhook received - Your app receives confirmation
- Subscription activated - User gains access to features
- Recurring billing - Automatic renewal each period
- Cancellation - User can cancel anytime
Managing Subscriptions
Creating a Subscription
import { createCheckoutSession } from '~/lib/billing/checkout';
const session = await createCheckoutSession({
accountId: user.accountId,
planId: 'pro',
returnUrl: '/dashboard',
});
// Redirect user to payment page
redirect(session.url);
Checking Subscription Status
import { getSubscription } from '~/lib/billing/subscription';
const subscription = await getSubscription(accountId);
if (subscription.status === 'active') {
// User has active subscription
}
Canceling a Subscription
import { cancelSubscription } from '~/lib/billing/subscription';
await cancelSubscription(subscriptionId);
Webhook Handling
Webhooks notify your application of billing events:
export async function POST(request: Request) {
const signature = request.headers.get('stripe-signature');
const payload = await request.text();
const event = stripe.webhooks.constructEvent(
payload,
signature,
process.env.STRIPE_WEBHOOK_SECRET
);
switch (event.type) {
case 'customer.subscription.created':
await handleSubscriptionCreated(event.data.object);
break;
case 'customer.subscription.updated':
await handleSubscriptionUpdated(event.data.object);
break;
case 'customer.subscription.deleted':
await handleSubscriptionCanceled(event.data.object);
break;
}
return new Response('OK');
}
Testing
Use test mode credentials for development:
- Test card: 4242 4242 4242 4242
- Any future expiry date
- Any CVC
All test transactions will appear in your provider's test dashboard.
