General

Billing

Manage subscriptions, one-time payments and credit-based billing for AI features.

The Pro Next.js Prisma starter kit provides a comprehensive billing system integrated with Stripe. It supports traditional subscriptions and a flexible credit system for AI-driven features.

Configuration

Billing plans are configured in config/billing.config.ts. Credit packages are configured separately in the same file.

config/billing.config.ts
export const billingConfig = {
  enabled: true,
  defaultCurrency: 'usd',
  plans: {
    free: {
      id: 'free',
      name: 'Free',
      isFree: true,
      features: ['Basic features']
    },
    pro: {
      id: 'pro',
      name: 'Pro',
      description: 'For professional developers',
      prices: [
        {
          id: 'pro_monthly',
          stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY ?? '',
          type: 'recurring',
          interval: 'month',
          amount: 2900, // $29.00 in cents
          currency: 'usd'
        }
      ],
      features: ['Advanced AI', 'Priority Support']
    }
  }
} satisfies BillingConfig;

// Credit packages are exported separately
export const creditPackages = [
  {
    id: 'basic',
    name: 'Basic Credits',
    credits: 1000,
    priceAmount: 1000, // $10.00 in cents
    stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_CREDITS_BASIC ?? ''
  }
] as const;

Subscriptions

Subscriptions are managed per organization. The kit handles checkout sessions, customer portals and webhooks automatically.

Checking Subscription Status

You can check if an organization has an active subscription using tRPC queries:

trpc/routers/organization/organization-router.ts
import { createTRPCRouter, protectedOrganizationProcedure } from '@/trpc/init';

import { getActiveSubscriptionByOrganizationId } from '@/lib/billing';

export const organizationRouter = createTRPCRouter({
  getSettings: protectedOrganizationProcedure.query(async ({ ctx }) => {
    const subscription = await getActiveSubscriptionByOrganizationId(
      ctx.organization.id
    );
    const isSubscribed =
      !!subscription &&
      (subscription.status === 'active' || subscription.status === 'trialing');
    return { isSubscribed };
  })
});

Credit System

The Pro kit includes a robust credit system for usage-based billing, typically used for AI features.

Consuming Credits

Use the consumeCredits helper to deduct credits from an organization's balance.

lib/actions/ai.ts
import { consumeCredits } from '@/lib/billing/credits';

await consumeCredits({
  organizationId: ctx.organization.id,
  amount: 50,
  description: 'AI Image Generation',
  referenceType: 'ai_image',
  referenceId: imageId
});

Checking Balance

trpc/routers/organization/organization-credit-router.ts
import { getCreditBalance } from '@/lib/billing/credits';

// In a procedure:
const { balance } = await getCreditBalance(organizationId);

Webhooks

Stripe webhooks are handled in app/api/webhooks/stripe/route.ts. They keep the local database in sync with Stripe events (e.g., successful payments, subscription cancellations).

Local Webhook Testing

To test webhooks locally, use the Stripe CLI:

Terminal
npm run stripe:listen

UI Components

The kit includes pre-built UI components for:

  • Pricing Tables: Display plans and packages.
  • Billing Settings: Manage subscriptions and view payment history.
  • Credit Dashboard: View current balance and recent transactions.