omaralalwi/laravel-taxify
Laravel Taxify adds flexible tax calculation to Laravel apps. Define tax rates, apply inclusive or exclusive taxes to prices, and compute totals for carts, invoices, and orders through a clean, configurable API. Supports multiple rates and jurisdictions.
composer require omaralalwi/laravel-taxify, then publish the config with php artisan vendor:publish --tag=taxify-config (confirm the exact tag/provider in the README for your pinned version). The package auto-discovers its service provider on Laravel 9+; older apps need the provider registered in config/app.php.config/taxify.php. That file is the whole mental model: default rate, tax classes/rate definitions, and the rounding/precision setting that the recent releases keep refining. If the config keys don't match the README, trust the installed config file — the package has moved fast across 2.x.TaxCalculator/PricingService, then have that service return a small value object (TaxBreakdown with net, tax, gross, rate). This keeps rounding policy in one place and makes it swappable in tests.tax_rate, tax_amount, and tax_inclusive on order lines at write time so a config change or upgrade never restates a historical invoice.gross - (gross / (1 + rate)), and for exclusive it's net * rate. Don't infer the mode from context — pass it, otherwise cart previews and final invoices drift apart.TaxRateResolver interface (country → zone → class → rate) backed by config or a DB table keeps multi-region logic out of controllers and makes it trivial to add a new jurisdiction.setUp()/php artisan config:cache-free test env. Assert on integer minor units (cents) rather than floats to avoid brittle assertions.number_format and currency symbols.php artisan config:cache is mandatory in production. Rate changes in config/taxify.php silently do nothing on a cached deploy until you re-cache. Add it to your deploy script and your "tax rate is wrong" runbook.config('taxify')) and the rate the resolver returned for the failing case. Nine times out of ten the bug is a stale config cache, a missing rate for the buyer's zone, or a mismatched inclusive/exclusive flag — not the math.How can I help you explore Laravel packages today?