Skip to content

/template recipe-credit-billing

Commercial License Required

MakerKit requires a commercial license. While Orchestre can help you build with it, you must obtain a valid license from MakerKit for commercial use.

Access: /template recipe-credit-billing or /t recipe-credit-billing

Purpose

Implements a complete credit-based billing system for AI-powered applications, API services, or any usage-based SaaS product. This recipe creates a prepaid credit system where users purchase credits and consume them through usage.

How It Actually Works

The recipe:

  1. Analyzes your current billing setup
  2. Creates credit tracking infrastructure
  3. Implements purchase and consumption flows
  4. Adds credit management UI components
  5. Integrates with Stripe for payments
  6. Sets up usage tracking and analytics

Use Cases

  • AI Applications: Token-based usage for GPT, image generation
  • API Services: Credit consumption per API call
  • Email Services: Credits for email sends
  • SMS Platforms: Message credits
  • Compute Services: Credits for processing time

Examples

Basic Implementation

bash
/template recipe-credit-billing
# Implements a standard credit system with:
# - Credit packages ($10, $50, $100)
# - Simple deduction model
# - Balance tracking
# - Purchase flow

AI Token System

bash
/template recipe-credit-billing ai-tokens gpt-4
# Creates an AI-focused credit system with:
# - Token packages (1K, 10K, 100K tokens)
# - Model-specific pricing
# - Token estimation
# - Usage analytics

API Credit System

bash
/template recipe-credit-billing api-calls tiered
# Implements API credits with:
# - Tiered pricing (bulk discounts)
# - Endpoint-specific costs
# - Rate limiting integration
# - Usage reports

What Gets Created

1. Database Schema

sql
-- Credit balance tracking
CREATE TABLE organization_credits (
  id UUID PRIMARY KEY,
  organization_id UUID REFERENCES organizations(id),
  balance INTEGER NOT NULL DEFAULT 0,
  lifetime_purchased INTEGER DEFAULT 0,
  lifetime_used INTEGER DEFAULT 0,
  low_balance_threshold INTEGER DEFAULT 1000,
  auto_recharge_enabled BOOLEAN DEFAULT false,
  auto_recharge_threshold INTEGER,
  auto_recharge_amount INTEGER
);

