Skip to main content
Back to packages
1,320 GitHub stars

bavix/laravel-wallet

View on GitHub

Description

Easy work with virtual wallet

Add the HasWallet trait and Wallet interface to model.

use Bavix\Wallet\Traits\HasWallet;
use Bavix\Wallet\Interfaces\Wallet;
 
class User extends Model implements Wallet
{
use HasWallet;
}

Now we make transactions.

$user = User::first();
$user->balanceInt; // 0
 
$user->deposit(10);
$user->balance; // 10
$user->balanceInt; // int(10)
 
$user->withdraw(1);
$user->balance; // 9
 
$user->forceWithdraw(200, ['description' => 'payment of taxes']);
$user->balance; // -191

Purchases

Add the CanPay trait and Customer interface to your User model.

use Bavix\Wallet\Traits\CanPay;
use Bavix\Wallet\Interfaces\Customer;
 
class User extends Model implements Customer
{
use CanPay;
}

Add the HasWallet trait and interface to Item model.

Starting from version 9.x there are two product interfaces:

  • For an unlimited number of products (ProductInterface);
  • For a limited number of products (ProductLimitedInterface);

An example with an unlimited number of products:

use Bavix\Wallet\Traits\HasWallet;
use Bavix\Wallet\Interfaces\Customer;
use Bavix\Wallet\Interfaces\ProductInterface;
 
class Item extends Model implements ProductInterface
{
use HasWallet;
 
public function getAmountProduct(Customer $customer): int|string
{
return 100;
}
 
public function getMetaProduct(): ?array
{
return [
'title' => $this->title,
'description' => 'Purchase of Product #' . $this->id,
];
}
}

Example with a limited number of products:

use Bavix\Wallet\Traits\HasWallet;
use Bavix\Wallet\Interfaces\Customer;
use Bavix\Wallet\Interfaces\ProductLimitedInterface;
use Bavix\Wallet\External\Api\PurchaseQuery;
use Bavix\Wallet\External\Api\PurchaseQueryHandlerInterface;
 
class Item extends Model implements ProductLimitedInterface
{
use HasWallet;
 
public function canBuy(Customer $customer, int $quantity = 1, bool $force = false): bool
{
/**
* This is where you implement the constraint logic.
*
* If the service can be purchased once, then
* return ! app(PurchaseQueryHandlerInterface::class)->one(PurchaseQuery::create($customer, $this));
*/
return true;
}
 
public function getAmountProduct(Customer $customer): int|string
{
return 100;
}
 
public function getMetaProduct(): ?array
{
return [
'title' => $this->title,
'description' => 'Purchase of Product #' . $this->id,
];
}
}

I do not recommend using the limited interface when working with a shopping cart. If you are working with a shopping cart, then you should override the PurchaseServiceInterface interface. With it, you can check the availability of all products with one request, there will be no N-queries in the database.

Proceed to purchase.

$user = User::first();
$user->balance; // 100
 
$item = Item::first();
$user->pay($item); // If you do not have enough money, throw an exception
var_dump($user->balance); // 0
 
if ($user->safePay($item)) {
// try to buy again
}
 
var_dump((bool) app(PurchaseQueryHandlerInterface::class)->one(PurchaseQuery::create($user, $item))); // bool(true)
 
var_dump($user->refund($item)); // bool(true)
var_dump((bool) app(PurchaseQueryHandlerInterface::class)->one(PurchaseQuery::create($user, $item))); // bool(false)

Related Content on Laravel Daily

Video
Video

Recent Courses on Laravel Daily

Laravel 13 Eloquent: Expert Level

41 lessons
1 h 34 min

How to Build Laravel 13 API From Scratch

30 lessons
1 h 23 min

How to Structure Laravel 13 Projects

16 lessons
1 h 32 min read

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.