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

Named buckets

Credits can be split into independent, named pools on the same entity — for example promotional and purchased credit that should never be spent against each other. On the facade, bucket() narrows the scope; buckets([...]) sums several for reading:

$promo = Credits::for($user)->bucket('promotional');   // an immutable scope — keep and reuse it
$promo->add(100, 'welcome promo');
$promo->balance();                                     // 100

Credits::for($user)->bucket('purchased')->add(50, 'top-up');

Credits::for($user)->buckets(['promotional', 'purchased'])->balance(); // 150 — summed, read-only
Credits::for($user)->total();                                          // every bucket

Every trait method accepts the same optional bucket argument:

$user->modifyCredits(100, 'welcome promo', bucket: 'promotional');
$user->modifyCredits(50, 'top-up', bucket: 'purchased');

$user->creditsBalance(bucket: 'promotional'); // 100
$user->creditsBalance(bucket: 'purchased');   // 50

Balances are fully isolated per bucket, and the overdraft guard is enforced per bucket — a deduction against purchased cannot draw on promotional credit.

The default bucket

When you omit the bucket, the configured default_bucket ('default') is used for both reads and writes. A bucket-less balance query therefore returns the default bucket only — it does not sum across every bucket:

$user->modifyCredits(25);                         // lands in the 'default' bucket
$user->creditsBalance();                          // 25  (the default bucket only)
$user->creditsBalance(bucket: 'promotional');     // 100

Single-pool usage needs no changes: every call without a bucket operates on one pool. setCreditsTo() and hasCredits() take the same bucket argument, and credits:modify has a --bucket= option.

Totals across buckets

When you do want a combined figure, sum a chosen set of buckets or every bucket the entity owns:

// Sum a chosen set of buckets (names are de-duplicated; an empty list returns 0).
$user->creditsBalanceForBuckets(['promotional', 'purchased']); // 150

// Sum every bucket on the entity.
$user->totalCreditsBalance(); // 175

// Both accept an optional point-in-time argument.
$user->totalCreditsBalance(now()->subWeek());
$user->creditsBalanceForBuckets(['promotional', 'purchased'], now()->subWeek());

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.