A ledger-based Laravel package for managing credit-based systems in your application. Perfect for virtual currencies, reward points, or any credit-based feature.
- π Credit transactions
- πΈ Credit transfers
- π’ Events for adding, deducting, and transferring credits
- π° Balance tracking with running balance
- π Transaction history
- π Point-in-time balance lookup
- π Transaction metadata support
- β‘ Efficient queries using running balance and indexes
You can install the package via composer:
composer require climactic/laravel-creditsPublish and run the migrations:
php artisan vendor:publish --tag="credits-migrations"
php artisan migrateOptionally publish the config file:
php artisan vendor:publish --tag="credits-config"return [
// Allow negative balances
'allow_negative_balance' => false,
// Table name for credit transactions (change if you've updated the migration table name)
'table_name' => 'credits',
];Concurrency & Locking: This package uses row-level locking (SELECT FOR UPDATE) to prevent race conditions during concurrent credit operations. This requires a database engine that supports proper transaction isolation and row-level locking:
- β MySQL/MariaDB: Requires InnoDB engine (default in modern versions)
- β PostgreSQL: Full support for row-level locking
β οΈ SQLite: Row-level locking is ignored; concurrent operations may produce incorrect results in high-concurrency scenarios
For production environments with concurrent users, we recommend using MySQL/MariaDB (InnoDB) or PostgreSQL.
Add the HasCredits trait to any model that should handle credits:
use Climactic\Credits\Traits\HasCredits;
class User extends Model
{
use HasCredits;
}// Add credits
$user->creditAdd(100.00, 'Subscription Activated');
// Deduct credits
$user->creditDeduct(50.00, 'Purchase Made');
// Get current balance
$balance = $user->creditBalance();
// Check if user has enough credits
if ($user->hasCredits(30.00)) {
// Proceed with transaction
}Transfer credits between two models:
$sender->creditTransfer($recipient, 100.00, 'Paying to user for their service');// Get last 10 transactions
$history = $user->creditHistory();
// Get last 20 transactions in ascending order
$history = $user->creditHistory(20, 'asc');Get balance as of a specific date:
$date = new DateTime('2023-01-01');
$balanceAsOf = $user->creditBalanceAt($date);Add additional information to transactions:
$metadata = [
'order_id' => 123,
'product' => 'Premium Subscription'
];
$user->creditAdd(100.00, 'Purchase', $metadata);Events are fired for each credit transaction, transfer, and balance update.
The events are:
CreditsAddedCreditsDeductedCreditsTransferred
| Method | Description |
|---|---|
creditAdd(float $amount, ?string $description = null, array $metadata = []) |
Add credits to the model |
creditDeduct(float $amount, ?string $description = null, array $metadata = []) |
Deduct credits from the model |
creditBalance() |
Get the current balance |
creditTransfer(Model $recipient, float $amount, ?string $description = null, array $metadata = []) |
Transfer credits to another model |
creditHistory(int $limit = 10, string $order = 'desc') |
Get transaction history |
hasCredits(float $amount) |
Check if model has enough credits |
creditBalanceAt(Carbon|DateTimeInterface|int $dateTime) |
Get balance at a specific time |
credits() |
Eloquent relationship to credit transactions |
The following methods are deprecated and will be removed in v2.0. They still work but will trigger deprecation warnings:
| Deprecated Method | Use Instead |
|---|---|
addCredits() |
creditAdd() |
deductCredits() |
creditDeduct() |
getCurrentBalance() |
creditBalance() |
transferCredits() |
creditTransfer() |
getTransactionHistory() |
creditHistory() |
hasEnoughCredits() |
hasCredits() |
getBalanceAsOf() |
creditBalanceAt() |
creditTransactions() |
credits() |
composer testPlease see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please report security vulnerabilities to security@climactic.co.
GitHub Sponsors: @climactic
To become a title sponsor, please contact sponsors@climactic.co.
The MIT License (MIT). Please see License File for more information.
This package is not affiliated with Laravel. It's for Laravel but is not by Laravel. Laravel is a trademark of Taylor Otwell.