Turns out the European Commission has a service where people can verify VAT numbers: The VAT Information Exchange System (VIES). Good thing since we don’t want to have to figure out how each individual European country handles VAT numbers. There is a web based user interface where users can manually input the number they want to check, but more interestingly for developers, there is a web service that uses SOAP.

I’m going to do is to call this SOAP service, but also wrap it in a REST API so it fits neatly into the rest of my API — slow clap for the bad pun.

The WSDL that describes the interface for the VAT service is here.


The Spring guide for SOAP web services suggests using a maven plugin for JAXB to generate the corresponding Java classes.



With this added to pom.xml, we can run the jax2b plugin with the generate goal.

mvn jaxb2:generate

These classes can also can be generated using IntelliJ.

With the code generated, we can create a web service client.

public class VatClient extends WebServiceGatewaySupport {
    private String url;

    private String wsdl;

    public CheckVatResponse checkVat(String countryCode, String vatNumber) {
        CheckVat request = new CheckVat();

        return (CheckVatResponse) getWebServiceTemplate()
                .marshalSendAndReceive(url, request, new SoapActionCallback(wsdl));

I’m placing strings in application.properties:


Jaxb2Marshaller configuration.

public class VatConfig {
    private String wsdl;

    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        return marshaller;

    public VatClient vatClient(Jaxb2Marshaller marshaller) {
        VatClient client = new VatClient();
        return client;

A controller for our API.

public class VatController {
    private VatClient vatClient;

    public ResponseEntity<?> vat(@RequestParam String countryCode, @RequestParam String vatNumber) {
        CheckVatResponse checkVatResponse = vatClient.checkVat(countryCode, vatNumber);
        if (checkVatResponse == null) {
            return ResponseEntity.status(500).build();
        return ResponseEntity.status(200).body(checkVatResponse);

Let’s call our REST API with the VAT number for a well known public company, Volvo.

curl 'http://localhost:8080/vat?countryCode=SE&vatNumber=556012579001'

The response we get indicates the VAT number is valid and gives us some information about the company.

    "countryCode": "SE",
    "vatNumber": "556012579001",
        "value": "Aktiebolaget Volvo",
        "value": "DC 24000 \nARSC2 \n405 08 GÖTEBORG",

Source on GitHub.