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

Money Casts Laravel Laravel Package

brokeyourbike/money-casts-laravel

Laravel Eloquent casts for monetary values that convert database amounts into Money objects and back, keeping currency handling clean and consistent across your models.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with Composer: composer require brokeyourbike/money-casts-laravel. The package is a thin Laravel integration around moneyphp/money, so expect that dependency to come along with it.
  • Requirements to confirm before adopting: a supported PHP version (8.x), a supported Laravel version, and a moneyphp/money constraint compatible with your app.
  • Look first at the package README and the src/ cast classes — typically MoneyCast and CurrencyCast. Those are the only public surface you interact with day to day.
  • First use case: cast an integer minor-unit column to a Money object on an Eloquent model, sourcing the currency from either a fixed code or another column.
use BrokeYourBike\MoneyCasts\MoneyCast;

class Order extends Model
{
    protected $casts = [
        'total' => MoneyCast::class.':currency', // currency column
        // or: MoneyCast::class.':USD'           // fixed currency
    ];
}

After that, $order->total is a Money\Money instance; $order->total->getAmount() returns the minor-unit string and $order->total->getCurrency()->getCode() returns the ISO code.

Implementation Patterns

  • Single-currency models — pass the currency code directly as the cast parameter (MoneyCast::class.':USD'). Good for domestic-only tables where a currency column would be redundant.
  • Multi-currency models — pass the name of the currency column (MoneyCast::class.':currency'). Keep that column as char(3) with an ISO 4217 code and make it non-nullable.
  • Currency-only columns — use CurrencyCast where you store just a currency code and want a Money\Currency object instead of a string.
  • Storage convention — store amounts as bigInteger minor units (cents) and currency as char(3). This is the least surprising layout and matches how moneyphp/money represents amounts.
  • Writing values — assign a Money instance to the attribute where possible. If you accept scalars in forms, convert to Money in a form request or model mutator before assignment, and verify the cast’s set behavior with a test.
  • Querying — casts only affect hydration. where('total', ...) still compares against the raw column, so query in minor units, not in formatted decimals.
  • API output — expose getAmount() and the currency code explicitly, or format with moneyphp/money formatters (DecimalMoneyFormatter, IntlMoneyFormatter) in a resource class rather than relying on default model serialization.
  • Validation — validate currency as string|size:3 (optionally in: a supported list) and amounts as integers in minor units. Reject floats at the boundary.
  • Testing — assert assertInstanceOf(Money::class, $model->total) and compare with $money->equals($other). Factories should create integer amounts.
  • Migrations — $table->bigInteger('total'); $table->char('currency', 3); keeps the cast’s assumptions explicit.

Gotchas and Tips

  • Immutability — Money is immutable. $model->total->add($x) returns a new instance and does nothing to the model; reassign it explicitly.
  • Don’t cast to float — (float) $money->getAmount() or storing decimals loses precision and introduces off-by-100 errors. Work in minor units and format only at the edges.
  • Compare with equals() — == on Money objects can mislead; use $a->equals($b).
  • Null currency columns — if the currency attribute is null or not loaded, the cast will fail when hydrating. Add a DB default, make it non-nullable, and guard against partially selected columns (select('total') without currency).
  • Mass assignment / updates — casts are reliable on read, but write behavior depends on the cast’s set implementation. Cover create/update paths with tests before relying on scalar assignment.
  • Serialization surprises — toArray()/toJson() will include the Money object unless you customize it. Use API resources or accessors so responses stay predictable.
  • Select clauses — always include the currency column when the cast depends on it, including in eager-loaded relations and raw DB::select hydration paths.
  • Version constraints — the package is a thin wrapper; when upgrading Laravel or PHP, check the moneyphp/money constraint at the same time.
  • Extension points — if your storage format differs (e.g. decimal strings), implement your own CastsAttributes using moneyphp/money rather than fighting the provided cast.
  • v1.0.4 — patch release only: homepage metadata fix and badge chores. No API changes, no deprecations, no migration steps. Safe to bump with composer update brokeyourbike/money-casts-laravel; pin to ^1.0.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager