Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Pay Pocket Laravel Package

toneflix/laravel-pay-pocket

A Laravel package for adding payment wallets and transactions to your app, with simple APIs for funding pockets, tracking balances, recording transactions, and supporting multiple payment providers. It simplifies wallet-based payment workflows in Laravel.

View on GitHub
Deep Wiki
Context7

Getting Started

Mind the rename first. v4.0.0 is a vendor + namespace move, not a feature release. Install as toneflix/laravel-pay-pocket:^4.0, and import Toneflix\LaravelPayPocket\... everywhere. Requirements are PHP ^8.3|^8.4 and Illuminate ^12.0|^13.0 — on Laravel 11 or PHP 8.2 you stay on 3.x.

composer require toneflix/laravel-pay-pocket:^4.0
php artisan vendor:publish --provider="Toneflix\LaravelPayPocket\PayPocketServiceProvider"
php artisan migrate

Look here first, in this order:

  1. config/pay-pocket.php — the wallet-type definitions and table names drive everything else.
  2. The published migrations — read the wallets and transactions schema before writing any code; the column types tell you how amounts are stored (decimal vs integer) and that determines your whole money-handling strategy.
  3. The trait you add to your model (typically HasWallet / PayPocket) — this is where the real public API lives. Read the method signatures in the trait body rather than trusting the README; argument order matters and the README lags releases.
  4. src/Models/Wallet.php and src/Models/Transaction.php — the relations your reporting queries will hang off.

First use case: add the trait to User, then in tinker do a deposit and read the balance back. Confirm the row landed in transactions and that the wallet balance matches what you expect before wiring it into a controller. Ten minutes in tinker saves a day of reconciling a broken ledger.

Implementation Patterns

Put the trait on the model that owns the money, not on User by default. Teams, organizations, and API clients all plausibly need wallets. Because the trait is model-agnostic, the same package serves all of them — but decide this early, since it affects your polymorphic foreign keys and every query you write afterwards.

Wrap every mutation in a service, never call the trait from a controller. A WalletService with credit(), debit(), transfer() methods gives you one place to add locking, logging, and authorization. Controllers stay thin; the trait stays an implementation detail you can swap.

Treat the transaction table as an append-only ledger. Do not update or delete transaction rows — if you need corrections, post a compensating entry. Every downstream concern (statements, reconciliation, dispute handling, finance exports) depends on that table being immutable, and you cannot retrofit immutability once rows have been mutated.

Pair each mutation with a domain event. Fire an event after the commit, not inside it, so listeners that send mail or hit a queue don't fire on a rolled-back transaction. A WalletDebited event carrying the transaction ID is enough for notifications, analytics, and webhooks.

Idempotency is your responsibility, not the package's. Payment webhooks retry. Add a unique index on your own reference column and catch the duplicate-key exception rather than checking-then-inserting — the check is a race condition under load.

Testing: use Pest (dev tooling is on Pest ^4 in this release) with RefreshDatabase. Assert on the transaction rows, not just the returned balance — a passing balance assertion hides double-posting if the test only reads the wallet column. For concurrency, DB::transaction in a test plus lockForUpdate gives you a reproducible race, but real coverage needs parallel processes.

Reporting: the transactions table joined to wallets covers most admin dashboards. Build read-only query objects or dedicated report classes rather than adding scopes to the vendor models — vendor models are the least stable surface in the package.

Gotchas and Tips

v4 upgrade checklist — do it in this order:

composer remove toneflix-code/laravel-pay-pocket
composer require toneflix/laravel-pay-pocket:^4.0
php artisan config:clear && php artisan cache:clear

Then grep your entire codebase — including config/, seeders, tests, queued job payloads, and any Blade/Action classes — for ToneflixCode. A partial rename produces Class not found at runtime in exactly the code paths you exercise least.

Namespace renames break more than imports. If you reference the fully-qualified class name as a string — in config/auth.php-style config, morph maps, Relation::morphMap(), container bindings, or serialized queue payloads — a use statement rewrite won't find it. Search for the string literal too. Queued jobs serialized before the deploy will fail to unserialize after it; drain the queue before upgrading.

PHP 8.3 is a hard floor. If your CI matrix or Docker base image is on 8.2, the upgrade fails at composer install and it looks like a dependency conflict. Check the runtime, not just composer.json.

The upgrade is not incremental. There is no 3.x-compatible patch path to Laravel 13 — you take the rename and the framework bump together. If you're mid-cycle on Laravel 11, pin ^3.0 and schedule this as deliberate work, not a composer update.

Amount precision will bite you. Whichever way the migrations store amounts, cast explicitly in your own code: integer minor units (cents) avoid float drift entirely. If the schema is decimal, never do arithmetic on the string values Eloquent returns before casting — "0.10" + "0.20" in PHP float space is the classic bug that shows up as a one-cent reconciliation gap a month later.

Race conditions on balance are silent. Two concurrent withdrawals can both read a sufficient balance and both write. Always lockForUpdate the wallet row inside DB::transaction before checking the balance. The package may or may not do this for you — verify in the source, and assume it doesn't.

Don't edit published migrations after they've run in production. Publish once, commit, and make subsequent schema changes in your own migration files that alter the vendor tables. Editing in place works locally and corrupts production state.

Config caching hides the rename. After deploying v4, php artisan config:cache can serve a stale cached config that still references the old namespace. Clear the cache in your deploy script before the new config is consumed.

Extension points: config file for wallet types and table names, the trait for model behaviour, and model resolution via config where supported. Prefer these to subclassing vendor models — subclassing couples you to internals that the 4.0.0 release just demonstrated are not stable. Where you need custom behaviour, wrap rather than extend.

Debugging tip: when a balance looks wrong, query transactions directly and sum it. If the sum disagrees with the wallet column, something bypassed the package (a seeder, a manual SQL update, a lost transaction) — that's a data-integrity bug, not a package bug, and the ledger tells you exactly when it started.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package