marshmallow / priceable
Package for handeling prices
Requires
- php: ^8.0|^8.1
- laravel/nova: ^4.0|^5.0
- marshmallow/commands: ^1.0
- marshmallow/helpers: ^2.0
- marshmallow/sluggable: ^1.0
- moneyphp/money: ^v4.0.3
This package is auto-updated.
Last update: 2026-06-11 16:00:49 UTC
README
Laravel Priceable
Attach prices, currencies, VAT rates and price types to any Eloquent model. Priceable handles VAT calculation, multi-currency, discounts and validity periods, and ships ready-made Laravel Nova resources for managing it all.
Installation
Priceable depends on Laravel Nova, a paid package. Make sure the Nova Composer repository is configured and your credentials are set:
composer config repositories.nova composer https://nova.laravel.com composer config http-basic.nova.laravel.com "your-email" "your-license-key"
Install the package via Composer:
composer require marshmallow/priceable
Publish the config file:
php artisan vendor:publish --tag="config"
The migrations are loaded automatically by the package, so just run:
php artisan migrate
Seed the default currencies and VAT rates:
php artisan db:seed --class="Marshmallow\Priceable\Seeders\CurrencySeeder" php artisan db:seed --class="Marshmallow\Priceable\Seeders\VatRatesSeeder"
Configuration
config/priceable.php:
| Key | Default | Description |
|---|---|---|
detault_price_type |
1 |
The price type id used when a model doesn't ask for a specific one. |
currency |
env('CURRENCY', 'eur') |
Default currency code. |
currency_locale |
env('CURRENCY_LOCALE', 'nl') |
Locale used to format money. |
models |
Price, Currency, VatRate, PriceType |
Swap any model for your own implementation. |
resources |
Priceable Nova resources | Swap any Nova resource for your own. |
nova.prices_are_including_vat |
true |
Whether prices entered in Nova include VAT. |
nova.defaults.currencies |
1 |
Default currency id for new prices. |
nova.defaults.vat_rates |
2 |
Default VAT rate id for new prices. |
nova.resources |
[] |
Priceable models that Nova should expose. |
on_multiple_prices |
'lowest' |
Which price wins when a model has several: highest, lowest, eldest, newest. |
public_excluding_vat |
false |
Display prices excluding VAT on the front-end. |
observers.price |
PriceableObserver |
Observer that computes the VAT columns on save. |
Usage
Add the Priceable trait to any model you want to price:
use Illuminate\Database\Eloquent\Model; use Marshmallow\Priceable\Traits\Priceable; class Product extends Model { use Priceable; }
Attach a price (prices are polymorphic, so any priceable model works):
$product->prices()->create([ 'price_type_id' => config('priceable.detault_price_type'), 'currency_id' => 1, 'vatrate_id' => 2, 'display_price' => 19.95, 'valid_from' => now(), ]);
Read prices on the front-end:
$product->currentPrice(); // numeric price for the active currency & price type $product->price; // the resolved Price model (->price(), ->formatPrice(), ...) $product->price_formatted; // formatted string, e.g. "€ 19,95" $product->isDiscounted(); // true when multiple prices resolve to different amounts $product->discountedFrom(); // the highest price, to show a struck-through "from" price
Ask for a specific price type:
use Marshmallow\Priceable\Models\PriceType; $product->priceType(PriceType::find(2))->currentPrice();
Switching currency
The package registers a named set-currency route and request macros:
@foreach (\Marshmallow\Priceable\Models\Currency::get() as $currency) <a href="{{ route('set-currency', $currency) }}">{{ $currency->name }}</a> @endforeach
request()->getUserCurrency(); // the visitor's active currency request()->setUserCurrency($currency); // set it manually
Contributing
Pull requests are welcome. For larger changes, please open an issue first to discuss what you would like to change.
Security Vulnerabilities
Please report security vulnerabilities by email to stef@marshmallow.dev rather than via the public issue tracker.
Credits
License
The MIT License. Please see the License File for more information.