NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Open source

Credits for Laravel

Install
composer require roundly-consulting/credits-for-laravel
Requires: PHP ^8.4 · Laravel ^12.0|^13.0

Overview

Credit and wallet balances for any Eloquent model, kept as an append-only ledger. Every change is its own immutable, time-stamped row — positive to grant, negative to deduct — and the balance is the sum of those rows, so you get the running total, the full history and any past balance without extra work. Named buckets, race-safe overdraft protection, exact fractional display and money-typed currency buckets are built in. MIT-licensed and dependency-light: Laravel plus two small Roundly packages.

What you get

Append-only ledger

Every grant and deduction is its own time-stamped row with a description and metadata. The balance is their sum — never a stored column.

Point-in-time balances

Ask for any balance as it stood at a past moment; the dated ledger reconstructs it exactly, per bucket or in total.

Named buckets

Keep promotional and purchased credit apart on the same owner — isolated balances, with totals across buckets when you want one figure.

Overdraft protection

Deductions below the floor throw by default, and a per-owner lock serialises racing changes on every isolation level — no double spend.

Exact fractional display

Integer minor units with a configurable scale and the native RoundingMode — no float drift, even at PHP_INT_MAX.

Currency-denominated buckets

Map a bucket to an ISO or custom currency and read and write it as Money; the wrong currency is refused before anything is written.

Facade, DI or actions

Credits::for($user) over an injectable CreditsManager and single-purpose actions, a recording fake, CreditsModified events and credits:modify.

Documentation

Installation

Install via Composer, publish and run the publish-only migration, and optionally publish the config and translations.

Configuration

Every config key and its default — model, key types, overdraft policy, default bucket, scale, rounding, currencies and bulk resolvers.

Key types & schema

The credits and credit_locks tables, and how key_type and primary_key_type type the morph column and the ledger’s own id.

Creditable models

Implement Creditable and use HasCredits on any Eloquent model — users, teams, accounts — to give it a ledger and a balance.

The Credits facade

Credits::for($owner) — an immutable scope to add, deduct, set and read credits per bucket, as integers or Money, plus owner-free helpers.

DI and actions

Inject CreditsManager instead of the facade, or call the single-purpose actions from jobs and services — modify, set, balance, total, format.

Granting & deducting

Append grants and deductions with modifyCredits(), attach a description and metadata, and set an exact balance with setCreditsTo().

Overdraft protection

Deductions below the floor throw InsufficientCreditsException by default; allow overdrafts per call or globally, and race-safely.

Reading balances

Read the current or a past balance, check available credits with hasCredits(), and query the ledger relation directly.

Named buckets

Split credit into isolated named pools on one owner, and sum chosen buckets or every bucket when you need a single figure.

Fractional credits & display

Store fractional credits as integer minor units with a scale, and render them as exact, locale-free decimal strings.

Currency-denominated buckets

Map a bucket to an ISO or custom money currency to read its balance as Money and refuse writes in any other currency.

Custom currencies & redemption

Denominate buckets in your own units such as loyalty points, respect the 64-bit precision limit, and redeem points for money.

Query scopes

Report over the ledger with the Credit model’s scopes — grants, deductions, point in time, owner and bucket filters.

Events

React to every recorded change with the CreditsModified event — the owner, the new ledger row and the bucket’s new balance.

Custom model & translations

Swap in your own Credit subclass through credits.model, and publish the exception messages to translate or reword them.

Artisan commands

Apply a credit change in bulk with credits:modify, and inspect the resolved configuration with php artisan about.

Exceptions

The credits exceptions and the money-for-laravel exceptions the package lets through — what throws them and what they carry.

Testing

Credits::fake() records every add, deduct and set without writing; or test balances, the guard and events against a real database.

Requirements

PHP 8.4+ with ext-bcmath, Laravel 12 or 13, and two Roundly packages that Composer installs for you.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.