Published on Mar 17, 2014, updated on Jul 24, 2025

EU VAT Validator

EU VAT validator class. Enter valid EU VAT number and click "Validate".

Note, that provided validation is not sufficient and does NOT guarantee that the verified VAT number really exists. For that purpose you can use online service ie. VAT checker or VIES VAT number validation. For automated verification are available paid services, such as viesapi.eu.

Example: valid EU VAT numbers are e.g. ATU99999999 or LU12345678

More EU VAT examples


/**
* Class to validate EU VAT number
* Based on JS validator by John Gardner:
* http://www.braemoor.co.uk/software/vat.shtml
*/
class EuVatValidator
{
	/**
	* @param string $vat Taxation ID, e.g. ATU99999999 for Austria
	* @return bool TRUE if supplied tax ID is valid for supplied country
	*/
	public static function isValid($vat)
	{
		$vat = preg_replace('/[ -,.]/', '', (string) $vat);
		$vat = strtoupper($vat);

		if (strlen($vat) < 8) {
			return false;
		}

		$country = substr($vat, 0, 2);

		switch ($country) {
			case 'AT': // AUSTRIA
				$isValid = (bool) preg_match('/^(AT)U(\d{8})$/', $vat);
				break;
			case 'BE': // BELGIUM
				$isValid = (bool) preg_match('/^(BE)(0|1)(\d{9})$/', $vat);
				break;
			case 'BG': // BULGARIA
				$isValid = (bool) preg_match('/^(BG)(\d{9,10})$/', $vat);
				break;
			case 'CH': // Switzerland
				$isValid = (bool) preg_match('/^(CHE)(\d{9})(MWST)?$/', $vat);
				break;
			case 'CY': // CYPRUS
				$isValid = (bool) preg_match('/^(CY)([0-5|9]\d{7}[A-Z])$/', $vat);
				break;
			case 'CZ': // CZECH REPUBLIC
				$isValid = (bool) preg_match('/^(CZ)(\d{8,10})(\d{3})?$/', $vat);
				break;
			case 'DE': // GERMANY
				$isValid = (bool) preg_match('/^(DE)([1-9]\d{8})/', $vat);
				break;
			case 'DK': // DENMARK
				$isValid = (bool) preg_match('/^(DK)(\d{8})$/', $vat);
				break;
			case 'EE': // ESTONIA
				$isValid = (bool) preg_match('/^(EE)(10\d{7})$/', $vat);
				break;
			case 'EL': // GREECE
				$isValid = (bool) preg_match('/^(EL)(\d{9})$/', $vat);
				break;
			case 'ES': // SPAIN
				$isValid = (bool) preg_match('/^(ES)([A-Z]\d{8})$/', $vat)
					|| preg_match('/^(ES)([A-H|N-S|W]\d{7}[A-J])$/', $vat)
					|| preg_match('/^(ES)([0-9|Y|Z]\d{7}[A-Z])$/', $vat)
					|| preg_match('/^(ES)([K|L|M|X]\d{7}[A-Z])$/', $vat);
				break;
			case 'EU': // EU type
				$isValid = (bool) preg_match('/^(EU)(\d{9})$/', $vat);
				break;
			case 'FI': // FINLAND
				$isValid = (bool) preg_match('/^(FI)(\d{8})$/', $vat);
				break;
			case 'FR': // FRANCE
				$isValid = (bool) preg_match('/^(FR)(\d{11})$/', $vat)
					|| preg_match('/^(FR)([(A-H)|(J-N)|(P-Z)]\d{10})$/', $vat)
					|| preg_match('/^(FR)(\d[(A-H)|(J-N)|(P-Z)]\d{9})$/', $vat)
					|| preg_match('/^(FR)([(A-H)|(J-N)|(P-Z)]{2}\d{9})$/', $vat);
				break;
			case 'GB': // GREAT BRITAIN
				$isValid = (bool) preg_match('/^(GB)?(\d{9})$/', $vat)
					|| preg_match('/^(GB)?(\d{12})$/', $vat)
					|| preg_match('/^(GB)?(GD\d{3})$/', $vat)
					|| preg_match('/^(GB)?(HA\d{3})$/', $vat);
				break;
			case 'GR': // GREECE
				$isValid = (bool) preg_match('/^(GR)(\d{8,9})$/', $vat);
				break;
			case 'HR': // CROATIA
				$isValid = (bool) preg_match('/^(HR)(\d{11})$/', $vat);
				break;
			case 'HU': // HUNGARY
				$isValid = (bool) preg_match('/^(HU)(\d{8})$/', $vat);
				break;
			case 'IE': // IRELAND
				$isValid = (bool) preg_match('/^(IE)(\d{7}[A-W])$/', $vat)
					|| preg_match('/^(IE)([7-9][A-Z\*\+)]\d{5}[A-W])$/', $vat)
					|| preg_match('/^(IE)(\d{7}[A-W][AH])$/', $vat);
				break;
			case 'IT': // ITALY
				$isValid = (bool) preg_match('/^(IT)(\d{11})$/', $vat);
				break;
			case 'LV': // LATVIA
				$isValid = (bool) preg_match('/^(LV)(\d{11})$/', $vat);
				break;
			case 'LT': // LITHUNIA
				$isValid = (bool) preg_match('/^(LT)(\d{9}|\d{12})$/', $vat);
				break;
			case 'LU': // LUXEMBOURG
				$isValid = (bool) preg_match('/^(LU)(\d{8})$/', $vat);
				break;
			case 'MT': // MALTA
				$isValid = (bool) preg_match('/^(MT)([1-9]\d{7})$/', $vat);
				break;
			case 'NL': // NETHERLAND
				$isValid = (bool) preg_match('/^(NL)(\d{9})B\d{2}$/', $vat);
				break;
			case 'NO': // NORWAY
				$isValid = (bool) preg_match('/^(NO)(\d{9})$/', $vat);
				break;
			case 'PL': // POLAND
				$isValid = (bool) preg_match('/^(PL)(\d{10})$/', $vat);
				break;
			case 'PT': // PORTUGAL
				$isValid = (bool) preg_match('/^(PT)(\d{9})$/', $vat);
				break;
			case 'RO': // ROMANIA
				$isValid = (bool) preg_match('/^(RO)([1-9]\d{1,9})$/', $vat);
				break;
			case 'RS': // SERBIA
				$isValid = (bool) preg_match('/^(RS)(\d{9})$/', $vat);
				break;
			case 'SI': // SLOVENIA
				$isValid = (bool) preg_match('/^(SI)([1-9]\d{7})$/', $vat);
				break;
			case 'SK': // SLOVAK REPUBLIC
				$isValid = (bool) preg_match('/^(SK)([1-9]\d[(2-4)|(6-9)]\d{7})$/', $vat);
				break;
			case 'SE': // SWEDEN
				$isValid = (bool) preg_match('/^(SE)(\d{10}01)$/', $vat);
				break;
			default:
				$isValid = false;
		}

		return $isValid;
	}
}

Got a question?

Synet.sk

Professional development of web applications and custom solutions. Consultancy services.

Demo

Contact


https://synet.sk