Skip to main content

Overview

Laravel Brick Money provides custom Livewire synthesizers that enable you to use Money and Currency objects as public properties in your Livewire components. The synthesizers handle serialization and deserialization automatically.

Installation

Livewire support is included out of the box. The synthesizers are automatically registered when you install the package.

Using Money in Livewire

Basic Usage

You can use Money objects as public properties in your Livewire components:
use Devhammed\LaravelBrickMoney\Money;
use Livewire\Component;

class ProductPrice extends Component
{
    public Money $price;
    
    public function mount()
    {
        $this->price = Money::of(99.99, 'USD');
    }
    
    public function increasePrice()
    {
        $this->price = $this->price->plus(10);
    }
    
    public function render()
    {
        return view('livewire.product-price');
    }
}
Product Price Component
<div>
    <h2>Current Price: {{ $price->format() }}</h2>
    <button wire:click="increasePrice">Increase by $10</button>
</div>

Wire Model Binding

You can bind to specific properties of Money objects:
use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Currency;
use Livewire\Component;

class PriceEditor extends Component
{
    public Money $price;
    
    public function mount()
    {
        $this->price = Money::of(0, 'USD');
    }
    
    public function render()
    {
        return view('livewire.price-editor');
    }
}
Price Editor View
<div>
    <input 
        type="text" 
        wire:model="price.amount" 
        placeholder="Enter amount"
    />
    
    <select wire:model="price.currency">
        <option value="USD">USD</option>
        <option value="EUR">EUR</option>
        <option value="GBP">GBP</option>
    </select>
    
    <p>Formatted: {{ $price->format() }}</p>
</div>

Using Currency in Livewire

Basic Usage

use Devhammed\LaravelBrickMoney\Currency;
use Livewire\Component;

class CurrencySelector extends Component
{
    public Currency $currency;
    
    public function mount()
    {
        $this->currency = Currency::of('USD');
    }
    
    public function changeCurrency(string $code)
    {
        $this->currency = Currency::of($code);
    }
    
    public function render()
    {
        return view('livewire.currency-selector');
    }
}
Currency Selector View
<div>
    <h3>Selected Currency: {{ $currency->getName() }}</h3>
    <p>Symbol: {{ $currency->getSymbol() }}</p>
    
    <select wire:model="currency.code">
        <option value="USD">US Dollar</option>
        <option value="EUR">Euro</option>
        <option value="GBP">British Pound</option>
    </select>
</div>

How Synthesizers Work

Money Synthesizer

The MoneySynthesizer handles serialization of Money objects:
Dehydrated format:
[
    'amount' => '100.00',
    'currency' => 'USD',
    'context' => ['default', []]
]
The synthesizer preserves:
  • The exact amount as a string (no precision loss)
  • The currency code
  • The context type (DefaultContext, CustomContext, CashContext, or AutoContext)

Currency Synthesizer

The CurrencySynthesizer is simpler:
Dehydrated format: 'USD'

Context Support

The Money synthesizer supports all Brick Money context types:
public Money $price;

public function mount()
{
    $this->price = Money::of(100, 'USD');
    // Uses DefaultContext automatically
}

Practical Examples

Shopping Cart Component

use Devhammed\LaravelBrickMoney\Money;
use Livewire\Component;

class ShoppingCart extends Component
{
    public array $items = [];
    public Money $total;
    public Money $tax;
    
    public function mount()
    {
        $this->calculateTotals();
    }
    
    public function addItem(int $productId, Money $price, int $quantity = 1)
    {
        $this->items[] = [
            'id' => $productId,
            'price' => $price,
            'quantity' => $quantity,
        ];
        
        $this->calculateTotals();
    }
    
    public function removeItem(int $index)
    {
        unset($this->items[$index]);
        $this->items = array_values($this->items);
        $this->calculateTotals();
    }
    
    private function calculateTotals()
    {
        $this->total = Money::of(0, 'USD');
        
        foreach ($this->items as $item) {
            $lineTotal = $item['price']->multipliedBy($item['quantity']);
            $this->total = $this->total->plus($lineTotal);
        }
        
        // Calculate 10% tax
        $this->tax = $this->total->multipliedBy(0.1);
    }
    
    public function render()
    {
        return view('livewire.shopping-cart');
    }
}
Shopping Cart View
<div>
    <h2>Shopping Cart</h2>
    
    @foreach($items as $index => $item)
        <div class="cart-item">
            <span>{{ $item['price']->format() }} x {{ $item['quantity'] }}</span>
            <button wire:click="removeItem({{ $index }})">Remove</button>
        </div>
    @endforeach
    
    <div class="totals">
        <p>Subtotal: {{ $total->format() }}</p>
        <p>Tax: {{ $tax->format() }}</p>
        <p><strong>Total: {{ $total->plus($tax)->format() }}</strong></p>
    </div>
</div>

Price Calculator

use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Currency;
use Livewire\Component;

class PriceCalculator extends Component
{
    public Money $basePrice;
    public float $markup = 0;
    public float $discount = 0;
    public Currency $currency;
    
    public function mount()
    {
        $this->currency = Currency::of('USD');
        $this->basePrice = Money::of(100, $this->currency);
    }
    
    public function updatedCurrency($value)
    {
        $this->currency = Currency::of($value);
        $this->basePrice = Money::of(
            $this->basePrice->getAmount(), 
            $this->currency
        );
    }
    
    public function getFinalPriceProperty(): Money
    {
        $price = $this->basePrice;
        
        // Apply markup
        if ($this->markup > 0) {
            $markupAmount = $price->multipliedBy($this->markup / 100);
            $price = $price->plus($markupAmount);
        }
        
        // Apply discount
        if ($this->discount > 0) {
            $discountAmount = $price->multipliedBy($this->discount / 100);
            $price = $price->minus($discountAmount);
        }
        
        return $price;
    }
    
    public function render()
    {
        return view('livewire.price-calculator');
    }
}
Computed properties like getFinalPriceProperty() work seamlessly with Money objects. Just return a Money instance and Livewire will handle serialization automatically.

Validation

You can validate Money and Currency properties using Livewire’s validation:
use Devhammed\LaravelBrickMoney\Rules\MoneyRule;
use Devhammed\LaravelBrickMoney\Rules\CurrencyRule;

class ProductForm extends Component
{
    public Money $price;
    public Currency $currency;
    
    public function rules()
    {
        return [
            'price.amount' => ['required', new MoneyRule(min: 0, max: 10000)],
            'currency.code' => ['required', new CurrencyRule()],
        ];
    }
    
    public function save()
    {
        $this->validate();
        
        // Save product with validated price and currency
    }
}
The synthesizers handle property access automatically, so $this->price->amount works in wire:model bindings and validation rules.

Troubleshooting

Make sure you’re reassigning the property rather than mutating it:
// Wrong - Money is immutable
$this->price->plus(10);

// Correct
$this->price = $this->price->plus(10);
When performing operations between Money objects, ensure they use the same currency:
// This will throw an exception
$usd = Money::of(100, 'USD');
$eur = Money::of(100, 'EUR');
$total = $usd->plus($eur); // Error!

// Convert first
$eurAsUsd = $eur->convertedTo('USD', 1.08);
$total = $usd->plus($eurAsUsd); // Works!
The synthesizer preserves the context type, but custom context parameters must be serializable. Stick to DefaultContext for most use cases:
// Simple and reliable
$this->price = Money::of(100, 'USD');

Next Steps

Formatting

Learn about advanced formatting options

Validation

Explore validation rules for Money and Currency

Build docs developers (and LLMs) love