Implementing Credit-Based Billing Systems in Laravel

Overview

Modern SaaS pricing has shifted from feature-gating to consumption-based models. This approach, popular in AI-driven tools, allows users to pay for specific usage—like tokens or

—on top of a recurring fee. Implementing this in
Laravel
involves synchronizing local database records with
Stripe
subscription cycles to ensure users never exceed their allocated limits.

Implementing Credit-Based Billing Systems in Laravel
Laravel SaaS with Credits/Tokens Pricing: Demo Project

Prerequisites

To follow this guide, you should be comfortable with

10+,
PHP
8.1+ features like Enums, and have a basic understanding of
Stripe
integration using
Laravel Cashier
.

Key Libraries & Tools

  • Laravel Cashier
    : Manages subscriptions and webhooks.
  • Stripe
    : Handles the actual payment processing.
  • Prism: A package used here to interact with the
    Anthropic
    AI provider.
  • PHP
    : Used to define static plan limits and pricing.

Code Walkthrough

1. Database Schema

Add fields to your users table to track the current balance and reset dates.

Schema::table('users', function (Blueprint $table) {
    $table->integer('credits_remaining')->default(100);
    $table->integer('credits_limit')->default(100);
    $table->timestamp('credits_reset_at')->nullable();
});

2. Credit Middleware

Validate that a user has enough credits before they hit expensive API endpoints.

public function handle(Request $request, Closure $next)
{
    if ($request->user()->credits_remaining < 1) {
        return back()->with('error', 'Insufficient credits.');
    }
    return $next($request);
}

3. Deduction Logic

Wrap the deduction in a service to keep your controllers clean and ensure transactions are logged.

public function deduct(User $user, int $amount)
{
    $user->decrement('credits_remaining', $amount);
    $user->creditTransactions()->create([
        'amount' => $amount,
        'type' => 'usage'
    ]);
}

Syntax Notes

This implementation uses PHP Enums to store plan details, making it easy to call $plan->creditLimit() anywhere in the app. It also relies on Laravel Artisan Commands to automate monthly resets by comparing the credits_reset_at timestamp with the current date.

Practical Examples

This system is ideal for AI Content Generators where each API call to models like

costs money. It also works for Email Marketing Tools that charge per 1,000 sent emails or Image Processing SaaS where high-resolution exports consume "points."

Tips & Gotchas

Avoid over-reliance on third-party wallet packages for simple credit needs; they can create dependency hell during

upgrades. Always use Stripe Webhooks (specifically invoice.payment_succeeded) to trigger credit resets, ensuring users only get their new balance once payment clears.

3 min read