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

laranex/laravel-money

A Laravel package for working with money. It provides value objects, arithmetic, formatting, and currency handling so you can store, calculate, and display amounts accurately without floating-point errors, making it useful for pricing, billing, and e-commerce features.

View on GitHub
Deep Wiki
Context7

Getting Started

This release (v4.0.0-alpha.8) ships with an autogenerated, empty changelog — it is a diff-only alpha bump with no documented features, fixes, or breaking changes. Treat it as a maintenance release and do not rewrite existing money-handling code because of it. The practical guidance below is unchanged from the v4 alpha line.

Minimal steps to adopt:

  1. composer require laranex/laravel-money — and because you are on an alpha, pin the exact version ("laranex/laravel-money": "4.0.0-alpha.8") rather than using ^4.0. Alpha-to-alpha bumps have historically shipped without release notes, so an unpinned constraint can silently move you across API changes.
  2. Publish any config the package exposes (php artisan vendor:publish --tag=...) and set your default currency, default locale, and rounding preference there — not in code.
  3. Look first at the package's own test suite and src/ casts/rules directories; with an empty changelog these are the authoritative source of truth for what the v4 API actually accepts.
  4. First use case: replace a raw decimal(10,2) column + float arithmetic on an invoice or order total. Define the column as an integer minor-units column (or keep the decimal but go through the package's cast), add the cast to the Eloquent model, and render via the package's formatting helper so no number_format() remains in your Blade files.

Verify on a throwaway branch before touching production models — alphas of this package have reshuffled namespaces between minors, and alpha.8 gives you no changelog to tell you whether it did so again.

Implementation Patterns

Model casts as the boundary. The highest-value pattern is to let the cast own the conversion: database value ↔ money object. Controllers and jobs then never see integers-of-cents or floats. Anything that reads $order->total gets a money instance with a currency attached, which kills the class of bug where a total is formatted with the wrong symbol because the currency lived only in a view.

Money arithmetic in the domain layer, formatting at the edge. Additions, multiplications (tax, quantity), and allocations (splitting a discount across line items) belong in services or value objects. Formatting and symbol placement belong in resources, API serializers, and Blade. Keep the two apart so a change of locale never touches business logic, and so tests assert integers/strings rather than rendered output.

Multi-currency as a first-class column. Store the currency code beside every amount and read it from the model rather than from config. A single default_currency config value is fine for a single-market app, but the moment you add a second currency, config-driven currency becomes a data-corruption bug — historical rows get reinterpreted under a new default.

API resources. Serialize money as a pair ({"amount": "1250.00", "currency": "EUR"}) or as integer minor units plus a currency code, never as a bare float. Consumers in JS will break on floats and you will not notice until a reconciliation fails.

Validation at the request layer. Pair a money validation rule with a FormRequest so malformed input never reaches the cast. This is the cheapest place to reject three-decimal input for a two-decimal currency.

Allocation over division. For splitting amounts (installments, proportional discounts), use the package's allocation helper rather than divide() — division leaves remainders that must be distributed, and hand-rolled remainder logic is where penny-drift bugs live.

Testing. Freeze the currency/locale config in your test base class and assert on minor units in feature tests. Add one test per currency you actually support; the failure mode of a money package is almost always a locale/currency mismatch, not arithmetic.

Gotchas and Tips

  • Empty changelog is a real risk, not a formality. alpha.7 → alpha.8 could contain a rename, a signature change, or a default flipped. Read the GitHub compare diff before upgrading, and pin the exact version in composer.json. Do not let CI resolve ^4.0.0-alpha.
  • Alpha stability. Do not build a payments or ledger path on a v4 alpha without a lockfile commit and a staging run. If you need stability today, evaluate whether v3 is sufficient for your use case and migrate deliberately once v4 is tagged stable.
  • Locale vs currency are independent. A EUR amount shown to a de locale and a en locale differ in separators and symbol position. If a formatted value looks wrong, check the locale before you check the arithmetic.
  • Rounding mode is a config quirk with teeth. Default rounding will surprise you on tax calculations and on currency conversion. Set it explicitly and test the half-cent boundary cases (0.005, 1.005 — the latter is a classic float-representation trap if the value ever passed through a float).
  • Never pass floats in. Anything originating from a request, a CSV, or a JSON payload should be parsed from a string. (float) anywhere upstream of the package reintroduces the bug the package exists to prevent.
  • Casts and dirty-checking. If a cast is not configured for the model's write path, mass assignment can store a formatted string into an integer column. Guard with $casts plus a DB column type that matches what the cast writes.
  • Debugging tip. When a total is off by one cent, dump the raw database value first, then the cast result, then the formatted output. The three-stage split localises the fault in one step.
  • Extension points. Currency and formatting behaviour are typically swappable through config or a bound interface — prefer overriding there over subclassing package classes, so alpha bumps do not break your subclasses.
  • Watch for the stable tag. Given the release-notes automation is producing empty bodies, subscribe to the repository's releases/commits rather than relying on changelogs to learn about breaking changes before you upgrade.
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style