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 Wallet Laravel Package

stephenjude/laravel-wallet

A Laravel wallet package for adding balances and transactions to any model. Create multiple wallets, deposit, withdraw, transfer funds, and track transaction history with a clean, simple API.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Eloquent-native package: a HasWallet trait on the owner model plus Wallet and Transaction models. This maps cleanly onto a standard Laravel domain model (User/Team/Account owns one or more wallets), so it slots into an existing app without introducing a new service, queue, or datastore.
  • It is a simple wallet, not a general ledger. Balance is held on the wallet record and mutated by credit/debit operations, with transactions acting as an activity log. That is sufficient for store credit, refunds, rewards, and prepaid balances; it is not sufficient as a system of record for regulated e-money or multi-party settlement without additional controls.
  • Multi-wallet and multi-currency support hinge on the wallet model's attributes and config; confirm whether currency is per-wallet and whether mixed-currency transfers are rejected at the package level or must be enforced by us.

Integration feasibility

  • Low friction: composer require, publish config and migrations, run migrations, add the trait, create a wallet, call deposit/withdraw/transfer. A mid-level Laravel developer can produce a working proof of concept in under a day.
  • Additive schema only — new tables alongside existing ones, no alterations to core tables. Rollback is a migration drop, which keeps the evaluation cheap and reversible.
  • The real integration work is not the package; it is the surrounding discipline: wrapping calls in our own service, tying wallet mutations to payment webhooks, and adding idempotency and reconciliation.

Technical risk

  • Ledger model: single-entry balance mutation with a log is not audit-grade. Corrections require compensating transactions, and there is no built-in guarantee that the transaction log reconstructs the balance. For any use case with financial reporting or dispute handling, we must own a reconciliation job.
  • Concurrency: correctness depends on lockForUpdate (or equivalent) inside a DB transaction for every balance-mutating path. If the package does not do this consistently, concurrent withdrawals can overdraw. This is the single highest-severity item to verify before adoption.
  • Idempotency: retried payment webhooks are the normal case, not the edge case. If deposit has no idempotency key or unique reference constraint, duplicate credits are a near-certainty in production.
  • Precision: confirm integer minor-units or bcmath throughout, and that rounding is applied once at the boundary. Float arithmetic anywhere in the money path is a disqualifier.
  • Bus factor: 266 stars and a single maintainer under MIT. Treat the package as a vendored dependency we may need to fork; do not assume timely upstream fixes for a money-path defect.
  • Maturity signal: the composite score (~15.7) is modest. Weigh it as "viable for low-stakes balances, requires hardening for high-stakes."

Key questions

  1. Does every balance mutation run inside a DB transaction with a row-level lock on the wallet?
  2. Is there an idempotency key or unique external reference on transactions, enforced at the database level?
  3. Integer minor units or bcmath — and where does rounding occur?
  4. Can a balance go negative? Is the check inside the same lock as the debit?
  5. Does transfer guarantee atomicity across both wallets, and does it deadlock-proof the lock ordering?
  6. Is the transaction log append-only and immutable, or can rows be updated/deleted?
  7. Which Laravel/PHP versions are supported, and is there a CI matrix?
  8. Test coverage on the money paths — and are concurrency tests present?
  9. Multi-currency: per-wallet currency, conversion, and rejection of cross-currency transfers?
  10. Does it support holds/reserves (authorize now, capture later), or only immediate debit?

Integration Approach

Stack fit

  • Standard Laravel + MySQL/PostgreSQL. No new infrastructure, no queue requirement, no external service. Fits a monolith or a modular monolith; if we are already service-oriented, this package belongs inside whichever service owns the customer balance, not shared across services via direct table access.
  • Compatible with existing auth, tenancy, and payment-provider integrations because it is just Eloquent models behind a trait.

