The AsIntegerMoney cast stores monetary values in their minor units (e.g., cents for USD, pence for GBP). This is the recommended approach for handling money in databases as it avoids floating-point precision issues.
Why integers? Storing $10.00 as 1000 cents instead of 10.00 ensures exact arithmetic. This is the standard practice in financial applications.
How It Works
The cast automatically converts between Money objects in your PHP code and integer values in your database:
Storage : Money::of(10.00, 'USD') → 1000 (stored as integer)
Retrieval : 1000 → Money::ofMinor(1000, 'USD') (Money object)
Implementation
The AsIntegerMoney class uses the AsMoneyCast trait and implements two key methods:
protected function serializeMoney ( Money $value ) : string
{
return ( string ) $value -> getMinorAmount ();
}
protected function deserializeMoney ( float | int | string $amount , string $currency ) : Money
{
return Money :: ofMinor ( $amount , $currency );
}
Usage Patterns
Separate Columns
JSON Column
Custom Column Names
Store amount and currency in separate columns for better queryability. Model Definition use Devhammed\LaravelBrickMoney\ Money ;
use Devhammed\LaravelBrickMoney\Casts\ AsIntegerMoney ;
use Illuminate\Database\Eloquent\ Model ;
/**
* @property Money $amount
* @property string $currency
*/
class Transaction extends Model
{
protected function casts () : array
{
return [
'amount' => AsIntegerMoney :: of ( 'currency' ),
];
}
}
Migration use Illuminate\Database\Schema\ Blueprint ;
use Illuminate\Support\Facades\ Schema ;
Schema :: create ( 'transactions' , function ( Blueprint $table ) {
$table -> id ();
$table -> bigInteger ( 'amount' ); // e.g., 1000 = $10.00
$table -> string ( 'currency' , 3 ); // e.g., 'USD'
$table -> timestamps ();
});
Usage Example // Create
$transaction = Transaction :: create ([
'amount' => Money :: of ( 10.00 , 'USD' ),
]);
// The database stores:
// amount: 1000
// currency: "USD"
// Retrieve
$transaction = Transaction :: find ( 1 );
echo $transaction -> amount -> format (); // "$10.00"
echo $transaction -> currency ; // "USD"
The currency column is automatically populated when you set the amount.
Store both amount and currency in a single JSON column. Model Definition use Devhammed\LaravelBrickMoney\ Money ;
use Devhammed\LaravelBrickMoney\Casts\ AsIntegerMoney ;
use Illuminate\Database\Eloquent\ Model ;
/**
* @property Money $price
*/
class Product extends Model
{
protected function casts () : array
{
return [
'price' => AsIntegerMoney :: class ,
];
}
}
Migration use Illuminate\Database\Schema\ Blueprint ;
use Illuminate\Support\Facades\ Schema ;
Schema :: create ( 'products' , function ( Blueprint $table ) {
$table -> id ();
$table -> json ( 'price' ); // {"amount": "1000", "currency": "USD"}
$table -> timestamps ();
});
Usage Example // Create
$product = Product :: create ([
'price' => Money :: of ( 10.00 , 'USD' ),
]);
// The database stores:
// price: {"amount": "1000", "currency": "USD"}
// Retrieve
$product = Product :: find ( 1 );
echo $product -> price -> format (); // "$10.00"
Specify custom column names for amount and currency. Model Definition use Devhammed\LaravelBrickMoney\ Money ;
use Devhammed\LaravelBrickMoney\Casts\ AsIntegerMoney ;
use Illuminate\Database\Eloquent\ Model ;
/**
* @property Money $total
*/
class Invoice extends Model
{
protected function casts () : array
{
return [
'total' => AsIntegerMoney :: of ( 'total_currency' , 'total_amount' ),
];
}
}
Migration Schema :: create ( 'invoices' , function ( Blueprint $table ) {
$table -> id ();
$table -> bigInteger ( 'total_amount' );
$table -> string ( 'total_currency' , 3 );
$table -> timestamps ();
});
The of() method signature: of(string $currencyColumn, ?string $amountColumn = null)
Cryptocurrency Support
Some cryptocurrencies have very high precision (e.g., Ethereum uses 18 decimal places). For these cases, the stored integer can exceed the BIGINT limit.
For high-precision cryptocurrencies , use string columns instead of bigInteger to avoid overflow:Schema :: create ( 'crypto_transactions' , function ( Blueprint $table ) {
$table -> id ();
$table -> string ( 'amount' ); // Can store very large numbers
$table -> string ( 'currency' , 10 );
$table -> timestamps ();
});
Example with Ethereum
use Devhammed\LaravelBrickMoney\ Money ;
// 1 ETH = 1,000,000,000,000,000,000 wei (18 decimals)
$transaction = CryptoTransaction :: create ([
'amount' => Money :: of ( 1 , 'ETH' ),
]);
// Database stores: "1000000000000000000"
Complete Example
Here’s a full example showing common operations:
use Devhammed\LaravelBrickMoney\ Money ;
use Devhammed\LaravelBrickMoney\Casts\ AsIntegerMoney ;
use Illuminate\Database\Eloquent\ Model ;
class Order extends Model
{
protected function casts () : array
{
return [
'subtotal' => AsIntegerMoney :: of ( 'currency' ),
'tax' => AsIntegerMoney :: of ( 'currency' ),
'total' => AsIntegerMoney :: of ( 'currency' ),
];
}
public function calculateTotal () : void
{
$this -> total = $this -> subtotal -> plus ( $this -> tax );
}
}
Querying
Since amounts are stored as integers, you can query them directly:
// Find orders over $100 (10000 cents)
$expensiveOrders = Order :: where ( 'total' , '>' , 10000 ) -> get ();
// Find orders between $50 and $200
$midRangeOrders = Order :: whereBetween ( 'total' , [ 5000 , 20000 ]) -> get ();
// Sum all orders in USD
$totalRevenue = Order :: where ( 'currency' , 'USD' ) -> sum ( 'total' );
echo Money :: ofMinor ( $totalRevenue , 'USD' ) -> format ();
Remember to convert your query amounts to minor units when comparing!
Best Practices
Always use separate columns for queryability
Separate columns allow you to filter, sort, and aggregate by amount or currency. 'amount' => AsIntegerMoney :: of ( 'currency' ) // ✅ Recommended
'amount' => AsIntegerMoney :: class // ⚠️ Less flexible
Use string columns for high-precision currencies
Cryptocurrencies and some exotic currencies may need larger storage. $table -> string ( 'amount' ); // For crypto
$table -> bigInteger ( 'amount' ); // For standard currencies
Add database indexes for frequently queried columns
$table -> bigInteger ( 'amount' ) -> index ();
$table -> string ( 'currency' , 3 ) -> index ();
Document property types in PHPDoc
/**
* @property Money $amount
* @property string $currency
*/
class Transaction extends Model { }
Advantages
Precision No floating-point errors - perfect for financial calculations
Storage Efficiency Integers are more compact than decimals
Query Performance Integer comparisons are faster than decimal
Industry Standard Used by Stripe, PayPal, and major payment processors
Next Steps
AsDecimalMoney Cast Learn about decimal-based storage
AsCurrency Cast Cast currency codes to objects