eu_vat_rates_data 2026.3.28 → 2026.3.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +30 -1
- data/data/eu-vat-rates-data.json +177 -46
- data/lib/eu_vat_rates_data/version.rb +1 -1
- data/lib/eu_vat_rates_data.rb +14 -1
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9aa5cfb0609e948804ee35b2314921d7f07a8561b015a35fde1b24465e6eac39
|
|
4
|
+
data.tar.gz: 909f7e7e7a454a4c83f10030c48e1bdcebdf2dffd96d00dfe47ef8dc017533f4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 47f2770e396b04e9140dd3aacae12c3980eb4a0906d9fd2d6e9a5bde6ca3b75f23a29e349f4d866b5cb4065a907def92c4d4184beb580703b06e206f984cdfe0
|
|
7
|
+
data.tar.gz: cc8cca83cf408f8a816440b86323caeb3e4f451de7c59da4ab647a4453f5f79309ac83b6cceca282b8838e9a417687b17315aec60defbf05750605e4b209b594
|
data/README.md
CHANGED
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
[](https://github.com/vatnode/eu-vat-rates-data-ruby/commits/main)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
|
|
7
|
-
VAT rates for **44 European countries** — EU-27 plus Norway, Switzerland, UK, and more. EU rates sourced from the
|
|
7
|
+
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.
|
|
8
8
|
|
|
9
9
|
- Standard, reduced, super-reduced, and parking rates
|
|
10
10
|
- `eu_member` flag on every country — `true` for EU-27, `false` for non-EU
|
|
11
11
|
- `vat_name` — official name of the VAT tax in the country's primary official language
|
|
12
12
|
- `vat_abbr` — short abbreviation used locally (e.g. "ALV", "MwSt", "TVA")
|
|
13
|
+
- **`format` — human-readable VAT number format (e.g. `"ATU + 8 digits"`)** — unique to this package
|
|
14
|
+
- **`pattern` — regex for VAT number validation + built-in `valid_format?()` — free, no API key needed** — unique to this package
|
|
13
15
|
- No dependencies — pure Ruby 3.0+
|
|
14
16
|
- Data bundled in the gem — works offline, no network calls
|
|
15
17
|
- EU rates checked daily via GitHub Actions, new version published only when rates change
|
|
@@ -67,6 +69,16 @@ end
|
|
|
67
69
|
|
|
68
70
|
# When were EU rates last fetched?
|
|
69
71
|
puts EuVatRatesData.data_version # e.g. "2026-03-27"
|
|
72
|
+
|
|
73
|
+
# VAT number format validation — no API key, no network call
|
|
74
|
+
EuVatRatesData.valid_format?("ATU12345678") # => true
|
|
75
|
+
EuVatRatesData.valid_format?("DE123456789") # => true
|
|
76
|
+
EuVatRatesData.valid_format?("INVALID") # => false
|
|
77
|
+
|
|
78
|
+
# Access format metadata directly
|
|
79
|
+
at = EuVatRatesData.get_rate("AT")
|
|
80
|
+
puts at["format"] # "ATU + 8 digits"
|
|
81
|
+
puts at["pattern"] # "^ATU\\d{8}$"
|
|
70
82
|
```
|
|
71
83
|
|
|
72
84
|
---
|
|
@@ -79,6 +91,23 @@ puts EuVatRatesData.data_version # e.g. "2026-03-27"
|
|
|
79
91
|
|
|
80
92
|
---
|
|
81
93
|
|
|
94
|
+
|
|
95
|
+
## Keeping rates current
|
|
96
|
+
|
|
97
|
+
Rates are bundled at install time. A new package version is published automatically whenever rates change — but your installed version will not update itself.
|
|
98
|
+
|
|
99
|
+
**Recommended:** add [Renovate](https://renovatebot.com) or [Dependabot](https://docs.github.com/en/code-security/dependabot) to your repo. They detect new versions and open a PR automatically whenever rates change — no manual update commands needed.
|
|
100
|
+
|
|
101
|
+
**Need real-time accuracy?** Fetch the always-current JSON directly:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
https://cdn.jsdelivr.net/gh/vatnode/eu-vat-rates-data@main/data/eu-vat-rates-data.json
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
No package needed — parse it with a single `fetch()` / `http.get()` / `file_get_contents()` call and cache locally.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
82
111
|
## Covered countries
|
|
83
112
|
|
|
84
113
|
**EU-27** (daily auto-updates via EC TEDB):
|
data/data/eu-vat-rates-data.json
CHANGED
|
@@ -1,39 +1,45 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2026-03-
|
|
2
|
+
"version": "2026-03-30",
|
|
3
3
|
"source": "European Commission TEDB",
|
|
4
|
-
"url": "https://ec.europa.eu/taxation_customs/tedb/",
|
|
5
4
|
"rates": {
|
|
6
5
|
"AD": {
|
|
7
6
|
"country": "Andorra",
|
|
8
7
|
"currency": "EUR",
|
|
9
8
|
"eu_member": false,
|
|
10
9
|
"vat_name": "Impost General Indirecte",
|
|
10
|
+
"vat_abbr": "IGI",
|
|
11
11
|
"standard": 4.5,
|
|
12
12
|
"reduced": [
|
|
13
13
|
1.0,
|
|
14
14
|
2.5
|
|
15
15
|
],
|
|
16
16
|
"super_reduced": null,
|
|
17
|
-
"parking": null
|
|
17
|
+
"parking": null,
|
|
18
|
+
"format": "AD + alphanumeric",
|
|
19
|
+
"pattern": null
|
|
18
20
|
},
|
|
19
21
|
"AL": {
|
|
20
22
|
"country": "Albania",
|
|
21
23
|
"currency": "ALL",
|
|
22
24
|
"eu_member": false,
|
|
23
25
|
"vat_name": "Tatimi mbi vlerën e shtuar",
|
|
26
|
+
"vat_abbr": "TVSH",
|
|
24
27
|
"standard": 20.0,
|
|
25
28
|
"reduced": [
|
|
26
29
|
6.0,
|
|
27
30
|
10.0
|
|
28
31
|
],
|
|
29
32
|
"super_reduced": null,
|
|
30
|
-
"parking": null
|
|
33
|
+
"parking": null,
|
|
34
|
+
"format": "AL + 1 letter + 8 digits + 1 letter",
|
|
35
|
+
"pattern": "^AL[A-Z]\\d{8}[A-Z]$"
|
|
31
36
|
},
|
|
32
37
|
"AT": {
|
|
33
38
|
"country": "Austria",
|
|
34
39
|
"currency": "EUR",
|
|
35
40
|
"eu_member": true,
|
|
36
41
|
"vat_name": "Umsatzsteuer",
|
|
42
|
+
"vat_abbr": "USt",
|
|
37
43
|
"standard": 20.0,
|
|
38
44
|
"reduced": [
|
|
39
45
|
10.0,
|
|
@@ -41,146 +47,182 @@
|
|
|
41
47
|
19.0
|
|
42
48
|
],
|
|
43
49
|
"super_reduced": null,
|
|
44
|
-
"parking": null
|
|
50
|
+
"parking": null,
|
|
51
|
+
"format": "ATU + 8 digits",
|
|
52
|
+
"pattern": "^ATU\\d{8}$"
|
|
45
53
|
},
|
|
46
54
|
"BA": {
|
|
47
55
|
"country": "Bosnia and Herzegovina",
|
|
48
56
|
"currency": "BAM",
|
|
49
57
|
"eu_member": false,
|
|
50
58
|
"vat_name": "Porez na dodanu vrijednost",
|
|
59
|
+
"vat_abbr": "PDV",
|
|
51
60
|
"standard": 17.0,
|
|
52
61
|
"reduced": [],
|
|
53
62
|
"super_reduced": null,
|
|
54
|
-
"parking": null
|
|
63
|
+
"parking": null,
|
|
64
|
+
"format": "BA + alphanumeric",
|
|
65
|
+
"pattern": null
|
|
55
66
|
},
|
|
56
67
|
"BE": {
|
|
57
68
|
"country": "Belgium",
|
|
58
69
|
"currency": "EUR",
|
|
59
70
|
"eu_member": true,
|
|
60
71
|
"vat_name": "Belasting over de toegevoegde waarde",
|
|
72
|
+
"vat_abbr": "BTW",
|
|
61
73
|
"standard": 21.0,
|
|
62
74
|
"reduced": [
|
|
63
75
|
6.0,
|
|
64
76
|
12.0
|
|
65
77
|
],
|
|
66
78
|
"super_reduced": null,
|
|
67
|
-
"parking": 12.0
|
|
79
|
+
"parking": 12.0,
|
|
80
|
+
"format": "BE + 0/1 + 9 digits",
|
|
81
|
+
"pattern": "^BE[01]\\d{9}$"
|
|
68
82
|
},
|
|
69
83
|
"BG": {
|
|
70
84
|
"country": "Bulgaria",
|
|
71
85
|
"currency": "BGN",
|
|
72
86
|
"eu_member": true,
|
|
73
87
|
"vat_name": "Данък върху добавената стойност",
|
|
88
|
+
"vat_abbr": "ДДС",
|
|
74
89
|
"standard": 20.0,
|
|
75
90
|
"reduced": [
|
|
76
91
|
9.0
|
|
77
92
|
],
|
|
78
93
|
"super_reduced": null,
|
|
79
|
-
"parking": null
|
|
94
|
+
"parking": null,
|
|
95
|
+
"format": "BG + 9–10 digits",
|
|
96
|
+
"pattern": "^BG\\d{9,10}$"
|
|
80
97
|
},
|
|
81
98
|
"CH": {
|
|
82
99
|
"country": "Switzerland",
|
|
83
100
|
"currency": "CHF",
|
|
84
101
|
"eu_member": false,
|
|
85
102
|
"vat_name": "Mehrwertsteuer",
|
|
103
|
+
"vat_abbr": "MWST",
|
|
86
104
|
"standard": 8.1,
|
|
87
105
|
"reduced": [
|
|
88
106
|
2.6,
|
|
89
107
|
3.8
|
|
90
108
|
],
|
|
91
109
|
"super_reduced": null,
|
|
92
|
-
"parking": null
|
|
110
|
+
"parking": null,
|
|
111
|
+
"format": "CHE + 9 digits (+ MWST/TVA/IVA)",
|
|
112
|
+
"pattern": "^CHE\\d{9}(MWST|TVA|IVA)?$"
|
|
93
113
|
},
|
|
94
114
|
"CY": {
|
|
95
115
|
"country": "Cyprus",
|
|
96
116
|
"currency": "EUR",
|
|
97
117
|
"eu_member": true,
|
|
98
118
|
"vat_name": "Φόρος Προστιθέμενης Αξίας",
|
|
119
|
+
"vat_abbr": "ΦΠΑ",
|
|
99
120
|
"standard": 19.0,
|
|
100
121
|
"reduced": [
|
|
101
122
|
5.0,
|
|
102
123
|
9.0
|
|
103
124
|
],
|
|
104
125
|
"super_reduced": 3.0,
|
|
105
|
-
"parking": null
|
|
126
|
+
"parking": null,
|
|
127
|
+
"format": "CY + 8 digits + 1 letter",
|
|
128
|
+
"pattern": "^CY\\d{8}[A-Z]$"
|
|
106
129
|
},
|
|
107
130
|
"CZ": {
|
|
108
131
|
"country": "Czech Republic",
|
|
109
132
|
"currency": "CZK",
|
|
110
133
|
"eu_member": true,
|
|
111
134
|
"vat_name": "Daň z přidané hodnoty",
|
|
135
|
+
"vat_abbr": "DPH",
|
|
112
136
|
"standard": 21.0,
|
|
113
137
|
"reduced": [
|
|
114
138
|
12.0
|
|
115
139
|
],
|
|
116
140
|
"super_reduced": null,
|
|
117
|
-
"parking": null
|
|
141
|
+
"parking": null,
|
|
142
|
+
"format": "CZ + 8–10 digits",
|
|
143
|
+
"pattern": "^CZ\\d{8,10}$"
|
|
118
144
|
},
|
|
119
145
|
"DE": {
|
|
120
146
|
"country": "Germany",
|
|
121
147
|
"currency": "EUR",
|
|
122
148
|
"eu_member": true,
|
|
123
149
|
"vat_name": "Umsatzsteuer",
|
|
150
|
+
"vat_abbr": "MwSt",
|
|
124
151
|
"standard": 19.0,
|
|
125
152
|
"reduced": [
|
|
126
153
|
7.0
|
|
127
154
|
],
|
|
128
155
|
"super_reduced": null,
|
|
129
|
-
"parking": null
|
|
156
|
+
"parking": null,
|
|
157
|
+
"format": "DE + 9 digits",
|
|
158
|
+
"pattern": "^DE\\d{9}$"
|
|
130
159
|
},
|
|
131
160
|
"DK": {
|
|
132
161
|
"country": "Denmark",
|
|
133
162
|
"currency": "DKK",
|
|
134
163
|
"eu_member": true,
|
|
135
164
|
"vat_name": "Moms",
|
|
165
|
+
"vat_abbr": "moms",
|
|
136
166
|
"standard": 25.0,
|
|
137
167
|
"reduced": [],
|
|
138
168
|
"super_reduced": null,
|
|
139
|
-
"parking": null
|
|
169
|
+
"parking": null,
|
|
170
|
+
"format": "DK + 8 digits",
|
|
171
|
+
"pattern": "^DK\\d{8}$"
|
|
140
172
|
},
|
|
141
173
|
"EE": {
|
|
142
174
|
"country": "Estonia",
|
|
143
175
|
"currency": "EUR",
|
|
144
176
|
"eu_member": true,
|
|
145
177
|
"vat_name": "Käibemaks",
|
|
178
|
+
"vat_abbr": "km",
|
|
146
179
|
"standard": 24.0,
|
|
147
180
|
"reduced": [
|
|
148
181
|
9.0,
|
|
149
182
|
13.0
|
|
150
183
|
],
|
|
151
184
|
"super_reduced": null,
|
|
152
|
-
"parking": null
|
|
185
|
+
"parking": null,
|
|
186
|
+
"format": "EE + 9 digits",
|
|
187
|
+
"pattern": "^EE\\d{9}$"
|
|
153
188
|
},
|
|
154
189
|
"ES": {
|
|
155
190
|
"country": "Spain",
|
|
156
191
|
"currency": "EUR",
|
|
157
192
|
"eu_member": true,
|
|
158
193
|
"vat_name": "Impuesto sobre el Valor Añadido",
|
|
194
|
+
"vat_abbr": "IVA",
|
|
159
195
|
"standard": 21.0,
|
|
160
196
|
"reduced": [
|
|
161
197
|
10.0
|
|
162
198
|
],
|
|
163
199
|
"super_reduced": 4.0,
|
|
164
|
-
"parking": null
|
|
200
|
+
"parking": null,
|
|
201
|
+
"format": "ES + letter/digit + 7 digits + letter/digit",
|
|
202
|
+
"pattern": "^ES[A-Z0-9]\\d{7}[A-Z0-9]$"
|
|
165
203
|
},
|
|
166
204
|
"FI": {
|
|
167
205
|
"country": "Finland",
|
|
168
206
|
"currency": "EUR",
|
|
169
207
|
"eu_member": true,
|
|
170
208
|
"vat_name": "Arvonlisävero",
|
|
209
|
+
"vat_abbr": "ALV",
|
|
171
210
|
"standard": 25.5,
|
|
172
211
|
"reduced": [
|
|
173
212
|
10.0,
|
|
174
213
|
13.5
|
|
175
214
|
],
|
|
176
215
|
"super_reduced": null,
|
|
177
|
-
"parking": null
|
|
216
|
+
"parking": null,
|
|
217
|
+
"format": "FI + 8 digits",
|
|
218
|
+
"pattern": "^FI\\d{8}$"
|
|
178
219
|
},
|
|
179
220
|
"FR": {
|
|
180
221
|
"country": "France",
|
|
181
222
|
"currency": "EUR",
|
|
182
223
|
"eu_member": true,
|
|
183
224
|
"vat_name": "Taxe sur la valeur ajoutée",
|
|
225
|
+
"vat_abbr": "TVA",
|
|
184
226
|
"standard": 20.0,
|
|
185
227
|
"reduced": [
|
|
186
228
|
0.9,
|
|
@@ -191,35 +233,44 @@
|
|
|
191
233
|
13.0
|
|
192
234
|
],
|
|
193
235
|
"super_reduced": 2.1,
|
|
194
|
-
"parking": null
|
|
236
|
+
"parking": null,
|
|
237
|
+
"format": "FR + 2 alphanumeric + 9 digits",
|
|
238
|
+
"pattern": "^FR[A-HJ-NP-Z0-9]{2}\\d{9}$"
|
|
195
239
|
},
|
|
196
240
|
"GB": {
|
|
197
241
|
"country": "United Kingdom",
|
|
198
242
|
"currency": "GBP",
|
|
199
243
|
"eu_member": false,
|
|
200
244
|
"vat_name": "Value Added Tax",
|
|
245
|
+
"vat_abbr": "VAT",
|
|
201
246
|
"standard": 20.0,
|
|
202
247
|
"reduced": [
|
|
203
248
|
5.0
|
|
204
249
|
],
|
|
205
250
|
"super_reduced": null,
|
|
206
|
-
"parking": null
|
|
251
|
+
"parking": null,
|
|
252
|
+
"format": "GB + 9 or 12 digits (or GD/HA + 3 digits)",
|
|
253
|
+
"pattern": "^GB(\\d{9}|\\d{12}|GD\\d{3}|HA\\d{3})$"
|
|
207
254
|
},
|
|
208
255
|
"GE": {
|
|
209
256
|
"country": "Georgia",
|
|
210
257
|
"currency": "GEL",
|
|
211
258
|
"eu_member": false,
|
|
212
259
|
"vat_name": "დამატებული ღირებულების გადასახადი",
|
|
260
|
+
"vat_abbr": "დღგ",
|
|
213
261
|
"standard": 18.0,
|
|
214
262
|
"reduced": [],
|
|
215
263
|
"super_reduced": null,
|
|
216
|
-
"parking": null
|
|
264
|
+
"parking": null,
|
|
265
|
+
"format": "GE + alphanumeric",
|
|
266
|
+
"pattern": null
|
|
217
267
|
},
|
|
218
268
|
"GR": {
|
|
219
269
|
"country": "Greece",
|
|
220
270
|
"currency": "EUR",
|
|
221
271
|
"eu_member": true,
|
|
222
272
|
"vat_name": "Φόρος Προστιθέμενης Αξίας",
|
|
273
|
+
"vat_abbr": "ΦΠΑ",
|
|
223
274
|
"standard": 24.0,
|
|
224
275
|
"reduced": [
|
|
225
276
|
6.0,
|
|
@@ -227,231 +278,285 @@
|
|
|
227
278
|
17.0
|
|
228
279
|
],
|
|
229
280
|
"super_reduced": 4.0,
|
|
230
|
-
"parking": 13.0
|
|
281
|
+
"parking": 13.0,
|
|
282
|
+
"format": "EL + 9 digits",
|
|
283
|
+
"pattern": "^EL\\d{9}$"
|
|
231
284
|
},
|
|
232
285
|
"HR": {
|
|
233
286
|
"country": "Croatia",
|
|
234
287
|
"currency": "EUR",
|
|
235
288
|
"eu_member": true,
|
|
236
289
|
"vat_name": "Porez na dodanu vrijednost",
|
|
290
|
+
"vat_abbr": "PDV",
|
|
237
291
|
"standard": 25.0,
|
|
238
292
|
"reduced": [
|
|
239
293
|
5.0,
|
|
240
294
|
13.0
|
|
241
295
|
],
|
|
242
296
|
"super_reduced": null,
|
|
243
|
-
"parking": null
|
|
297
|
+
"parking": null,
|
|
298
|
+
"format": "HR + 11 digits",
|
|
299
|
+
"pattern": "^HR\\d{11}$"
|
|
244
300
|
},
|
|
245
301
|
"HU": {
|
|
246
302
|
"country": "Hungary",
|
|
247
303
|
"currency": "HUF",
|
|
248
304
|
"eu_member": true,
|
|
249
305
|
"vat_name": "Általános forgalmi adó",
|
|
306
|
+
"vat_abbr": "ÁFA",
|
|
250
307
|
"standard": 27.0,
|
|
251
308
|
"reduced": [
|
|
252
309
|
5.0,
|
|
253
310
|
18.0
|
|
254
311
|
],
|
|
255
312
|
"super_reduced": null,
|
|
256
|
-
"parking": null
|
|
313
|
+
"parking": null,
|
|
314
|
+
"format": "HU + 8 digits",
|
|
315
|
+
"pattern": "^HU\\d{8}$"
|
|
257
316
|
},
|
|
258
317
|
"IE": {
|
|
259
318
|
"country": "Ireland",
|
|
260
319
|
"currency": "EUR",
|
|
261
320
|
"eu_member": true,
|
|
262
321
|
"vat_name": "Value Added Tax",
|
|
322
|
+
"vat_abbr": "VAT",
|
|
263
323
|
"standard": 23.0,
|
|
264
324
|
"reduced": [
|
|
265
325
|
9.0,
|
|
266
326
|
13.5
|
|
267
327
|
],
|
|
268
328
|
"super_reduced": null,
|
|
269
|
-
"parking": null
|
|
329
|
+
"parking": null,
|
|
330
|
+
"format": "IE + 7 digits + 1–2 letters",
|
|
331
|
+
"pattern": "^IE\\d{7}[A-W][A-IW]?$|^IE\\d[A-Z+*]\\d{5}[A-W]$"
|
|
270
332
|
},
|
|
271
333
|
"IS": {
|
|
272
334
|
"country": "Iceland",
|
|
273
335
|
"currency": "ISK",
|
|
274
336
|
"eu_member": false,
|
|
275
337
|
"vat_name": "Virðisaukaskattur",
|
|
338
|
+
"vat_abbr": "VSK",
|
|
276
339
|
"standard": 24.0,
|
|
277
340
|
"reduced": [
|
|
278
341
|
11.0
|
|
279
342
|
],
|
|
280
343
|
"super_reduced": null,
|
|
281
|
-
"parking": null
|
|
344
|
+
"parking": null,
|
|
345
|
+
"format": "IS + 5–6 digits",
|
|
346
|
+
"pattern": "^IS\\d{5,6}$"
|
|
282
347
|
},
|
|
283
348
|
"IT": {
|
|
284
349
|
"country": "Italy",
|
|
285
350
|
"currency": "EUR",
|
|
286
351
|
"eu_member": true,
|
|
287
352
|
"vat_name": "Imposta sul valore aggiunto",
|
|
353
|
+
"vat_abbr": "IVA",
|
|
288
354
|
"standard": 22.0,
|
|
289
355
|
"reduced": [
|
|
290
356
|
5.0,
|
|
291
357
|
10.0
|
|
292
358
|
],
|
|
293
359
|
"super_reduced": 4.0,
|
|
294
|
-
"parking": null
|
|
360
|
+
"parking": null,
|
|
361
|
+
"format": "IT + 11 digits",
|
|
362
|
+
"pattern": "^IT\\d{11}$"
|
|
295
363
|
},
|
|
296
364
|
"LI": {
|
|
297
365
|
"country": "Liechtenstein",
|
|
298
366
|
"currency": "CHF",
|
|
299
367
|
"eu_member": false,
|
|
300
368
|
"vat_name": "Mehrwertsteuer",
|
|
369
|
+
"vat_abbr": "MWST",
|
|
301
370
|
"standard": 8.1,
|
|
302
371
|
"reduced": [
|
|
303
372
|
2.6,
|
|
304
373
|
3.8
|
|
305
374
|
],
|
|
306
375
|
"super_reduced": null,
|
|
307
|
-
"parking": null
|
|
376
|
+
"parking": null,
|
|
377
|
+
"format": "LI + alphanumeric",
|
|
378
|
+
"pattern": null
|
|
308
379
|
},
|
|
309
380
|
"LT": {
|
|
310
381
|
"country": "Lithuania",
|
|
311
382
|
"currency": "EUR",
|
|
312
383
|
"eu_member": true,
|
|
313
384
|
"vat_name": "Pridėtinės vertės mokestis",
|
|
385
|
+
"vat_abbr": "PVM",
|
|
314
386
|
"standard": 21.0,
|
|
315
387
|
"reduced": [
|
|
316
388
|
5.0,
|
|
317
389
|
12.0
|
|
318
390
|
],
|
|
319
391
|
"super_reduced": null,
|
|
320
|
-
"parking": null
|
|
392
|
+
"parking": null,
|
|
393
|
+
"format": "LT + 9 or 12 digits",
|
|
394
|
+
"pattern": "^LT(\\d{9}|\\d{12})$"
|
|
321
395
|
},
|
|
322
396
|
"LU": {
|
|
323
397
|
"country": "Luxembourg",
|
|
324
398
|
"currency": "EUR",
|
|
325
399
|
"eu_member": true,
|
|
326
400
|
"vat_name": "Taxe sur la valeur ajoutée",
|
|
401
|
+
"vat_abbr": "TVA",
|
|
327
402
|
"standard": 17.0,
|
|
328
403
|
"reduced": [
|
|
329
404
|
8.0,
|
|
330
405
|
14.0
|
|
331
406
|
],
|
|
332
407
|
"super_reduced": 3.0,
|
|
333
|
-
"parking": 14.0
|
|
408
|
+
"parking": 14.0,
|
|
409
|
+
"format": "LU + 8 digits",
|
|
410
|
+
"pattern": "^LU\\d{8}$"
|
|
334
411
|
},
|
|
335
412
|
"LV": {
|
|
336
413
|
"country": "Latvia",
|
|
337
414
|
"currency": "EUR",
|
|
338
415
|
"eu_member": true,
|
|
339
416
|
"vat_name": "Pievienotās vērtības nodoklis",
|
|
417
|
+
"vat_abbr": "PVN",
|
|
340
418
|
"standard": 21.0,
|
|
341
419
|
"reduced": [
|
|
342
420
|
5.0,
|
|
343
421
|
12.0
|
|
344
422
|
],
|
|
345
423
|
"super_reduced": null,
|
|
346
|
-
"parking": null
|
|
424
|
+
"parking": null,
|
|
425
|
+
"format": "LV + 11 digits",
|
|
426
|
+
"pattern": "^LV\\d{11}$"
|
|
347
427
|
},
|
|
348
428
|
"MC": {
|
|
349
429
|
"country": "Monaco",
|
|
350
430
|
"currency": "EUR",
|
|
351
431
|
"eu_member": false,
|
|
352
432
|
"vat_name": "Taxe sur la valeur ajoutée",
|
|
433
|
+
"vat_abbr": "TVA",
|
|
353
434
|
"standard": 20.0,
|
|
354
435
|
"reduced": [
|
|
355
436
|
5.5,
|
|
356
437
|
10.0
|
|
357
438
|
],
|
|
358
439
|
"super_reduced": 2.1,
|
|
359
|
-
"parking": null
|
|
440
|
+
"parking": null,
|
|
441
|
+
"format": "MC + alphanumeric",
|
|
442
|
+
"pattern": null
|
|
360
443
|
},
|
|
361
444
|
"MD": {
|
|
362
445
|
"country": "Moldova",
|
|
363
446
|
"currency": "MDL",
|
|
364
447
|
"eu_member": false,
|
|
365
448
|
"vat_name": "Taxa pe valoarea adăugată",
|
|
449
|
+
"vat_abbr": "TVA",
|
|
366
450
|
"standard": 20.0,
|
|
367
451
|
"reduced": [
|
|
368
452
|
8.0
|
|
369
453
|
],
|
|
370
454
|
"super_reduced": null,
|
|
371
|
-
"parking": null
|
|
455
|
+
"parking": null,
|
|
456
|
+
"format": "MD + alphanumeric",
|
|
457
|
+
"pattern": null
|
|
372
458
|
},
|
|
373
459
|
"ME": {
|
|
374
460
|
"country": "Montenegro",
|
|
375
461
|
"currency": "EUR",
|
|
376
462
|
"eu_member": false,
|
|
377
463
|
"vat_name": "Porez na dodatu vrijednost",
|
|
464
|
+
"vat_abbr": "PDV",
|
|
378
465
|
"standard": 21.0,
|
|
379
466
|
"reduced": [
|
|
380
467
|
7.0,
|
|
381
468
|
15.0
|
|
382
469
|
],
|
|
383
470
|
"super_reduced": null,
|
|
384
|
-
"parking": null
|
|
471
|
+
"parking": null,
|
|
472
|
+
"format": "ME + 8 digits",
|
|
473
|
+
"pattern": "^ME\\d{8}$"
|
|
385
474
|
},
|
|
386
475
|
"MK": {
|
|
387
476
|
"country": "North Macedonia",
|
|
388
477
|
"currency": "MKD",
|
|
389
478
|
"eu_member": false,
|
|
390
479
|
"vat_name": "Данок на додадена вредност",
|
|
480
|
+
"vat_abbr": "ДДВ",
|
|
391
481
|
"standard": 18.0,
|
|
392
482
|
"reduced": [
|
|
393
483
|
5.0,
|
|
394
484
|
10.0
|
|
395
485
|
],
|
|
396
486
|
"super_reduced": null,
|
|
397
|
-
"parking": null
|
|
487
|
+
"parking": null,
|
|
488
|
+
"format": "MK + 13 digits",
|
|
489
|
+
"pattern": "^MK\\d{13}$"
|
|
398
490
|
},
|
|
399
491
|
"MT": {
|
|
400
492
|
"country": "Malta",
|
|
401
493
|
"currency": "EUR",
|
|
402
494
|
"eu_member": true,
|
|
403
495
|
"vat_name": "Taxxa tal-Valur Miżjud",
|
|
496
|
+
"vat_abbr": "VAT",
|
|
404
497
|
"standard": 18.0,
|
|
405
498
|
"reduced": [
|
|
406
499
|
5.0,
|
|
407
500
|
7.0
|
|
408
501
|
],
|
|
409
502
|
"super_reduced": null,
|
|
410
|
-
"parking": 12.0
|
|
503
|
+
"parking": 12.0,
|
|
504
|
+
"format": "MT + 8 digits",
|
|
505
|
+
"pattern": "^MT\\d{8}$"
|
|
411
506
|
},
|
|
412
507
|
"NL": {
|
|
413
508
|
"country": "Netherlands",
|
|
414
509
|
"currency": "EUR",
|
|
415
510
|
"eu_member": true,
|
|
416
511
|
"vat_name": "Belasting over de toegevoegde waarde",
|
|
512
|
+
"vat_abbr": "btw",
|
|
417
513
|
"standard": 21.0,
|
|
418
514
|
"reduced": [
|
|
419
515
|
9.0
|
|
420
516
|
],
|
|
421
517
|
"super_reduced": null,
|
|
422
|
-
"parking": null
|
|
518
|
+
"parking": null,
|
|
519
|
+
"format": "NL + 9 digits + B + 2 digits",
|
|
520
|
+
"pattern": "^NL\\d{9}B\\d{2}$"
|
|
423
521
|
},
|
|
424
522
|
"NO": {
|
|
425
523
|
"country": "Norway",
|
|
426
524
|
"currency": "NOK",
|
|
427
525
|
"eu_member": false,
|
|
428
526
|
"vat_name": "Merverdiavgift",
|
|
527
|
+
"vat_abbr": "MVA",
|
|
429
528
|
"standard": 25.0,
|
|
430
529
|
"reduced": [
|
|
431
530
|
12.0,
|
|
432
531
|
15.0
|
|
433
532
|
],
|
|
434
533
|
"super_reduced": null,
|
|
435
|
-
"parking": null
|
|
534
|
+
"parking": null,
|
|
535
|
+
"format": "NO + 9 digits + MVA",
|
|
536
|
+
"pattern": "^NO\\d{9}MVA$"
|
|
436
537
|
},
|
|
437
538
|
"PL": {
|
|
438
539
|
"country": "Poland",
|
|
439
540
|
"currency": "PLN",
|
|
440
541
|
"eu_member": true,
|
|
441
542
|
"vat_name": "Podatek od towarów i usług",
|
|
543
|
+
"vat_abbr": "VAT",
|
|
442
544
|
"standard": 23.0,
|
|
443
545
|
"reduced": [
|
|
444
546
|
5.0,
|
|
445
547
|
8.0
|
|
446
548
|
],
|
|
447
549
|
"super_reduced": 8.0,
|
|
448
|
-
"parking": null
|
|
550
|
+
"parking": null,
|
|
551
|
+
"format": "PL + 10 digits",
|
|
552
|
+
"pattern": "^PL\\d{10}$"
|
|
449
553
|
},
|
|
450
554
|
"PT": {
|
|
451
555
|
"country": "Portugal",
|
|
452
556
|
"currency": "EUR",
|
|
453
557
|
"eu_member": true,
|
|
454
558
|
"vat_name": "Imposto sobre o Valor Acrescentado",
|
|
559
|
+
"vat_abbr": "IVA",
|
|
455
560
|
"standard": 23.0,
|
|
456
561
|
"reduced": [
|
|
457
562
|
6.0,
|
|
@@ -460,108 +565,134 @@
|
|
|
460
565
|
22.0
|
|
461
566
|
],
|
|
462
567
|
"super_reduced": 6.0,
|
|
463
|
-
"parking": 13.0
|
|
568
|
+
"parking": 13.0,
|
|
569
|
+
"format": "PT + 9 digits",
|
|
570
|
+
"pattern": "^PT\\d{9}$"
|
|
464
571
|
},
|
|
465
572
|
"RO": {
|
|
466
573
|
"country": "Romania",
|
|
467
574
|
"currency": "RON",
|
|
468
575
|
"eu_member": true,
|
|
469
576
|
"vat_name": "Taxa pe valoarea adăugată",
|
|
577
|
+
"vat_abbr": "TVA",
|
|
470
578
|
"standard": 21.0,
|
|
471
579
|
"reduced": [
|
|
472
580
|
11.0
|
|
473
581
|
],
|
|
474
582
|
"super_reduced": null,
|
|
475
|
-
"parking": null
|
|
583
|
+
"parking": null,
|
|
584
|
+
"format": "RO + 2–10 digits",
|
|
585
|
+
"pattern": "^RO\\d{2,10}$"
|
|
476
586
|
},
|
|
477
587
|
"RS": {
|
|
478
588
|
"country": "Serbia",
|
|
479
589
|
"currency": "RSD",
|
|
480
590
|
"eu_member": false,
|
|
481
591
|
"vat_name": "Porez na dodatu vrednost",
|
|
592
|
+
"vat_abbr": "PDV",
|
|
482
593
|
"standard": 20.0,
|
|
483
594
|
"reduced": [
|
|
484
595
|
10.0
|
|
485
596
|
],
|
|
486
597
|
"super_reduced": null,
|
|
487
|
-
"parking": null
|
|
598
|
+
"parking": null,
|
|
599
|
+
"format": "RS + 9 digits",
|
|
600
|
+
"pattern": "^RS\\d{9}$"
|
|
488
601
|
},
|
|
489
602
|
"SE": {
|
|
490
603
|
"country": "Sweden",
|
|
491
604
|
"currency": "SEK",
|
|
492
605
|
"eu_member": true,
|
|
493
606
|
"vat_name": "Mervärdesskatt",
|
|
607
|
+
"vat_abbr": "moms",
|
|
494
608
|
"standard": 25.0,
|
|
495
609
|
"reduced": [
|
|
496
610
|
6.0,
|
|
497
611
|
12.0
|
|
498
612
|
],
|
|
499
613
|
"super_reduced": null,
|
|
500
|
-
"parking": null
|
|
614
|
+
"parking": null,
|
|
615
|
+
"format": "SE + 12 digits",
|
|
616
|
+
"pattern": "^SE\\d{12}$"
|
|
501
617
|
},
|
|
502
618
|
"SI": {
|
|
503
619
|
"country": "Slovenia",
|
|
504
620
|
"currency": "EUR",
|
|
505
621
|
"eu_member": true,
|
|
506
622
|
"vat_name": "Davek na dodano vrednost",
|
|
623
|
+
"vat_abbr": "DDV",
|
|
507
624
|
"standard": 22.0,
|
|
508
625
|
"reduced": [
|
|
509
626
|
5.0,
|
|
510
627
|
9.5
|
|
511
628
|
],
|
|
512
629
|
"super_reduced": null,
|
|
513
|
-
"parking": null
|
|
630
|
+
"parking": null,
|
|
631
|
+
"format": "SI + 8 digits",
|
|
632
|
+
"pattern": "^SI\\d{8}$"
|
|
514
633
|
},
|
|
515
634
|
"SK": {
|
|
516
635
|
"country": "Slovakia",
|
|
517
636
|
"currency": "EUR",
|
|
518
637
|
"eu_member": true,
|
|
519
638
|
"vat_name": "Daň z pridanej hodnoty",
|
|
639
|
+
"vat_abbr": "DPH",
|
|
520
640
|
"standard": 23.0,
|
|
521
641
|
"reduced": [
|
|
522
642
|
5.0,
|
|
523
643
|
19.0
|
|
524
644
|
],
|
|
525
645
|
"super_reduced": null,
|
|
526
|
-
"parking": null
|
|
646
|
+
"parking": null,
|
|
647
|
+
"format": "SK + 10 digits",
|
|
648
|
+
"pattern": "^SK\\d{10}$"
|
|
527
649
|
},
|
|
528
650
|
"TR": {
|
|
529
651
|
"country": "Turkey",
|
|
530
652
|
"currency": "TRY",
|
|
531
653
|
"eu_member": false,
|
|
532
654
|
"vat_name": "Katma Değer Vergisi",
|
|
655
|
+
"vat_abbr": "KDV",
|
|
533
656
|
"standard": 20.0,
|
|
534
657
|
"reduced": [
|
|
535
658
|
1.0,
|
|
536
659
|
10.0
|
|
537
660
|
],
|
|
538
661
|
"super_reduced": null,
|
|
539
|
-
"parking": null
|
|
662
|
+
"parking": null,
|
|
663
|
+
"format": "TR + 10 digits",
|
|
664
|
+
"pattern": "^TR\\d{10}$"
|
|
540
665
|
},
|
|
541
666
|
"UA": {
|
|
542
667
|
"country": "Ukraine",
|
|
543
668
|
"currency": "UAH",
|
|
544
669
|
"eu_member": false,
|
|
545
670
|
"vat_name": "Податок на додану вартість",
|
|
671
|
+
"vat_abbr": "ПДВ",
|
|
546
672
|
"standard": 20.0,
|
|
547
673
|
"reduced": [
|
|
548
674
|
7.0,
|
|
549
675
|
14.0
|
|
550
676
|
],
|
|
551
677
|
"super_reduced": null,
|
|
552
|
-
"parking": null
|
|
678
|
+
"parking": null,
|
|
679
|
+
"format": "UA + 12 digits",
|
|
680
|
+
"pattern": "^UA\\d{12}$"
|
|
553
681
|
},
|
|
554
682
|
"XK": {
|
|
555
683
|
"country": "Kosovo",
|
|
556
684
|
"currency": "EUR",
|
|
557
685
|
"eu_member": false,
|
|
558
686
|
"vat_name": "Tatimi mbi Vlerën e Shtuar",
|
|
687
|
+
"vat_abbr": "TVSH",
|
|
559
688
|
"standard": 18.0,
|
|
560
689
|
"reduced": [
|
|
561
690
|
8.0
|
|
562
691
|
],
|
|
563
692
|
"super_reduced": null,
|
|
564
|
-
"parking": null
|
|
693
|
+
"parking": null,
|
|
694
|
+
"format": "XK + alphanumeric",
|
|
695
|
+
"pattern": null
|
|
565
696
|
}
|
|
566
697
|
}
|
|
567
698
|
}
|
data/lib/eu_vat_rates_data.rb
CHANGED
|
@@ -68,7 +68,20 @@ module EuVatRatesData
|
|
|
68
68
|
rates.key?(country_code.upcase)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
# Return true if vat_id matches the expected format for its country.
|
|
72
|
+
# Input must include the country code prefix (e.g. "ATU12345678").
|
|
73
|
+
# Returns false when the country has no standardised format or the ID does not match.
|
|
74
|
+
# Note: Greece uses the "EL" prefix, not "GR".
|
|
75
|
+
# @param vat_id [String] VAT number string including country code prefix
|
|
76
|
+
# @return [Boolean]
|
|
77
|
+
def self.valid_format?(vat_id)
|
|
78
|
+
code = vat_id[0, 2].upcase
|
|
79
|
+
rate = get_rate(code)
|
|
80
|
+
return false unless rate && rate["pattern"]
|
|
81
|
+
!!(vat_id.upcase =~ /\A#{rate["pattern"]}\z/)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Return the ISO 8601 date when EU data was last fetched from EC TEDB.
|
|
72
85
|
# @return [String] e.g. "2026-03-18"
|
|
73
86
|
def self.data_version
|
|
74
87
|
dataset["version"]
|
metadata
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: eu_vat_rates_data
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2026.3.
|
|
4
|
+
version: 2026.3.31
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Iurii Rogulia
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: VAT rates (standard, reduced, super-reduced, parking) for 44 European
|
|
14
|
-
countries — EU-27 plus Norway, Switzerland, UK, and more.
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
countries — EU-27 plus Norway, Switzerland, UK, and more. Includes eu_member flag,
|
|
15
|
+
local VAT name and abbreviation. Useful for billing, invoicing, e-commerce, fintech,
|
|
16
|
+
and VAT compliance.
|
|
17
17
|
email:
|
|
18
18
|
- iurii@rogulia.fi
|
|
19
19
|
executables: []
|
|
@@ -51,5 +51,5 @@ rubygems_version: 3.5.22
|
|
|
51
51
|
signing_key:
|
|
52
52
|
specification_version: 4
|
|
53
53
|
summary: VAT rates for 44 European countries — EU-27 plus Norway, Switzerland, UK,
|
|
54
|
-
and more.
|
|
54
|
+
and more.
|
|
55
55
|
test_files: []
|