Migration path

  1. Isolate behind an interface. Define our own WalletService contract (credit, debit, transfer, balance, hold) and implement it with this package. Every call site depends on our interface, not on the vendor models. This is the decision that makes the rest reversible.
  2. Additive schema. Publish and run migrations as-is; add our own columns/tables for idempotency keys, external references, and reconciliation state rather than patching vendor migrations.
  3. Backfill. If balances already exist as a column on users, run a one-time idempotent backfill that creates a wallet per owner and seeds an opening-balance transaction, then freeze the legacy column behind read-only access until cutover is verified.
  4. Dual-read, single-write. Serve balance reads from the new wallet while the legacy column is still written for a short window; alert on divergence, then retire the legacy field.

Compatibility

  • Confirm the supported Laravel range against our current and next-upgrade versions before committing — a money-path package that blocks a framework upgrade is an expensive dependency.
  • Verify behavior under our tenancy model (global scopes, connection routing for read replicas). Reads must not hit a replica that lags behind a just-committed debit.
  • If we run multiple databases or shard by tenant, confirm the package does not assume a single connection for transfers.

Sequencing

  1. Spike: install, run the test suite, and write four adversarial tests (concurrent double-withdraw, duplicate webhook deposit, cross-currency transfer, rounding at the boundary). Gate on these passing.
  2. Wrap in WalletService with idempotency enforced by us — a unique index on (wallet_id, idempotency_key) regardless of what the package offers.
  3. Integrate one low-risk flow first: refunds to store credit. Measure, reconcile daily.
  4. Expand to the payment-webhook funding path once reconciliation is clean for two weeks.
  5. Only then consider holds/reserves or multi-currency, and only if the package supports them or we can layer them.

Operational Impact

Maintenance

  • Low day-to-day code churn, but plan for stewardship: pin the exact version, vendor the source into our repo or a private fork, and record the delta. Budget roughly a few days per year for upstream review plus the cost of any patch we carry ourselves.
  • MIT license is clean for commercial use; no attribution burden beyond retaining the notice.

Support

  • Community-only: GitHub issues, no SLA, no vendor. For a money path this means our on-call owns defects. Staff accordingly — one engineer should be able to read the whole package in an afternoon, which makes self-support realistic.
  • Maintain an internal runbook covering: how to reverse a transaction, how to reconcile a wallet against the ledger, and how to identify and correct a duplicate credit.

Scaling

  • Correctness scales; throughput does not scale horizontally for a single hot wallet. Row-level locking serializes writes per wallet, so a high-traffic shared wallet (e.g., a platform account) becomes a contention point. Expect deadlocks and lock-wait timeouts under load and design retries with backoff.
  • The transaction table grows without bound. Plan for indexing on (wallet_id, created_at) and a partitioning or archival strategy from day one — retrofitting this on a large table is painful.
  • Reads of a cached balance are fine if staleness is bounded and clearly communicated in the UI.

Failure modes

  • Duplicate credit from a retried webhook — the highest-likelihood production incident. Mitigate with our own idempotency key plus a unique constraint.
  • Overdraft from a race between balance check and debit — mitigate with locking inside the transaction, and a DB-level check constraint on non-negative balance where the schema allows.
  • Rounding drift accumulating across many small transactions — mitigate with integer minor units and periodic reconciliation.
  • Deadlock on concurrent transfers in opposite directions — mitigate with deterministic lock ordering or retry-with-backoff.
  • Partial transfer if the two-wallet update is not atomic — verify and, if needed, wrap in our own outer transaction.
  • Replica lag presenting a stale balance immediately after a write — route post-write reads to the primary.

Ramp-up

  • Low. Any Laravel developer is productive within a day; the trait-plus-models API is idiomatic and the surface area is small.
  • The real onboarding cost is domain, not package: teaching the team the invariant set (no negative balances, every mutation idempotent, ledger reconciles to balance) and the reconciliation runbook. Estimate one engineer-week for the first integration including hardening and tests, and treat any figure below three days as a signal that the hardening work was skipped.
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.
skyraptor/chatter
edlugz/sasapay
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