Billing Overview

Learn how to manage subscriptions and billing in your application.

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

  1. Customer selects plan - User chooses subscription tier
  2. Payment processed - Provider handles payment collection
  3. Webhook received - Your app receives confirmation
  4. Subscription activated - User gains access to features
  5. Recurring billing - Automatic renewal each period
  6. 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.