PHPackages                             eidolex/e-wallet - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. eidolex/e-wallet

ActiveLibrary[Payment Processing](/categories/payments)

eidolex/e-wallet
================

E-Wallet package for managing wallets, transfers, and transactions.

v0.0.5(3mo ago)051MITPHPPHP ^8.1

Since Feb 8Pushed 3mo agoCompare

[ Source](https://github.com/eidolex/e-wallet)[ Packagist](https://packagist.org/packages/eidolex/e-wallet)[ RSS](/packages/eidolex-e-wallet/feed)WikiDiscussions main Synced today

READMEChangelog (5)Dependencies (6)Versions (7)Used By (0)

Eidolex E-Wallet
================

[](#eidolex-e-wallet)

A Laravel package for managing wallets, transfers, and transactions. Attach a wallet to any Eloquent model with a simple trait and start processing top-ups, withdrawals, and peer-to-peer transfers.

Requirements
------------

[](#requirements)

- PHP ^8.1
- Laravel ^9.0 | ^10.0 | ^11.0 | ^12.0
- [spatie/laravel-data](https://github.com/spatie/laravel-data) ^3.0 | ^4.0 (v3 for Laravel 9, v4 for Laravel 10+)

Installation
------------

[](#installation)

Add the package to your `composer.json` repositories (local path or VCS), then require it:

```
composer require eidolex/e-wallet
```

The service provider is auto-discovered via `composer.json` extra config.

Run the migrations:

```
php artisan migrate
```

Optionally publish the config and migrations:

```
# Config only
php artisan vendor:publish --tag=e-wallet-config

# Migrations only
php artisan vendor:publish --tag=e-wallet-migrations
```

Setup
-----

[](#setup)

Add the `HasWallet` trait and `HasWalletContract` interface to any Eloquent model:

```
use Eidolex\EWallet\Concerns\HasWallet;
use Eidolex\EWallet\Contracts\HasWalletContract;

class User extends Model implements HasWalletContract
{
    /** @use HasWallet */
    use HasWallet;
}
```

This gives the model access to `wallet()`, `transactions()`, `deposit)`, `withdraw()`, and `transfer()`. To use your own Wallet, Transaction, or Transfer models, see [Custom models](#custom-models).

Usage
-----

[](#usage)

### Top Up

[](#top-up)

Add funds to a wallet. The wallet is automatically created on first use.

```
use Eidolex\EWallet\Data\DepositData;
use Eidolex\EWallet\Enums\TransactionName;
use Eidolex\EWallet\Enums\TransactionStatus;

$transaction = $user->depositnew DepositData(
    name: TransactionName::TopUp,
    amount: 10000,
    status: TransactionStatus::Completed, // default
    metadata: ['source' => 'credit_card'],
));

$transaction->id;     // UUID
$transaction->amount; // 10000
$transaction->type;   // TransactionType::Deposit
```

You can pass a custom DTO that extends `DepositData` (e.g. to add fees, computed metadata, or opening/closing balance). See [Custom DepositData](#custom-DepositData) for an example.

### Withdraw

[](#withdraw)

Deduct funds from a wallet.

```
use Eidolex\EWallet\Data\WithdrawData;
use Eidolex\EWallet\Enums\TransactionName;

$transaction = $user->withdraw(new WithdrawData(
    name: TransactionName::Withdraw,
    amount: 3000,
    metadata: ['reason' => 'cash_out'],
));
```

You can pass a custom DTO that extends `WithdrawData` and overrides `fields(Wallet $wallet)`. See [Custom DepositData](#custom-DepositData) for the same pattern.

### Transfer

[](#transfer)

Move funds between two wallet holders. Creates a withdrawal transaction for the sender and a deposit transaction for the receiver, linked by a `Transfer` record.

```
use Eidolex\EWallet\Data\TransferData;
use Eidolex\EWallet\Enums\TransactionName;

$transfer = $sender->transfer(new TransferData(
    to: $receiver,
    name: TransactionName::Gift,
    amount: 5000,
    fromMetadata: ['note' => 'Birthday gift'],
    toMetadata: ['from' => $sender->name],
));

$transfer->from; // Transaction (sender, type: Withdraw)
$transfer->to;   // Transaction (receiver, type: Deposit)
$transfer->amount;
```

You can pass a custom DTO that extends `TransferData` and overrides `fromFields(Wallet $wallet)` and `toFields(Wallet $wallet)`. See [Custom DepositData](#custom-DepositData) for the same pattern.

### Accessing the Wallet &amp; Transactions

[](#accessing-the-wallet--transactions)

```
// Wallet (auto-created on first operation)
$wallet = $user->wallet;
$wallet->balance; // current balance

// All transactions through the wallet
$transactions = $user->transactions;
```

### Transaction Statuses

[](#transaction-statuses)

Balance is **only updated** when a transaction's status is `Completed`. Use `Pending` to record a transaction without affecting the balance.

```
use Eidolex\EWallet\Enums\TransactionStatus;

// Pending transaction — balance unchanged
$transaction = $user->depositnew DepositData(
    name: TransactionName::TopUp,
    amount: 5000,
    status: TransactionStatus::Pending,
));
```

Data Transfer Objects
---------------------

[](#data-transfer-objects)

All operations use [Spatie Laravel Data](https://spatie.be/docs/laravel-data) DTOs. The `name` parameter accepts any `UnitEnum`, so you can use the built-in `TransactionName` or your own enum. Transaction attributes are built from each DTO: `DepositData` and `WithdrawData` expose `fields(Wallet $wallet)`, and `TransferData` exposes `fromFields(Wallet $wallet)` and `toFields(Wallet $wallet)`. Extend the DTO classes and override these methods if you need custom transaction data (e.g. computed metadata or balances).

DTOParameters`DepositData``name` (UnitEnum), `amount` (int), `status` (TransactionStatus = Completed), `metadata` (?array)`WithdrawData``name` (UnitEnum), `amount` (int), `status` (TransactionStatus = Completed), `metadata` (?array)`TransferData``to` (HasWalletContract), `name` (UnitEnum), `amount` (int), `fromMetadata` (?array), `toMetadata` (?array)Customization
-------------

[](#customization)

### Custom Transaction Name Enum

[](#custom-transaction-name-enum)

By default, transaction names use `Eidolex\EWallet\Enums\TransactionName` which provides: `TopUp`, `Withdraw`, `Gift`, and `Purchase`.

To use your own enum, create it and update the config:

```
// app/Enums/MyTransactionName.php
enum MyTransactionName: string
{
    case TopUp = 'top_up';
    case Withdraw = 'withdraw';
    case Subscription = 'subscription';
    case Refund = 'refund';
}
```

```
// config/e-wallet.php
'enums' => [
    'transaction_name' => App\Enums\MyTransactionName::class,
    // ...
],
```

Then pass your enum when creating transactions:

```
$user->depositnew DepositData(
    name: MyTransactionName::Subscription,
    amount: 2999,
));
```

### Custom Transaction Status Enum

[](#custom-transaction-status-enum)

Similarly, you can replace the default `TransactionStatus` enum:

```
// config/e-wallet.php
'enums' => [
    'transaction_status' => App\Enums\MyTransactionStatus::class,
    // ...
],
```

### Custom Metadata Cast

[](#custom-metadata-cast)

The `metadata` column is cast to `array` by default. You can change this in the config:

```
// config/e-wallet.php
'enums' => [
    'transaction_metadata' => 'collection', // or AsArrayObject::class, etc.
],
```

### Custom DepositData

[](#custom-depositdata)

Extend `DepositData` and override `fields(Wallet $wallet)` when you need custom transaction attributes (e.g. computed metadata, fees, or opening/closing balance).

```
// app/Data/CustomDepositData.php
namespace App\Data;

use Eidolex\EWallet\Data\DepositData;
use Eidolex\EWallet\Models\Wallet;

/**
 * Custom top-up DTO that adds a 2% fee, processed_at timestamp, and opening/closing balance to transactions.
 *
 * @extends DepositData
 */
class CustomDepositData extends DepositData
{
    public function fields(Wallet $wallet): array
    {
        $fee = (int) ($this->amount * 0.02);
        $metadata = array_merge($this->metadata ?? [], [
            'processed_at' => now()->toISOString(),
            'fee' => $fee,
        ]);

        return [
            'name' => $this->name,
            'amount' => $this->amount,
            'status' => $this->status,
            'metadata' => $metadata,
            'opening_balance' => $wallet->balance,
            'closing_balance' => $wallet->balance + $this->amount,
        ];
    }
}
```

Usage:

```
use App\Data\CustomDepositData;
use Eidolex\EWallet\Enums\TransactionName;

$transaction = $user->depositnew CustomDepositData(
    name: TransactionName::TopUp,
    amount: 10000,
    metadata: ['source' => 'credit_card'],
));
```

The same pattern applies to `WithdrawData` (override `fields(Wallet $wallet)`) and `TransferData` (override `fromFields(Wallet $wallet)` and `toFields(Wallet $wallet)`).

Configuration Reference
-----------------------

[](#configuration-reference)

```
// config/e-wallet.php
return [
    'enums' => [
        // Cast for the Transaction `name` column (string or enum class)
        'transaction_name' => Eidolex\EWallet\Enums\TransactionName::class,

        // Cast for the Transaction `status` column (optional; package uses TransactionStatus enum by default)
        // 'transaction_status' => Eidolex\EWallet\Enums\TransactionStatus::class,

        // Cast for the Transaction `metadata` column
        'transaction_metadata' => 'array',
    ],

    'models' => [
        'wallet' => Eidolex\EWallet\Models\Wallet::class,
        'transaction' => Eidolex\EWallet\Models\Transaction::class,
        'transfer' => Eidolex\EWallet\Models\Transfer::class,
    ],
];
```

### Custom Models

[](#custom-models)

You can swap the package models with your own by extending the base classes and registering them in config. Use this when you need a custom table, extra attributes, or app-specific methods.

**1. Extend the package model** (e.g. custom Wallet):

```
// app/Models/EWallet.php
namespace App\Models;

use Eidolex\EWallet\Models\Wallet;

class EWallet extends Wallet
{
    protected $table = 'wallets';
}
```

**2. Register in config:**

```
// config/e-wallet.php
return [
    'models' => [
        'wallet' => App\Models\EWallet::class,
        'transaction' => Eidolex\EWallet\Models\Transaction::class,
        'transfer' => Eidolex\EWallet\Models\Transfer::class,
    ],
    // ...
];
```

**3. Add the trait with matching generics** so static analysis and IDE know the correct types:

```
// app/Models/User.php
use Eidolex\EWallet\Concerns\HasWallet;
use Eidolex\EWallet\Contracts\HasWalletContract;

class User extends Model implements HasWalletContract
{
    /** @use HasWallet */
    use HasWallet;
}
```

Trait generic order: `TName`, `WalletModel`, `TransactionModel`, `TransferModel`. Omit or keep defaults for models you do not customize. If you only use a custom Wallet:

```
/** @use HasWallet */
use HasWallet;
```

Database Schema
---------------

[](#database-schema)

The package creates three tables:

**wallets** — One wallet per owner (polymorphic). Unique on `(owner_type, owner_id)`.

ColumnType`id`UUID (primary)`owner_type`string`owner_id`string`balance`unsigned big integer (default: 0)`created_at`timestamp`updated_at`timestamp**transactions** — Individual debit/credit records.

ColumnType`id`UUID (primary)`wallet_id`UUID (foreign key)`type`unsigned tiny integer (enum: 0 = Withdraw, 1 = Deposit)`name`string (configurable enum)`amount`unsigned big integer`status`unsigned tiny integer (enum: Pending, Completed, Cancelled, Failed, Refunded)`opening_balance`unsigned big integer (nullable)`closing_balance`unsigned big integer (nullable)`metadata`JSON (nullable)`created_at`timestamp`updated_at`timestamp**transfers** — Links two transactions (sender and receiver).

ColumnType`id`UUID (primary)`from_transaction_id`UUID (foreign key, cascade delete)`to_transaction_id`UUID (foreign key, cascade delete)`amount`unsigned big integer`metadata`JSON (nullable)`created_at`timestamp`updated_at`timestampTransaction Safety
------------------

[](#transaction-safety)

All wallet operations (`topUp`, `withdraw`, `transfer`) are wrapped in `DB::transaction()` so each operation is atomic.

License
-------

[](#license)

MIT

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance82

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~11 days

Total

6

Last Release

90d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/12557367?v=4)[Eidolex](/maintainers/Eidolex)[@eidolex](https://github.com/eidolex)

---

Top Contributors

[![eidolex](https://avatars.githubusercontent.com/u/12557367?v=4)](https://github.com/eidolex "eidolex (28 commits)")

### Embed Badge

![Health badge](/badges/eidolex-e-wallet/health.svg)

```
[![Health](https://phpackages.com/badges/eidolex-e-wallet/health.svg)](https://phpackages.com/packages/eidolex-e-wallet)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[yajra/laravel-oci8

Oracle DB driver for Laravel via OCI8

8793.2M25](/packages/yajra-laravel-oci8)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k90.5k1](/packages/mike-bronner-laravel-model-caching)[api-platform/laravel

API Platform support for Laravel

58171.4k14](/packages/api-platform-laravel)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45444.2k1](/packages/pressbooks-pressbooks)[sebdesign/laravel-viva-payments

A Laravel package for integrating the Viva Payments gateway

4851.0k](/packages/sebdesign-laravel-viva-payments)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
