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.

TPTInvesting

TPT Investing is an educational and research platform operated by Winterhowlers LLC. All content, tools, data, analysis, and research outputs are for informational and educational purposes only. Nothing on this platform constitutes investment advice, financial advice, or professional financial guidance. TPT Investing does not recommend the purchase or sale of any security. Past performance is not indicative of future results. All investing involves risk. AI-generated analysis is provided for research and learning purposes and may not be complete, current, or error-free. Users should independently verify all data and consult a qualified financial advisor before making investment decisions. TPT Investing is not a registered investment advisor, broker-dealer, or fiduciary.

© 2026 Winterhowlers LLC. All rights reserved.