Custom VAT handler
This page is for developers whose VAT rules cannot be expressed with VAT rules by country and product category. The shop asks a VAT handler for the percentage of each product with dynamic VAT; you can write your own handler and keep everything else.
Contents
When you need one
| Situation | Default handler enough? |
|---|---|
| Rate by customer country and product category | Yes (Product categories and VAT rules) |
| A different rate for business customers with a valid VAT number | No |
| The rate depends on the delivery address rather than the account country | No |
| Rates come from an external tax service | No |
The tax rules themselves are for your tax adviser; the handler only implements what you decide.
The contract
eZVATManager::getVAT( $object, $country ) (kernel/classes/ezvatmanager.php) loads the handler and calls:
function getVatPercent( $object, $country )| Argument | Meaning |
|---|---|
$object | The product's content object |
$country | The customer's country code, or false when unknown |
Return the percentage as a number. Returning null marks the VAT as unknown. The handler is only asked for products
whose price uses the dynamic VAT type; products with a fixed VAT type keep it.
Registering it
# extension/mystore_shop/settings/shop.ini.append.php
[VATSettings]
Handler=mystore
ExtensionDirectories[]=mystore_shop
RequireUserCountry=falseThe class mystoreVATHandler goes in extension/mystore_shop/vathandlers/mystorevathandler.php. Set
RequireUserCountry=false only if your handler does not need the country; the shipped comment says so too
(shop.ini walkthrough).
Building on the default handler
Extending eZDefaultVATHandler (kernel/classes/vathandlers/ezdefaultvathandler.php) keeps the rule-based decision and
lets you handle one exception first:
class mystoreVATHandler extends eZDefaultVATHandler
{
function getVatPercent( $object, $country )
{
if ( $this->isBusinessCustomerWithValidNumber() )
{
return 0;
}
return parent::getVatPercent( $object, $country );
}
}isBusinessCustomerWithValidNumber() is yours to write; where the VAT number comes from (an account field, the checkout
form of your shop account handler) is your design. The RAD handler wizard has a VAT handler recipe that writes this
skeleton (Developer path).
Testing
- To do: Unit tests of
getVatPercent()for every case you implement. - To do: A test order per case; the confirmation page, order and mail agree.
- To do: Unknown country: the result is what you intend, not an accidental 0.
- To do: The Store dashboard shows no unexpected 0 percent warning.
Related pages
- Extending the shop
- VAT rules and VAT types
- VAT checklist
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.