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