tomatophp/tomato-wallet
A Laravel wallet package from TomatoPHP for managing user balances and transactions. Add credit and debit operations, track wallet history, and integrate multi-wallet support into your app with a simple, fluent API.
Build vs. buy for the balance/credit ledger. The concrete decision this package informs: spend engineering weeks specifying a wallet schema, atomic credit/debit operations, and payment-adapter plumbing, or adopt this as the starting primitive and own the integration. It supplies the parts PMs most reliably underestimate — a HasWallet trait attachable to any Eloquent model, deposit/withdraw/transfer operations, a recorded transaction per mutation, multi-currency balances, and configurable transaction types. For a PM the framing is scope and time-to-learning, not architecture taste.
Validating prepaid and credit-based bets cheaply. It makes testable, at low cost, the wallet-shaped features that show up in almost every roadmap: prepaid account top-ups, refunds issued as store credit instead of cash, partial payments drawn down against a funded balance, agency retainers consumed against an account, loyalty/store credit, and internal floats for operational tooling. That means a hypothesis like "does letting customers hold a balance move conversion, retention, or AOV?" can be put in front of users without standing up a payments platform first.
Roadmap sequencing for the payments track. If balances are a near-term need and requirements are genuinely modest — one currency, straightforward credit/debit, a small number of providers, no reconciliation or audit obligation beyond a transaction log — this supports a flagged bridge release now and deferring platform investment. If the roadmap genuinely needs multi-currency settlement, daily reconciliation, double-entry accounting, or regulatory posture, treat it as a prototype only and sequence a replacement path in parallel. Wrapping every wallet call behind an internal interface is what keeps that sequencing cheap and the decision reversible.
An explicit platform commitment, made knowingly. Adopting this standardizes the wallet domain on TomatoPHP/TomatoCRM conventions and Filament admin scaffolding. That is a platform decision dressed as a library choice, and it is materially harder to reverse than swapping a Composer package. The PM's job is to get it recorded as a decision rather than let it happen by default in a sprint.
Use-case fit as a scoping filter. Good fit: agency retainers, prepaid service credits, internal tooling where customers hold a float, loyalty/store credit, low-value pilot cohorts. Poor fit: regulated e-money, marketplace escrow, multi-party settlement, high-volume ledger workloads. Flag the misfits early — they invalidate the approach rather than merely adding scope.
Consider it when:
tomato-* packages) over ecosystem independence.Look elsewhere when:
Diligence checklist before adoption: read the source and assess test coverage (does it exercise failure and partial-failure paths, not just happy-path credit/debit?); confirm which payment providers are genuinely implemented versus stubbed or documented-only; verify transaction atomicity under concurrent debits and idempotent handling of replayed webhooks; check whether balance is a mutable column or derived from an append-only ledger; verify Laravel/PHP/Filament version compatibility (it predates current Filament majors); check which tomato-* packages are hard transitive dependencies and how mature those are; and commit to a fork-and-own plan with a named owner and maintenance budget.
For executives: We can put account wallets and basic payment top-ups in front of users in days rather than a full build cycle, at zero license cost under MIT, and get real evidence on whether prepaid balances and store credit move conversion and retention before we fund a payments platform. The trade-off is real: this is a very early package — one GitHub star, no known dependents, single maintainer, last release May 2024 — so we should fund it as an accelerator for a pilot, budget internal ownership of the codebase, run it behind a feature flag on a low-value cohort with daily reconciliation, and plan to replace the ledger layer if the feature proves out. What we are buying is an option and a few weeks of learning, not a platform commitment.
For engineering: It is a Laravel-native, polymorphic wallet manager — wallets attach to any Eloquent model via a trait — with deposit/withdraw/transfer primitives, transaction history with metadata, multi-currency and precision configuration, extendable transaction types, and payment-integration hooks built for TomatoPHP/TomatoCRM, so it slots into our existing models and Filament admin conventions. It is not a production-grade ledger. Expect to fork it under an internal namespace, add row-locking or optimistic versioning around balance updates, write our own tests around credit/debit invariants and partial-failure paths, validate each payment adapter against sandbox and provider docs, pin Laravel/PHP/database/payment-SDK versions, and test on the actual target database — MySQL and Postgres diverge on JSON and enum handling, exactly where a wallet schema bites. The two gates are a deliberate parallel-debit test (if it double-spends, we stop) and webhook signature verification plus idempotency against replayed payloads. Wrap every wallet operation behind an internal interface so no call site touches package classes directly — that interface is the escape hatch that keeps this decision reversible.
Recommendation: Adopt as a time-boxed spike or pilot dependency — feature-flagged, low-value cohort, daily reconciliation — contingent on a code review confirming the balance logic survives a concurrency test and the payment adapters actually work. Not a long-term platform commitment.
How can I help you explore Laravel packages today?