sylius/taxation
Sylius Taxation Component provides core models and extensible tax calculators to handle taxes for different items, zones, and tax rates in PHP applications. Part of the Sylius eCommerce ecosystem, designed for easy integration and customization.
Installation:
composer require sylius/taxation
Add the service provider to config/app.php:
Sylius\Taxation\TaxationServiceProvider::class,
First Use Case: Define a basic tax category and rate:
use Sylius\Taxation\Model\TaxCategoryInterface;
use Sylius\Taxation\Model\TaxRateInterface;
// Create a tax category (e.g., "Standard")
$taxCategory = new TaxCategory();
$taxCategory->setName('Standard');
// Create a tax rate (e.g., 20% VAT for a specific zone)
$taxRate = new TaxRate();
$taxRate->setName('VAT 20%');
$taxRate->setRate(20.0); // 20%
$taxRate->setCategory($taxCategory);
$taxRate->setZone('EU'); // Define your zone logic (e.g., country code)
Calculate Tax:
use Sylius\Taxation\Calculator\TaxItemsCalculatorInterface;
$calculator = app()->make(TaxItemsCalculatorInterface::class);
$taxItems = $calculator->calculate($orderItems, $taxRate);
Key Classes to Explore:
TaxCategory: Groups taxable items.TaxRate: Defines the tax percentage and applicable zones.TaxItem: Represents a taxable line item in an order.TaxItemsCalculator: Core logic for tax calculation.Tax Category Assignment: Assign tax categories to products or product variants:
$product->setTaxCategory($taxCategory);
Useful for differentiating taxable items (e.g., digital vs. physical goods).
Zone-Based Taxation: Implement zone logic (e.g., country/region) to apply rates dynamically:
$taxRate->setZone('US-CA'); // State-level taxation
Extend ZoneInterface or use existing implementations like CountryZone.
Order-Level Calculation: Calculate taxes for an entire order:
$orderTaxItems = $calculator->calculate($order->getItems(), $taxRates);
$order->setTaxTotal($orderTaxItems->getTotal());
Custom Calculators:
Extend TaxItemsCalculator for business-specific rules (e.g., tiered pricing):
class CustomTaxCalculator implements TaxItemsCalculatorInterface {
public function calculate(array $items, TaxRateInterface $taxRate): TaxItemsCollectionInterface {
// Custom logic here
}
}
Integration with Sylius Ecosystem:
sylius/resource for admin CRUD of tax categories/rates.sylius/order to auto-calculate taxes during checkout.TaxItemsCalculator in unit tests to isolate tax logic.Zone Logic:
CustomerZoneProvider).setZone() accepts ISO codes without validation.Tax Category Inheritance:
NestedSet) if hierarchical rules are needed.Floating-Point Precision:
bcmath or round to 2 decimal places:
$taxRate->setRate(round($rate, 2));
Order Item Taxability:
$orderItem->setTaxable(true);
Log Tax Calculations:
$calculator->calculate($items, $taxRate, ['debug' => true]);
(Extend TaxItemsCalculator to support debug mode.)
Validate Tax Rates: Ensure rates are positive and zones are non-empty:
if ($taxRate->getRate() <= 0) {
throw new \InvalidArgumentException('Tax rate must be positive.');
}
Custom Calculators:
Override TaxItemsCalculator to support:
Tax Rate Providers:
Implement TaxRateProviderInterface to fetch rates dynamically (e.g., from an API):
class ApiTaxRateProvider implements TaxRateProviderInterface {
public function getTaxRateForItem(TaxableInterface $item): ?TaxRateInterface {
// Fetch from external API
}
}
Event Listeners:
Listen to sylius.taxation.calculate events to modify calculations:
event(new TaxCalculationEvent($items, $taxRate, $taxItems));
Default Tax Rate:
The package doesn’t enforce a default rate. Define one in your config/packages/sylius_taxation.yaml:
sylius_taxation:
default_tax_rate: 'default_rate_id'
Database Schema:
Ensure your tax_category and tax_rate tables include:
code (for unique identification).created_at/updated_at (for auditing).How can I help you explore Laravel packages today?