euvatrates

package module
v1.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2026 License: MIT Imports: 4 Imported by: 0

README

eu-vat-rates-data-go

Go Reference Last updated

VAT rates for 44 European countries — EU-27 plus Norway, Switzerland, UK, and more. EU rates sourced from the European Commission TEDB and checked daily. Non-EU rates maintained manually.

  • Standard, reduced, super-reduced, and parking rates
  • EUMember field on every country — true for EU-27, false for non-EU
  • VATName — official name of the VAT tax in the country's primary official language
  • VATAbbr — short abbreviation used locally (e.g. "ALV", "MwSt", "TVA")
  • Format — human-readable VAT number format (e.g. "ATU + 8 digits") — unique to this package
  • Pattern — regex for VAT number validation + built-in ValidateFormat() — free, no API key needed — unique to this package
  • Zero dependencies — data embedded with //go:embed
  • Fully typed — works with Go 1.21+
  • EU rates checked daily via GitHub Actions, new version tagged only when rates change

Also available in: JavaScript/TypeScript (npm) · Python (PyPI) · PHP (Packagist) · Ruby (RubyGems)


Installation

go get github.com/vatnode/eu-vat-rates-data-go

Usage

package main

import (
    "fmt"
    euvatrates "github.com/vatnode/eu-vat-rates-data-go"
)

func main() {
    // Full rate struct for a country
    fi, ok := euvatrates.GetRate("FI")
    if ok {
        fmt.Printf("%s: %.1f%% (EU member: %v, tax: %s / %s)\n", fi.Country, fi.Standard, fi.EUMember, fi.VATName, fi.VATAbbr)
        // Finland: 25.5% (EU member: true, tax: Arvonlisävero / ALV)
    }

    // Just the standard rate
    standard, ok := euvatrates.GetStandardRate("DE")
    fmt.Println(standard) // 19

    // EU membership check — false for non-EU countries (GB, NO, CH, ...)
    if euvatrates.IsEUMember(userInput) {
        rate, _ := euvatrates.GetRate(userInput)
        _ = rate
    }

    // Dataset membership check (all 44 countries)
    if euvatrates.HasRate(userInput) {
        rate, _ := euvatrates.GetRate(userInput)
        _ = rate
    }

    // All 44 countries
    all := euvatrates.GetAllRates()
    for code, rate := range all {
        fmt.Printf("%s: %.1f%%\n", code, rate.Standard)
    }

    // When were EU rates last fetched?
    fmt.Println(euvatrates.DataVersion()) // "2026-03-27"

    // VAT number format validation — no API key, no network call
    euvatrates.ValidateFormat("ATU12345678") // → true
    euvatrates.ValidateFormat("DE123456789") // → true
    euvatrates.ValidateFormat("INVALID")     // → false

    // Access format metadata directly
    at, _ := euvatrates.GetRate("AT")
    fmt.Println(at.Format)   // "ATU + 8 digits"
    fmt.Println(at.Pattern) // "^ATU\\d{8}$"

    // Flag emoji from a 2-letter country code — no lookup table, computed from regional indicator symbols
    fmt.Println(euvatrates.GetFlag("FI")) // "🇫🇮"
    fmt.Println(euvatrates.GetFlag("DE")) // "🇩🇪"
    fmt.Println(euvatrates.GetFlag("XX")) // "" (empty string for unknown/invalid codes)
}

Types

type VatRate struct {
    Country      string    `json:"country"`
    Currency     string    `json:"currency"`
    EUMember     bool      `json:"eu_member"`
    VATName      string    `json:"vat_name"`
    VATAbbr      string    `json:"vat_abbr"`
    Standard     float64   `json:"standard"`
    Reduced      []float64 `json:"reduced"`
    SuperReduced *float64  `json:"super_reduced"`
    Parking      *float64  `json:"parking"`
    Format       string    `json:"format"`   // "ATU + 8 digits"
    Pattern      string    `json:"pattern"`  // "^ATU\\d{8}$" — always present for all 44 countries
}

Data source & update frequency

  • EU-27 rates: European Commission TEDB, refreshed daily at 07:00 UTC
  • Non-EU rates: maintained manually, updated on official rate changes
  • New git tag + pkg.go.dev version published only when rates change

Keeping rates current

Rates are bundled at install time. A new package version is published automatically whenever rates change — but your installed version will not update itself.

Recommended: add Renovate or Dependabot to your repo. They detect new versions and open a PR automatically whenever rates change — no manual update commands needed.

Need real-time accuracy? Fetch the always-current JSON directly:

