Laravel Easy Wallet is a simple, secure, and highly extensible wallet system for Laravel applications. It allows you to associate wallets with any model, manage balances, and record transactions safely with concurrency protection, custom exceptions, and event dispatches.
- Wallet Association: Attach a wallet to any Eloquent model (
Walletablecontract). - Concurrency Safe: Uses
lockForUpdateon DB transactions to prevent race conditions during debits and transfers. - Transaction History: Tracks all
creditanddebitoperations with secure UUIDs. - Events System: Dispatches Laravel events upon transaction completion (
WalletCredited,WalletDebited,WalletTransferCompleted). - Custom Exceptions: Easy-to-catch exceptions (
InsufficientBalanceException,WalletNotFoundException,InvalidAmountException). - Highly Extensible: Change the package's internal models easily via configuration.
composer require yasser-elgammal/laravel-easy-walletImplement the Walletable contract and add the HasWallet trait into models that need wallets.
use Illuminate\Database\Eloquent\Model;
use YasserElgammal\LaravelEasyWallet\Contracts\Walletable;
use YasserElgammal\LaravelEasyWallet\Traits\HasWallet;
class User extends Model implements Walletable
{
use HasWallet;
/**
* Automatically create a wallet when the model is created.
* Default is [true]. Set to false to disable auto creation.
*/
protected bool $autoCreateWallet = true;
}use YasserElgammal\LaravelEasyWallet\Facades\EasyWallet;
use App\Models\User;
$user = User::find(1);
EasyWallet::credit($user, 100.00, 'Initial deposit');try {
EasyWallet::debit($user, 25.00, 'Purchased course');
} catch (\YasserElgammal\LaravelEasyWallet\Exceptions\InsufficientBalanceException $e) {
// Handle lack of funds...
}$fromUser = User::find(1);
$toUser = User::find(2);
try {
EasyWallet::transfer($fromUser, $toUser, 40.00, 'Transfer to friend');
} catch (\Exception $e) {
// Handle error...
}$balance = EasyWallet::balance($user);The package fires events that you can listen to in your EventServiceProvider:
YasserElgammal\LaravelEasyWallet\Events\WalletCreditedYasserElgammal\LaravelEasyWallet\Events\WalletDebitedYasserElgammal\LaravelEasyWallet\Events\WalletTransferCompleted
Example Listener:
use YasserElgammal\LaravelEasyWallet\Events\WalletCredited;
public function handle(WalletCredited $event)
{
// Access transaction details:
// $event->transaction->amount
// Send email/notification to user...
}By default, it uses TXN-{UUID}. You can customize the prefix in your .env file:
WALLET_TXN_PREFIX=MY-PREFIX-You can completely override the default Wallet and WalletTransaction models by publishing the config file and updating the class references.
php artisan vendor:publish --tag=easy-wallet-configThen in config/easy-wallet.php:
'models' => [
'wallet' => \App\Models\CustomWallet::class,
'transaction' => \App\Models\CustomWalletTransaction::class,
],You can optionally publish resources to customize them:
php artisan vendor:publish --tag=easy-wallet-configphp artisan vendor:publish --tag=easy-wallet-migrationsphp artisan vendor:publish --tag=easy-wallet-models(Remember to update the config/easy-wallet.php if you change the model namespaces!)
Contributions are welcome and appreciated!
If you have an idea, feature request, bug fix, or any improvement:
- Feel free to open an issue.
- Submit a Pull Request.
- Or simply get in touch if you need help.
Thank you for supporting the project! 🙌