
If you’ve ever tried building a wallet system in Laravel — like for in-app purchases, balance top-ups, or digital credits — you know it’s a bit of a pain. There’s a lot to keep track of: balance management, deposits, withdrawals, transactions, currency formatting, even rounding issues.
So when I came across this new Laravel Virtual Wallet package, I got a little excited (okay, maybe a lot). This package basically wraps all the painful stuff in a clean, easy-to-integrate interface that just works. I gave it a try, and here’s what I found — the good, the gotchas, and whether I’d use it again.
Why You Might Want a Virtual Wallet System
There are plenty of use cases for virtual wallets:
- Loyalty points in e-commerce apps
- Token systems for games or education platforms
- Internal currency for SaaS products
- Digital credit for services like food delivery or ride-sharing
You could build it from scratch — but why reinvent the wheel if someone else already built the spokes, rim, and hub?
That’s where Laravel Virtual Wallet comes in.
What the Package Actually Does
This package gives you an easy way to attach a wallet to any Eloquent model (like User
), and then perform operations like:
deposit()
withdraw()
forceWithdraw()
transfer()
balance()
transactions()
All wrapped in a nice API-style method chain you’d expect from Laravel packages.
The core logic lives in a HasWallet
trait that you drop into your model. So if you want to give a User
a wallet:
use Bavix\Wallet\Traits\HasWallet;
class User extends Authenticatable
{
use HasWallet;
}
That’s it. No boilerplate, no extending weird base classes. Clean.
Installing the Package
Here’s the install flow I used:
composer require bavix/laravel-wallet
Then publish and run the migration:
php artisan vendor:publish --tag=wallet-migrations
php artisan migrate
Done. Now your database has the tables it needs for wallets and transactions.
Pro tip: You can customize table names and models in the config if needed.
Real-World Usage: Deposit & Withdraw
Let’s say you want to top-up a user’s balance. With this package, it’s literally one line:
$user->deposit(500); // adds 500 units (e.g. cents, points, tokens)
Need to deduct something?
$user->withdraw(200); // subtracts 200 units
Worried about overdraws? Don’t be. The package throws an exception if there isn’t enough balance.
Unless you want to override that (which you can, with forceWithdraw()
).
You can also do transfers between users:
$userA->transfer($userB, 150); // move 150 from A to B
And yes — everything gets logged in a transactions table, including transfer logs, amounts, timestamps, and wallet IDs.
What’s Stored in the Database?
Two main tables:
wallets
: tracks each model’s balance and currencytransactions
: logs all movements (deposit, withdraw, transfer, etc.)
The cool part? It stores amounts in raw integers — perfect for avoiding floating-point nightmares. So if you’re dealing with money, always treat values as cents, not dollars.
Multiple Wallets Per Model?
Yes. This part kinda blew my mind.
You can assign multiple named wallets to a single model. For example, a user might have:
main
walletbonus
walletreferral
wallet
Here’s how to use them:
$user->createWallet([
'name' => 'Referral Wallet',
'slug' => 'referral',
'meta' => ['type' => 'promo']
]);
$user->wallet('referral')->deposit(300);
Now that’s flexible. I immediately thought of loyalty programs, games, and promo campaigns.
Currency Support
Out of the box, it doesn’t handle multiple currencies yet, but you can customize that in the config if needed.
The stored amounts are numeric only, so formatting is up to you (hint: use moneyphp/money
if you need hardcore currency logic).
Event Hooks and Observers
One thing I appreciate is how the package fires model events — so you can hook into stuff like:
TransactionCreated
WalletCreated
BalanceUpdated
Useful if you want to trigger things like notifications, audits, or logs. You can even extend or override the core logic if needed.
What I Liked (and What Could Be Better)
👍 What I Loved:
- Super easy to set up
- Intuitive API methods
- Solid database design
- Supports decimal precision and rounding
- Multiple wallets per model — seriously cool
🤔 Room for Improvement:
- Docs are a bit sparse in some advanced areas
- Custom transaction types require some digging
- No built-in UI (but that’s fair — it’s backend-focused)
Final Thoughts
If you’re building anything that involves tracking virtual balances — whether it’s coins, credits, or points — this package is a solid time-saver.
You don’t have to worry about concurrency issues, math precision, or creating transaction logs manually. It’s all handled behind the scenes. And Laravel devs will feel right at home thanks to the trait-based setup and familiar API design.
Would I use this in a real project?
Absolutely. In fact, I already am.
Pro Tip:
Store all balances in integers (like cents or tokens), and let your frontend handle the formatting. It’ll save you from money-related headaches down the line.