• Stars
    star
    1,113
  • Rank 41,590 (Top 0.9 %)
  • Language
    PHP
  • License
    MIT License
  • Created almost 6 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

It's easy to work with a virtual wallet

Laravel Wallet

Maintainability Test Coverage Financial Contributors on Open Collective Mutation testing badge

Latest Stable Version Latest Unstable Version License composer.lock

Sparkline

laravel-wallet - Easy work with virtual wallet.

[Benchmark] [Documentation] [Get Started]

  • Vendor: bavix
  • Package: laravel-wallet
  • Version: Latest Stable Version
  • PHP Version: 8.0+
  • Laravel Version: 9.x
  • Composer: composer require bavix/laravel-wallet

Support Policy

Version Laravel PHP Release date End of improvements End of support
7.x ^6.0,^7.0,^8.0 7.4,8.0,8.1 Nov 25, 2021 Mar 1, 2022 Sep 6, 2022
8.x ^9.0 8.0,8.1 Feb 8, 2022 May 1, 2022 Jun 1, 2022
9.x [LTS] ^9.0,^10.0 8.0,8.1,8.2 May 2, 2022 Feb 1, 2023 Feb 6, 2024
10.x [LTS] ^10.0 8.1,8.2 Jul 8, 2023 May 1, 2024 Feb 3, 2025

Upgrade Guide

To perform the migration, you will be helped by the instruction.

Community

I want to create a cozy place for developers using the wallet package. This will help you find bugs faster, get feedback and discuss ideas.

telegram

Telegram: @laravel_wallet

Extensions

Extension Description
Swap Addition to the laravel-wallet library for quick setting of exchange rates
uuid Addition to laravel-wallet to support model uuid keys
Warm Up Addition to the laravel-wallet library for refresh balance wallets

Usage

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;

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 !$customer->paid($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)$user->paid($item)); // bool(true)

var_dump($user->refund($item)); // bool(true)
var_dump((bool)$user->paid($item)); // bool(false)

Eager Loading

// When working with one wallet
User::with('wallet');

// When using the multi-wallet functionality
User::with('wallets');

How to work with fractional numbers?

Add the HasWalletFloat trait and WalletFloat interface to model.

use Bavix\Wallet\Traits\HasWalletFloat;
use Bavix\Wallet\Interfaces\WalletFloat;
use Bavix\Wallet\Interfaces\Wallet;

class User extends Model implements Wallet, WalletFloat
{
    use HasWalletFloat;
}

Now we make transactions.

$user = User::first();
$user->balance; // 100
$user->balanceFloat; // 1.00

$user->depositFloat(1.37);
$user->balance; // 237
$user->balanceFloat; // 2.37

Performance Comparison

All versions:

Name 7.3 8.4 9.2 9.3 9.4 9.5 9.6 10.0
Atomic:Blocks - - 913ms 734ms 723ms 853ms 677ms 669ms
Cart:EagerLoaderPay 25.6s 800ms 650ms 650ms 641ms 837ms 666ms 655ms
Cart:Pay 1.64s 580ms 421ms 424ms 421ms 524ms 390ms 382ms
Cart:PayFree 1.55s 491ms 344ms 333ms 337ms 465ms 361ms 377ms
Cart:PayOneItemXPieces 697ms 149ms 74.5ms 77.1ms 78.9ms 94.3ms 77.6ms 60.4ms
Gift:Gift 61ms 69.3ms 67.1ms 69ms 70.3ms 91.4ms 70.2ms 65.8ms
Gift:Refund 130ms 144ms 133ms 138ms 139ms 182ms 140ms 131ms
Solo:Deposit 35.9ms 36.5ms 37.7ms 37.9ms 38.6ms 43.8ms 39.8ms 20.5ms
Solo:EagerLoading 1.1s 1.33s 1.12s 1.1s 1.06s 1.49s 1.28s 1.17s
Solo:ForceWithdraw 36.2ms 37.2ms 37.6ms 38ms 38.3ms 44.8ms 40ms 20.2ms
Solo:GetBalance 26.6ms 27.7ms 29.9ms 29.2ms 31.8ms 32.8ms 32ms 8.39ms
Solo:Transfer 54.9ms 56.4ms 51.1ms 51.8ms 53.1ms 65ms 53.2ms 35ms
Solo:Withdraw 41.3ms 42ms 42ms 41.5ms 43ms 50.8ms 44.9ms 25.9ms
State:InTransaction 758ms 778ms 773ms 742ms 779ms 1.03s 566ms 571ms
State:RefreshInTransaction 51.6ms 52.4ms 52.2ms 52.3ms 58.8ms 61.6ms 53.5ms 43ms
State:TransactionRollback 38.8ms 39.7ms 39.8ms 41.3ms 42ms 51.3ms 43ms 23.9ms

