PHPackages                             jakubjachym/vat-calculator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. jakubjachym/vat-calculator

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

jakubjachym/vat-calculator
==========================

EU VAT calculation, the way it should be. Revived fork of spaze/vat-calculator which was a standalone &amp; modernized fork of mpociot/vat-calculator, with some new features.

v3.6.11(1y ago)04.0k↓37.5%MITPHPPHP ^7.3 || ^8.0

Since Dec 20Pushed 1y agoCompare

[ Source](https://github.com/JakubJachym/vat-calculator)[ Packagist](https://packagist.org/packages/jakubjachym/vat-calculator)[ RSS](/packages/jakubjachym-vat-calculator/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (6)Versions (7)Used By (0)

VatCalculator
=============

[](#vatcalculator)

[![Software License](https://camo.githubusercontent.com/9f5228f835d48a4c2394cc0a527af565480ad4f7a65cc7e9befa72861b2338b4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f4a616b75624a616368796d2f7661742d63616c63756c61746f72)](LICENSE.md)[![PHP Tests](https://github.com/JakubJachym/vat-calculator/workflows/PHP%20Tests/badge.svg)](https://github.com/JakubJachym/vat-calculator/actions?query=workflow%3A%22PHP+Tests%22)

Handle all the hard stuff related to EU MOSS tax/vat regulations, the way it should be. This is a revived fork of [spaze/vat-calculator](https://github.com/spaze/vat-calculator) which was a "modernized" fork of [mpociot/vat-calculator](https://github.com/mpociot/vat-calculator) without Laravel/Cashier support, with some new features, that requires PHP 7.3+.

```
// Easy to use!
use JakubJachym\VatCalculator\VatCalculator;

$vatRates = new VatRates();
$vatCalculator = new VatCalculator($vatRates);
$vatCalculator->calculate(71.00, 'DE' /* $countryCode */, '41352' /* $postalCode or null */,  true /* Whether the customer you're calculating the VAT for is a company */);
$vatCalculator->getTaxRateForLocation('NL');
// Check validity of a VAT number
$vatCalculator->isValidVatNumber('NL123456789B01');
```

Contents
--------

[](#contents)

- [Installation](#installation)
    - [Standalone](#installation-standalone)
- [Usage](#usage)
    - [Calculate the gross price](#calculate-the-gross-price)
    - [Validate EU VAT numbers](#validate-eu-vat-numbers)
    - [Get EU VAT number details](#vat-number-details)
    - [Get all known rates for a country](#all-known-rates)
    - [Countries](#countries)
- [License](#license)
- [Contributing](#contributing)
- [Disclaimer](#disclaimer)

Installation
------------

[](#installation)

In order to install the VAT Calculator, just run

```
$ composer require jakubjachym/vat-calculator
```

### Standalone

[](#standalone)

This package is designed for standalone usage. Simply create a new instance of the VAT calculator and use it.

Example:

```
use JakubJachym\VatCalculator\VatCalculator;

$vatRates = new VatRates();
$vatCalculator = new VatCalculator($vatRates);
$vatCalculator->setBusinessCountryCode('DE');  // Where your company is based in
$price = $vatCalculator->calculate(49.99, 'LU', null, false);
$price->getPrice();
$price->getNetPrice();
$price->getTaxValue();
$price->getTaxRate();
```

Usage
-----

[](#usage)

### Calculate the gross price

[](#calculate-the-gross-price)

To calculate the gross price (price with VAT added) use the `calculate` method with a net price, a country code, a postal code (null if unknown) and whether you're calculating VAT for a customer that's a company as parameters.

```
$grossPrice = $vatCalculator->calculate(24.00, 'DE', null, false /* [, $rateType [, $dateTime]] */);
```

The third parameter is the postal code of the customer, pass `null` if unknown.

As a fourth parameter, you can pass in a boolean indicating whether the customer is a company or a private person. If the customer is a company, which you should check by [validating the VAT number](#validate-eu-vat-numbers), the net price gets returned.

Fifth optional parameter defines which VAT rate to use if there are more defined for the particular country (`VatRates::HIGH`, `VatRates::LOW`, `VatRates::GENERAL` is the default when just one rate is defined).

The sixth parameter, optional, specifies the date to use the VAT rate for. This is needed when a country changes its VAT rate and you want to calculate a price with the previous rate. Pass `DateTime` or `DateTimeImmutable` object. Current date used when not specified.

Returns `VatPrice` object:

```
$grossPrice->getPrice();
$grossPrice->getNetPrice();
$grossPrice->getTaxValue();
$grossPrice->getTaxRate();
```

### Validate EU VAT numbers

[](#validate-eu-vat-numbers)

Prior to validating your customers VAT numbers, you can use the `shouldCollectVat` method to check if the country code requires you to collect VAT in the first place. This method will return `true` even for non-EU countries added manually with `addRateForCountry` (see below).

To ignore those manually added non-EU countries and return `true` only for EU member states, you can use `shouldCollectEuVat`.

```
if ($vatCalculator->shouldCollectVat('DE')) {

}

if ($vatCalculator->shouldCollectEuVat('DE')) {

}
```

To validate your customers VAT numbers, you can use the `isValidVatNumber` method. The VAT number should be in a format specified by the [VIES](https://ec.europa.eu/taxation_customs/vies/faqvies.do#item_11). The given VAT numbers will be truncated and non relevant characters (`-`, `.`, `,`, whitespace) will automatically be removed. If there are any invalid characters left, like non-latin letters for example, `InvalidCharsInVatNumberException` will be thrown.

This service relies on a third party SOAP API provided by the EU. If, for whatever reason, this API is unavailable a `VatCheckUnavailableException` will be thrown.

If a VAT number from an unsupported/non-EU country is provided, `UnsupportedCountryException` will be thrown.

```
try {
	$validVat = $vatCalculator->isValidVatNumber('NL 123456789 B01');
} catch (VatCheckUnavailableException $e) {
	// Please handle me
}
```

### Get EU VAT number details

[](#get-eu-vat-number-details)

To get the details of a VAT number, you can use the `getVatDetails` method. The VAT number should be in a format specified by the [VIES](https://ec.europa.eu/taxation_customs/vies/faqvies.do#item_11). The given VAT numbers will be truncated and non relevant characters / whitespace will automatically be removed.

This service relies on a third party SOAP API provided by the EU. If, for whatever reason, this API is unavailable a `VatCheckUnavailableException` will be thrown.

If a VAT number from an unsupported/non-EU country is provided, `UnsupportedCountryException` will be thrown.

```
try {
	$vat_details = $vatCalculator->getVatDetails('NL 123456789 B01');
	print_r($vat_details);
	/* Outputs VatDetails object, use getters to access values
	VatDetails Object
	(
		[valid:VatDetails:private] => false
		[countryCode:VatDetails:private] => NL
		[vatNumber:VatDetails:private] => 123456789B01
		[requestId:VatDetails:private] => FOOBAR338
	)
	*/
} catch (VatCheckUnavailableException $e) {
	// Please handle me
}
```

### Get all known rates for a country

[](#get-all-known-rates-for-a-country)

Get all known rates (current, high &amp; low, historical &amp; future, exceptions) for a country by:

```
$vatRates = new VatRates();
$vatRates->getAllKnownRates('DE');
```

The returned array of rates is unsorted. This method can be useful when you want to prefill a selectbox with known VAT rates for a country for example, or when you want to validate user-provided rates.

Countries
---------

[](#countries)

EU countries are supported as well as some non-EU countries that use VAT. Some countries are not supported even though they also have VAT. Currently, that's the case for the following countries:

- Switzerland (CH)
- United Kingdom (GB)
- Norway (NO)
- Turkey (TR)

These can be added manually with `VatRates::addRateForCountry()`:

```
$vatRates = new VatRates();
$vatRates->addRateForCountry('NO');
$vatCalculator = new VatCalculator($vatRates);
```

Please keep in mind that with these countries you cannot validate VAT ids with `isValidVatNumber()` because it uses VIES, the EU VAT number validation service, and as these countries are not part of the EU, it will always come back as invalid.

License
-------

[](#license)

This library is licensed under the MIT license. Please see [License file](LICENSE.md) for more information.

Contributing
------------

[](#contributing)

Run PHPUnit tests and static analysis with `composer test`, see `scripts` in `composer.json`. Tests are also run on GitHub with Actions on each push.

Disclaimer
----------

[](#disclaimer)

While this repository tries to provide up-to-date VAT rates, it is possible that it will fail to do so. Please keep in mind that author cannot be held responsible for any damage done to you or anyone for using this repository. It is your responsibility to check that used VAT rate is valid.

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity22

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~89 days

Total

5

Last Release

523d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d2e99b8c5ab56038c6bae8d6bbddd986bf8d3f670a7862409baa4bb8dadf5da3?d=identicon)[jakubjachym](/maintainers/jakubjachym)

---

Top Contributors

[![spaze](https://avatars.githubusercontent.com/u/1966648?v=4)](https://github.com/spaze "spaze (101 commits)")[![mpociot](https://avatars.githubusercontent.com/u/804684?v=4)](https://github.com/mpociot "mpociot (99 commits)")[![JakubJachym](https://avatars.githubusercontent.com/u/3509811?v=4)](https://github.com/JakubJachym "JakubJachym (36 commits)")[![michellaurent](https://avatars.githubusercontent.com/u/1630290?v=4)](https://github.com/michellaurent "michellaurent (3 commits)")[![galexth](https://avatars.githubusercontent.com/u/10194439?v=4)](https://github.com/galexth "galexth (3 commits)")[![netpok](https://avatars.githubusercontent.com/u/6945600?v=4)](https://github.com/netpok "netpok (2 commits)")[![lanort](https://avatars.githubusercontent.com/u/57423?v=4)](https://github.com/lanort "lanort (2 commits)")[![iruoy](https://avatars.githubusercontent.com/u/5859352?v=4)](https://github.com/iruoy "iruoy (2 commits)")[![mrk-j](https://avatars.githubusercontent.com/u/1250622?v=4)](https://github.com/mrk-j "mrk-j (2 commits)")[![webcraft](https://avatars.githubusercontent.com/u/56675?v=4)](https://github.com/webcraft "webcraft (2 commits)")[![orottier](https://avatars.githubusercontent.com/u/5442615?v=4)](https://github.com/orottier "orottier (2 commits)")[![webdevvie](https://avatars.githubusercontent.com/u/6097722?v=4)](https://github.com/webdevvie "webdevvie (1 commits)")[![driesvints](https://avatars.githubusercontent.com/u/594614?v=4)](https://github.com/driesvints "driesvints (1 commits)")[![kduma](https://avatars.githubusercontent.com/u/1062582?v=4)](https://github.com/kduma "kduma (1 commits)")[![kitbs](https://avatars.githubusercontent.com/u/4569320?v=4)](https://github.com/kitbs "kitbs (1 commits)")[![krizzdev](https://avatars.githubusercontent.com/u/5312693?v=4)](https://github.com/krizzdev "krizzdev (1 commits)")[![lsimeonov](https://avatars.githubusercontent.com/u/17702047?v=4)](https://github.com/lsimeonov "lsimeonov (1 commits)")[![NSpehler](https://avatars.githubusercontent.com/u/379186?v=4)](https://github.com/NSpehler "NSpehler (1 commits)")[![pascalbaljet](https://avatars.githubusercontent.com/u/8403149?v=4)](https://github.com/pascalbaljet "pascalbaljet (1 commits)")[![rossbearman](https://avatars.githubusercontent.com/u/212036?v=4)](https://github.com/rossbearman "rossbearman (1 commits)")

---

Tags

vattaxtax calculationEU Mossvat calculationVAT ID

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/jakubjachym-vat-calculator/health.svg)

```
[![Health](https://phpackages.com/badges/jakubjachym-vat-calculator/health.svg)](https://phpackages.com/packages/jakubjachym-vat-calculator)
```

###  Alternatives

[mpociot/vat-calculator

EU VAT calculation, the way it should be.

1.3k3.9M18](/packages/mpociot-vat-calculator)[commerceguys/tax

Tax library with a flexible data model, predefined tax rates, powerful resolving logic.

286763.3k](/packages/commerceguys-tax)[omaralalwi/laravel-taxify

Laravel Taxify provides a set of helper functions and classes to simplify tax (VAT) calculations within Laravel applications. that allow developers to easily integrate tax calculation functionalities into their projects. it's offers a straightforward and efficient solution Designed to streamline the process of handling taxes.

471.7k](/packages/omaralalwi-laravel-taxify)[ibericode/vat-bundle

Bundle for using ibericode/vat in a Symfony environment

21254.5k](/packages/ibericode-vat-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
