eu_vat_rates_data 2026.8.12 → 2026.8.14
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 +40 -16
- data/data/eu-vat-rates-data.json +1 -1
- data/lib/eu_vat_rates_data/version.rb +1 -1
- data/lib/eu_vat_rates_data.rb +3 -0
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 867e872a863f754240a5bc267436a0c980015a449506db8ee5617f3597334af3
|
|
4
|
+
data.tar.gz: 85a05ca031f7db5d96295f7017df4de7c1161ef97287d453a2242da0f044163a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6e2042ba9b7dc8ab16fdf692c41bbaa11d332363dc43b24971d14f2bd0688c214661c5619a3b202e94717f1a221c0c0d18cee02c10abbd8c15c5c5e05a21bfc2
|
|
7
|
+
data.tar.gz: 03df437a6bde6839ce51c07bcb4c011b3191f8573f4587e4c814925be350f4c7eb931d219b3aaead9b75632e372557366b62eea3ef87328ce4c7dd733a728190
|
data/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Also available in: [JavaScript/TypeScript (npm)](https://www.npmjs.com/package/e
|
|
|
24
24
|
|
|
25
25
|
This package gives you VAT **rates** and **format checks** for free, offline, in your code. It does **not** call VIES — `valid_format?()` only checks the shape of a VAT number, not whether it actually exists.
|
|
26
26
|
|
|
27
|
-
For **live VIES validation** — confirming a VAT ID is real, pulling the registered company name and address, and getting the VIES consultation number as your reference for the check — there's **[vatnode](https://vatnode.dev)**:
|
|
27
|
+
For **live VIES validation** — confirming a VAT ID is real, pulling the registered company name and address, and getting the VIES consultation number as your reference for the check — there's **[vatnode](https://vatnode.dev?ref=rates-readme-rb)**:
|
|
28
28
|
|
|
29
29
|
- Live VIES validation, with national-database fallback when VIES is down
|
|
30
30
|
- Registered company name, address, registration date
|
|
@@ -38,7 +38,7 @@ curl https://api.vatnode.dev/v1/vat/IE6388047V \
|
|
|
38
38
|
-H "Authorization: Bearer YOUR_API_KEY"
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
[**Get a free API key
|
|
41
|
+
[**See what the API adds →**](https://vatnode.dev/vat-rates?ref=rates-readme-rb#beyond-rates) · [Get a free API key](https://vatnode.dev/login?ref=rates-readme-rb)
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
@@ -110,6 +110,43 @@ EuVatRatesData.flag("XX") # => "" (empty string for unknown/invalid codes)
|
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
113
|
+
## Example: charging VAT on an invoice
|
|
114
|
+
|
|
115
|
+
Rates on their own rarely answer the question you actually have, which is what
|
|
116
|
+
to put on the invoice. Two rules cover most of it: charge the buyer's domestic
|
|
117
|
+
rate, unless the sale is cross-border B2B inside the EU, where the reverse
|
|
118
|
+
charge applies and you invoice 0%.
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
# Money in minor units (cents). Never floats.
|
|
122
|
+
def invoice_total(net_cents, seller_country, buyer_country, buyer_vat_id = nil)
|
|
123
|
+
cross_border_b2b = buyer_country != seller_country &&
|
|
124
|
+
!buyer_vat_id.nil? &&
|
|
125
|
+
EuVatRatesData.valid_format?(buyer_vat_id)
|
|
126
|
+
|
|
127
|
+
return { vat_cents: 0, total_cents: net_cents, reverse_charge: true } if cross_border_b2b
|
|
128
|
+
|
|
129
|
+
rate = EuVatRatesData.get_standard_rate(buyer_country)
|
|
130
|
+
vat_cents = (net_cents * rate / 100.0).round
|
|
131
|
+
|
|
132
|
+
{ vat_cents: vat_cents, total_cents: net_cents + vat_cents, reverse_charge: false }
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Domestic sale in Finland — 25.5%
|
|
136
|
+
invoice_total(10_000, 'FI', 'FI')
|
|
137
|
+
# => { vat_cents: 2550, total_cents: 12550, reverse_charge: false }
|
|
138
|
+
|
|
139
|
+
# Finnish seller, German business buyer — reverse charge
|
|
140
|
+
invoice_total(10_000, 'FI', 'DE', 'DE123456789')
|
|
141
|
+
# => { vat_cents: 0, total_cents: 10000, reverse_charge: true }
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`valid_format?` only checks the shape of the number. Applying the reverse charge
|
|
145
|
+
requires the buyer to actually be VAT-registered, which is a VIES lookup — see
|
|
146
|
+
above.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
113
150
|
## Data source & update frequency
|
|
114
151
|
|
|
115
152
|
How the daily check works, and what changed when: [vatnode.dev/data](https://vatnode.dev/data?ref=rates-readme-rb).
|
|
@@ -149,22 +186,9 @@ No package needed — parse it with a single `fetch()` / `http.get()` / `file_ge
|
|
|
149
186
|
|
|
150
187
|
---
|
|
151
188
|
|
|
152
|
-
## Need to validate VAT numbers?
|
|
153
|
-
|
|
154
|
-
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](https://vatnode.dev), a simple REST API with a free tier.
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
curl https://api.vatnode.dev/v1/vat/FI17156132 \
|
|
158
|
-
-H "Authorization: Bearer vat_live_..."
|
|
159
|
-
# → { "valid": true, "companyName": "Suomen Pehmeä Ikkuna Oy" }
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
189
|
## Changelog
|
|
165
190
|
|
|
166
|
-
|
|
167
|
-
- **fix:** Corrected Sweden (SE) VAT number regex — was `^SE\d{12}$`, now correctly requires the mandatory `01` suffix: `^SE\d{10}01$`.
|
|
191
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
168
192
|
|
|
169
193
|
---
|
|
170
194
|
|
data/data/eu-vat-rates-data.json
CHANGED
data/lib/eu_vat_rates_data.rb
CHANGED
|
@@ -77,6 +77,9 @@ module EuVatRatesData
|
|
|
77
77
|
# @return [Boolean]
|
|
78
78
|
def self.valid_format?(vat_id)
|
|
79
79
|
code = vat_id[0, 2].upcase
|
|
80
|
+
# Greek VAT numbers carry the VIES prefix EL, while the dataset keys Greece
|
|
81
|
+
# under its ISO code GR.
|
|
82
|
+
code = "GR" if code == "EL"
|
|
80
83
|
rate = get_rate(code)
|
|
81
84
|
return false unless rate && rate["pattern"]
|
|
82
85
|
!!(vat_id.upcase =~ /\A#{rate["pattern"]}\z/)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: eu_vat_rates_data
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2026.8.
|
|
4
|
+
version: 2026.8.14
|
|
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-08-
|
|
11
|
+
date: 2026-08-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: VAT rates (standard, reduced, super-reduced, parking) for 45 European
|
|
14
14
|
countries — EU-27 plus Norway, Switzerland, UK, and more. Includes eu_member flag,
|
|
@@ -25,13 +25,15 @@ files:
|
|
|
25
25
|
- data/eu-vat-rates-data.json
|
|
26
26
|
- lib/eu_vat_rates_data.rb
|
|
27
27
|
- lib/eu_vat_rates_data/version.rb
|
|
28
|
-
homepage: https://
|
|
28
|
+
homepage: https://vatnode.dev/vat-rates?ref=rates-rubygems
|
|
29
29
|
licenses:
|
|
30
30
|
- MIT
|
|
31
31
|
metadata:
|
|
32
|
-
homepage_uri: https://
|
|
32
|
+
homepage_uri: https://vatnode.dev/vat-rates?ref=rates-rubygems
|
|
33
33
|
source_code_uri: https://github.com/vatnode/eu-vat-rates-data-ruby
|
|
34
34
|
bug_tracker_uri: https://github.com/vatnode/eu-vat-rates-data-ruby/issues
|
|
35
|
+
changelog_uri: https://github.com/vatnode/eu-vat-rates-data-ruby/blob/main/CHANGELOG.md
|
|
36
|
+
documentation_uri: https://github.com/vatnode/eu-vat-rates-data-ruby#readme
|
|
35
37
|
post_install_message:
|
|
36
38
|
rdoc_options: []
|
|
37
39
|
require_paths:
|