-- Credit transactions
CREATE TABLE credit_transactions (
  id UUID PRIMARY KEY,
  organization_id UUID REFERENCES organizations(id),
  amount INTEGER NOT NULL,
  balance_after INTEGER NOT NULL,
  type VARCHAR(50) NOT NULL,
  description TEXT,
  reference_id VARCHAR(255),
  reference_type VARCHAR(50),
  metadata JSONB DEFAULT '{}',
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Credit packages
CREATE TABLE credit_packages (
  id UUID PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  credits INTEGER NOT NULL,
  price_cents INTEGER NOT NULL,
  currency VARCHAR(3) DEFAULT 'USD',
  is_active BOOLEAN DEFAULT true,
  stripe_price_id VARCHAR(255),
  features JSONB DEFAULT '[]'
);

2. API Routes

typescript
// app/api/credits/balance/route.ts
// GET endpoint for current balance

// app/api/credits/purchase/route.ts
// POST endpoint for credit purchases

// app/api/credits/history/route.ts
// GET endpoint for transaction history

// app/api/credits/consume/route.ts
// POST endpoint for credit consumption (internal)

3. Server Actions

typescript
// packages/credits/src/actions.ts
export async function purchaseCredits(packageId: string)
export async function consumeCredits(amount: number, reason: string)
export async function getCreditBalance(organizationId: string)
export async function enableAutoRecharge(threshold: number, amount: number)

4. React Components

tsx
// Credit balance display
<CreditBalance />

// Purchase modal
<PurchaseCreditModal />

// Usage chart
<CreditUsageChart />

// Transaction history
<CreditHistory />

// Low balance alert
<LowBalanceAlert />

5. Hooks

typescript
// packages/credits/src/hooks.ts
export function useCreditBalance()
export function useCreditPackages()
export function useCanAfford(creditCost: number)
export function useCreditHistory(options?: FilterOptions)

Technical Details

Credit Consumption Pattern

typescript
// Middleware for API routes
export async function withCreditCheck(
  handler: NextApiHandler,
  creditCost: number
): NextApiHandler {
  return async (req, res) => {
    const { organizationId } = await getSession(req);
    
    // Check balance
    const balance = await getCreditBalance(organizationId);
    if (balance < creditCost) {
      return res.status(402).json({
        error: 'Insufficient credits',
        required: creditCost,
        balance
      });
    }
    
    // Execute handler
    const result = await handler(req, res);
    
    // Deduct credits if successful
    if (res.statusCode === 200) {
      await consumeCredits(organizationId, creditCost, {
        endpoint: req.url,
        method: req.method
      });
    }
    
    return result;
  };
}

Auto-Recharge Implementation

typescript
// Triggered after credit consumption
async function checkAutoRecharge(organizationId: string) {
  const settings = await getAutoRechargeSettings(organizationId);
  
  if (!settings.enabled) return;
  
  const balance = await getCreditBalance(organizationId);
  
  if (balance < settings.threshold) {
    await purchaseCredits(organizationId, settings.amount, {
      automatic: true,
      trigger: 'low_balance'
    });
  }
}

Stripe Integration

typescript
// Credit package purchase
export async function createCreditPurchaseSession(
  packageId: string,
  organizationId: string
) {
  const package = await getCreditPackage(packageId);
  
  const session = await stripe.checkout.sessions.create({
    mode: 'payment',
    customer: organization.stripeCustomerId,
    line_items: [{
      price: package.stripePriceId,
      quantity: 1
    }],
    metadata: {
      organizationId,
      packageId,
      credits: package.credits
    },
    success_url: `${baseUrl}/settings/billing?credits=purchased`,
    cancel_url: `${baseUrl}/settings/billing?credits=cancelled`
  });
  
  return session;
}

Memory Evolution

The recipe updates CLAUDE.md files:

markdown
## Credit System

The application uses a prepaid credit system for usage-based billing:

- Credits are purchased in packages via Stripe
- Each API call/action consumes credits
- Auto-recharge available for convenience
- Real-time balance tracking
- Detailed usage analytics

### Credit Costs
- GPT-4 API call: 10 credits
- Image generation: 50 credits
- Data export: 100 credits

### Integration Points
- API middleware checks credit balance
- UI shows balance in navigation
- Low balance alerts at 10% remaining
- Usage tracked in credit_transactions table

Workflow Examples

1. Initial Setup

bash
User: Implement credit-based billing for our AI app
Assistant: I'll implement a credit-based billing system. Let me use the recipe:

/template recipe-credit-billing ai-tokens

This will create:
1. Credit tracking infrastructure
2. Token packages for purchase
3. Usage deduction system
4. Balance management UI
5. Stripe integration for payments

2. Adding Custom Package

bash
User: Add an enterprise credit package with 1M tokens
Assistant: I'll add the enterprise package to your credit system:

/template recipe-credit-billing add-package enterprise 1000000 999

This creates a new package with:
- 1 million tokens
- $999 price point
- Bulk discount pricing
- Enterprise features

Best Practices

  1. Set Appropriate Costs: Balance between profitability and usage
  2. Clear Pricing Display: Show credit costs before actions
  3. Grace Period: Allow small negative balance for UX
  4. Usage Estimates: Preview credit consumption
  5. Detailed History: Track all credit movements

Integration Points

  • Billing Dashboard: Shows credit balance and purchase options
  • API Routes: Automatic credit checking middleware
  • User Actions: Credit cost validation before expensive operations
  • Analytics: Track credit usage patterns
  • Webhooks: Stripe payment confirmation

Common Patterns

Freemium Model

typescript
// Give new users free credits
export async function onUserSignup(userId: string) {
  await grantFreeCredits(userId, 1000, 'welcome_bonus');
}

Usage Warnings

typescript
// Warn before expensive operations
if (creditCost > balance * 0.5) {
  showWarning(`This will use ${creditCost} credits (50% of balance)`);
}

Bulk Operations

typescript
// Reserve credits for batch operations
const reserved = await reserveCredits(organizationId, totalCost);
try {
  await performBulkOperation();
  await confirmReservation(reserved.id);
} catch (error) {
  await cancelReservation(reserved.id);
  throw error;
}

Next Steps

  • Configure credit packages and pricing
  • Set up Stripe products
  • Customize UI components
  • Implement usage analytics
  • Add credit cost estimates

Built with ❤️ for the AI Coding community, by Praney Behl