General
Billing

Credits

Learn how to implement and manage a credit-based billing system.

The Pro Next.js Prisma starter kit includes a robust credit system for usage-based billing, typically used for AI features and pay-as-you-go services.

Overview

Credits allow you to charge users based on their actual usage rather than fixed subscription tiers. This is ideal for:

  • AI-powered features (image generation, text analysis, etc.)
  • API calls and compute resources
  • Pay-as-you-go services

Configuration

Credit packages are configured separately in config/billing.config.ts:

config/billing.config.ts
import { env } from '@/lib/env';

// Credit packages are exported separately from billingConfig
export const creditPackages = [
  {
    id: 'credits_starter',
    name: 'Starter',
    credits: 10_000,
    priceAmount: 999, // $9.99 in cents
    stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_CREDITS_STARTER ?? ''
  },
  {
    id: 'credits_basic',
    name: 'Basic',
    credits: 50_000,
    bonusCredits: 5_000, // 10% bonus
    priceAmount: 3999, // $39.99 in cents
    stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_CREDITS_BASIC ?? ''
  }
] as const;

Consuming Credits

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

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

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

The consumeCredits function will:

  • Check if the organization has sufficient credits
  • Deduct the specified amount
  • Create a transaction record
  • Throw an error if insufficient credits

Checking Credit Balance

Get the current credit balance for an organization:

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

import { getCreditBalance } from '@/lib/billing/credits';

export const organizationCreditRouter = createTRPCRouter({
  getBalance: protectedOrganizationProcedure.query(async ({ ctx }) => {
    const { balance } = await getCreditBalance(ctx.organization.id);
    return { balance };
  })
});

Adding Credits

Credits are automatically added when a user purchases a credit package. This is handled automatically via Stripe webhooks in lib/billing/sync.ts. The webhook handler processes checkout.session.completed events and adds credits based on the purchased package.

Credit Transactions

All credit operations are tracked in the database, allowing you to:

  • View transaction history
  • Audit credit usage
  • Generate reports
trpc/routers/organization/organization-credit-router.ts
import { createTRPCRouter, protectedOrganizationProcedure } from '@/trpc/init';

import { listCreditTransactions } from '@/lib/billing/credits';

export const organizationCreditRouter = createTRPCRouter({
  getTransactions: protectedOrganizationProcedure.query(async ({ ctx }) => {
    return await listCreditTransactions(ctx.organization.id, {
      limit: 50,
      offset: 0
    });
  })
});

UI Components

The kit includes pre-built UI components for:

  • Credit Balance Display: Show current balance
  • Credit Purchase: Purchase credit packages
  • Transaction History: View credit transactions
  • Low Balance Warnings: Alert users when credits are running low