Major compare:

Name 7.x 8.x 9.x 10.x
Atomic:Blocks - - 753ms 669ms
Cart:EagerLoaderPay 25.6s 800ms 661ms 655ms
Cart:Pay 1.64s 580ms 424ms 382ms
Cart:PayFree 1.55s 491ms 347ms 377ms
Cart:PayOneItemXPieces 697ms 149ms 78.5ms 60.4ms
Gift:Gift 61ms 69.3ms 70.6ms 65.8ms
Gift:Refund 130ms 144ms 139ms 131ms
Solo:Deposit 35.9ms 36.5ms 39.3ms 20.5ms
Solo:EagerLoading 1.1s 1.33s 1.16s 1.17s
Solo:ForceWithdraw 36.2ms 37.2ms 38.8ms 20.2ms
Solo:GetBalance 26.6ms 27.7ms 31.1ms 8.39ms
Solo:Transfer 54.9ms 56.4ms 53.5ms 35ms
Solo:Withdraw 41.3ms 42ms 43.6ms 25.9ms
State:InTransaction 758ms 778ms 754ms 571ms
State:RefreshInTransaction 51.6ms 52.4ms 59.2ms 43ms
State:TransactionRollback 38.8ms 39.7ms 42.4ms 23.9ms

Table generated using benchmark. Pull Request.


Supported by

Supported by JetBrains

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

More Repositories

1

laravel-admin-leaflet

OpenStreetMap for laravel-admin
PHP
29
star
2

gripmock

gRPC Mock Server
Go
24
star
3

dash

Server control panel
PHP
22
star
4

laravel-xhprof

Laravel XHProf - Library for profiling in production.
PHP
20
star
5

laravel-wallet-swap

Package for working with currencies in laravel-wallet.
PHP
19
star
6

laravel-entry

Highly loaded ClickHouse entry for Laravel
PHP
7
star
7

laravel-wallet-warmup

PHP
5
star
8

boxpacker3

A 3D container packing library in golang.
Go
5
star
9

laravel-wallet-vacuum

PHP
4
star
10

laravel-prof

DIY profiler, can be used in production.
PHP
4
star
11

laravel-settings

Keep user settings easy
PHP
4
star
12

glow

Create your distributed file storage. Store files and images in one place with automatic preview generation
PHP
3
star
13

nodejs-cozy-house

analytics system
JavaScript
2
star
14

flow-native

PHP
2
star
15

glow-kit

A set of functions for fast image processing for the web
PHP
2
star
16

laravel-wallet-uuid

Package for uuid support in laravel-wallet.
PHP
2
star
17

geo

library for work with GEODATA
PHP
2
star
18

laravel-middleware-ifindex

Removes "index.php" from the route
PHP
1
star
19

cozy-house

Analytics collection system
PHP
1
star
20

dius

Fast calculation of folder/file sizes. Alternative `du -h -d 1`
Go
1
star
21

laravel-middleware-https

Automatic protocol change from http to https
PHP
1
star
22

helpers

PHP
1
star
23

config

Lightweight configuration file loader that supports popular formats
PHP
1
star
24

slice

Library for quick access to the array
PHP
1
star
25

laravel-wallet-benchmark

Tests to measure the performance of different versions of laravel-wallet
PHP
1
star
26

glow-flysystem

FlySystem adapter for working with Glow CDN
PHP
1
star
27

microservices

Simple microservice
PHP
1
star
28

router

Library helps you quickly build routes
PHP
1
star
29

uuid-ui

Quick uuid conversion. Test Assistant
JavaScript
1
star