-
Notifications
You must be signed in to change notification settings - Fork 1
/
validate.go
91 lines (80 loc) · 2.35 KB
/
validate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package vat
import (
"fmt"
"regexp"
"strings"
)
// Validate validates a VAT number by both format and existence. If no error then it is valid.
func Validate(vatNumber string) error {
err := ValidateFormat(vatNumber)
if err != nil {
return err
}
return ValidateExists(vatNumber)
}
// ValidateFormat validates a VAT number by its format. If no error is returned then it is valid.
func ValidateFormat(vatNumber string) error {
patterns := map[string]string{
"AT": `U[A-Z0-9]{8}`,
"BE": `(0[0-9]{9}|[0-9]{10})`,
"BG": `[0-9]{9,10}`,
"CH": `(?:E(?:-| )[0-9]{3}(?:\.| )[0-9]{3}(?:\.| )[0-9]{3}( MWST)?|E[0-9]{9}(?:MWST)?)`,
"CY": `[0-9]{8}[A-Z]`,
"CZ": `[0-9]{8,10}`,
"DE": `[0-9]{9}`,
"DK": `[0-9]{8}`,
"EE": `[0-9]{9}`,
"EL": `[0-9]{9}`,
"ES": `[A-Z][0-9]{7}[A-Z]|[0-9]{8}[A-Z]|[A-Z][0-9]{8}`,
"FI": `[0-9]{8}`,
"FR": `([A-Z]{2}|[0-9]{2})[0-9]{9}`,
// Supposedly the regex for GB numbers is `[0-9]{9}|[0-9]{12}|(GD|HA)[0-9]{3}`,
// but our validator service only accepts numbers with 9 or 12 digits following the country code.
// Seems like the official site only accepts 9 digits... https://www.gov.uk/check-uk-vat-number
"GB": `([0-9]{9}|[0-9]{12})`,
"HR": `[0-9]{11}`,
"HU": `[0-9]{8}`,
"IE": `[A-Z0-9]{7}[A-Z]|[A-Z0-9]{7}[A-W][A-I]`,
"IT": `[0-9]{11}`,
"LT": `([0-9]{9}|[0-9]{12})`,
"LU": `[0-9]{8}`,
"LV": `[0-9]{11}`,
"MT": `[0-9]{8}`,
"NL": `[0-9]{9}B[0-9]{2}`,
"PL": `[0-9]{10}`,
"PT": `[0-9]{9}`,
"RO": `[0-9]{2,10}`,
"SE": `[0-9]{12}`,
"SI": `[0-9]{8}`,
"SK": `[0-9]{10}`,
"XI": `([0-9]{9}|[0-9]{12})`, // Northern Ireland, same format as GB
}
if len(vatNumber) < 3 {
return ErrInvalidVATNumberFormat
}
vatNumber = strings.ToUpper(vatNumber)
pattern, ok := patterns[vatNumber[0:2]]
if !ok {
return ErrInvalidCountryCode
}
matched, err := regexp.MatchString(fmt.Sprintf("^%s$", pattern), vatNumber[2:])
if err != nil {
return err
}
if !matched {
return ErrInvalidVATNumberFormat
}
return nil
}
// ValidateExists validates that the given VAT number exists in the external lookup service.
func ValidateExists(vatNumber string) error {
if len(vatNumber) < 3 {
return ErrInvalidVATNumberFormat
}
vatNumber = strings.ToUpper(vatNumber)
lookupService := ViesLookupService
if strings.HasPrefix(vatNumber, "GB") {
lookupService = UKVATLookupService
}
return lookupService.Validate(vatNumber)
}