https://cdn.jsdelivr.net/gh/vatnode/eu-vat-rates-data@main/data/eu-vat-rates-data.json

No package needed — parse it with a single fetch() / http.get() / file_get_contents() call and cache locally.


Covered countries

EU-27 (daily auto-updates via EC TEDB):

AT BE BG CY CZ DE DK EE ES FI FR GR HR HU IE IT LT LU LV MT NL PL PT RO SE SI SK

Non-EU Europe (manually maintained):

AD AL BA CH GB GE IS LI MC MD ME MK NO RS TR UA XK


Need to validate VAT numbers?

This package provides VAT rates only. If you also need to validate EU VAT numbers against the official VIES database — confirming a business is VAT-registered — check out vatnode.dev, a simple REST API with a free tier.

curl https://api.vatnode.dev/v1/vat/FI17156132 \
  -H "Authorization: Bearer vat_live_..."
# → { "valid": true, "companyName": "Suomen Pehmeä Ikkuna Oy" }

License

MIT

If you find this useful, a ⭐ on GitHub is appreciated.

Documentation

Overview

Package euvatrates provides VAT rates for 44 European countries (EU-27 + 17 non-EU).

EU rates are sourced from the European Commission TEDB (Taxes in Europe Database) and embedded at compile time. Non-EU rates are maintained manually.

Usage:

import euvatrates "github.com/vatnode/eu-vat-rates-data-go"

rate, ok := euvatrates.GetRate("FI")
// rate.Standard == 25.5, rate.Country == "Finland", rate.EUMember == true

standard, ok := euvatrates.GetStandardRate("DE")  // 19.0, true
euvatrates.IsEUMember("NO")                        // false
euvatrates.IsEUMember("FR")                        // true
euvatrates.DataVersion()                           // "2026-03-18"

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DataVersion

func DataVersion() string

DataVersion returns the ISO 8601 date when the EU data was last fetched from EC TEDB.

func GetAllRates

func GetAllRates() map[string]VatRate

GetAllRates returns a copy of the full rates map (44 countries).

func GetFlag added in v1.6.0

func GetFlag(countryCode string) string

GetFlag returns the flag emoji for a 2-letter ISO 3166-1 alpha-2 country code. Computed from regional indicator symbols — no lookup table needed. Returns an empty string if the input is not exactly 2 ASCII letters.

Example:

GetFlag("FI") // "🇫🇮"
GetFlag("DE") // "🇩🇪"
GetFlag("GB") // "🇬🇧"

func GetStandardRate

func GetStandardRate(countryCode string) (float64, bool)

GetStandardRate returns the standard VAT rate for the given country code. The second return value is false if the country is not in the dataset.

func HasRate added in v1.0.1

func HasRate(countryCode string) bool

HasRate returns true if the given country code is present in the dataset (all 44 countries). Use IsEUMember to check EU membership specifically.

func IsEUMember

func IsEUMember(countryCode string) bool

IsEUMember returns true if the country is an EU-27 member state. Returns false for non-EU countries in the dataset (GB, NO, CH, etc.) and for unknown country codes.

func ValidateFormat added in v1.5.0

func ValidateFormat(vatID string) bool

ValidateFormat returns true if vatID matches the expected format for its country. Input must include the country code prefix (e.g. "ATU12345678"). Returns false when the country has no standardised format or the ID does not match. Note: Greece uses the "EL" prefix, not "GR".

Types

type Dataset

type Dataset struct {
	Version string             `json:"version"`
	Source  string             `json:"source"`
	URL     string             `json:"url"`
	Rates   map[string]VatRate `json:"rates"`
}

Dataset is the top-level structure of the data file.

func RawDataset

func RawDataset() Dataset

RawDataset returns the full parsed Dataset struct.

type VatRate

type VatRate struct {
	Country      string    `json:"country"`
	Currency     string    `json:"currency"`
	EUMember     bool      `json:"eu_member"`
	VATName      string    `json:"vat_name"`
	VATAbbr      string    `json:"vat_abbr"`
	Standard     float64   `json:"standard"`
	Reduced      []float64 `json:"reduced"`
	SuperReduced *float64  `json:"super_reduced"`
	Parking      *float64  `json:"parking"`
	Format       string    `json:"format"`
	Pattern      string    `json:"pattern"` // Always present for all 44 countries
}

VatRate holds all VAT rates for a single country.

func GetRate

func GetRate(countryCode string) (VatRate, bool)

GetRate returns the full VatRate for the given ISO 3166-1 alpha-2 country code. The second return value is false if the country is not in the dataset.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL