--- name: credits-handler description: Manage the credit system (allocation, purchasing, usage). Use when adding credit types, configuring pricing, or building credit UI. --- # Credits Handler This skill guides you through the entire credit system, from backend configuration to frontend UI implementation. ## 1. Configuration All credit configuration lives in `src/lib/credits/config.ts`. ### Adding a New Credit Type 1. **Define the Type**: Add the new type to `creditTypeSchema` enum. ```typescript export const creditTypeSchema = z.enum([ "image_generation", "video_generation", "your_new_credit_type" // Add this ]); ``` 2. **Configure Pricing & Metadata**: Add an entry to `creditsConfig`. ```typescript your_new_credit_type: { name: "New Credit Name", currency: "USD", minimumAmount: 10, // Option A: Fixed Slabs slabs: [ { from: 1, to: 100, pricePerUnit: 0.10 }, { from: 101, to: 1000, pricePerUnit: 0.08 }, ], // Option B: Dynamic Calculator (e.g., based on user plan) priceCalculator: (amount, userPlan) => { // Logic here return amount * 0.1; } } ``` 3. **Plan Allocations (Optional)**: Define how many credits are given when subscribing to a plan in `onPlanChangeCredits`. ## 2. UI Implementation: Buying Credits To let users purchase credits, use the `useBuyCredits` hook. This hook handles price calculation (factoring in plan discounts) and generating checkout URLs. ### Key Hook: `useBuyCredits` **Location**: `src/lib/credits/useBuyCredits.ts` #### Usage ```typescript import useBuyCredits from "@/lib/credits/useBuyCredits"; import { PlanProvider } from "@/lib/plans/getSubscribeUrl"; const { price, // Calculated total price (number | undefined) isLoading, // Price calculation in progress error, // Error state getBuyCreditsUrl // Function to generate payment URL } = useBuyCredits(creditType, amount); ``` ### Example: Building a Pricing Card Here is a pattern for creating a credit purchase UI, similar to `src/components/website/website-credits-section.tsx`. ```tsx "use client"; import { useState } from "react"; import useBuyCredits from "@/lib/credits/useBuyCredits"; import { PlanProvider } from "@/lib/plans/getSubscribeUrl"; import { Button } from "@/components/ui/button"; import { Loader2 } from "lucide-react"; // 1. Define your packages const PACKAGE = { credits: 100, name: "Starter Pack", }; export function BuyCreditsCard({ creditType }: { creditType: "image_generation" }) { const [provider] = useState(PlanProvider.STRIPE); // or LEMONSQUEEZY // 2. Call the hook const { price, isLoading, error, getBuyCreditsUrl } = useBuyCredits( creditType, PACKAGE.credits ); // 3. Handle Purchase const handleBuy = () => { const url = getBuyCreditsUrl(provider); window.location.href = url; }; // 4. Render UI return (
{error.message}
}