Community Spring Cleaning week is here! Join your fellow Maveryx in digging through your old posts and marking comments on them as solved. Learn more here!

Alteryx Designer Desktop Discussions

Find answers, ask questions, and share expertise about Alteryx Designer Desktop and Intelligence Suite.
SOLVED

Verification VAT numbers VIES website

speedway
7 - Meteor

Hi,

 

I'm trying to create a flow that verifies if a VAT number is active according to the EU website http://ec.europa.eu/taxation_customs/vies/?locale=en

 

They have an API that can be used to verify this: http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

 

I started for this from an other API flow but I do not see how I can reuse this in this case.

 

The enlcosed flow has a VAT number in a second file input file which can be validated via the AP.

 

Thanks for the support.

32 REPLIES 32
KevinP
Alteryx Alumni (Retired)

@speedway Is using a third party API wrapper an option? If so a third party that uses a REST API to provide this same data would be much simpler to develop a workflow for. I was able to find a number of third parties that provide various alternatives to the SOAP API provided by europa.eu for VIES VAT validation. Using one of these third parties I was able to toss together a simple REST API example (See attached). The third party provider I used was isvat.eu and per their documentation all the data returned comes from the VIES VAT Validation System.

 

If using a third party is not an option the options to use eurpopa.eu's SOAP API would be to either mimic the form data submitted by their web form. This would require capturing network traffic for a successful form submission and indepth review of their html for the web form to piece the process together. The other option would be to develop a direct SOAP API integration which would require detailed documentation of the API and knowledge of how SOAP API's work. From looking at the information available it seems most of the SOAP API documentation is in the WSDL file rather than documented on their website. My experience with SOAP API's is also limited so I wasn't able to piece together a working example for you.

speedway
7 - Meteor

Thanks for the response, this indeed works however, the amount of checks is limited to only 1.000 per month (which is unfortunately to limited for the project I'm working on).

 

As this is connecting to the official VIES website, I guess it should be possible to also connect to the VIES website directly.

 

I know that our accounting software (MS Dynamics NAV) has a connector directly to the VIES website, that's probably the SOAP API option you are referring to.

 

I'm able to get some response using the XML Parse but nothing I can work with.

 

speedway
7 - Meteor

Postman gives me the following information for the link http://ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl but I do not know how to setup a correct flow to verify a VAT number (e.g. BE 0462.525.791)

 

 

 

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:ec.europa.eu:taxud:vies:services:checkVat" xmlns:tns1="urn:ec.europa.eu:taxud:vies:services:checkVat:types" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:impl="urn:ec.europa.eu:taxud:vies:services:checkVat" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/">
  <xsd:documentation>
     Specific disclaimer for this service ----------------------------------------- 
     Here is the list of VAT Number to use to receive each kind of answer : 
		100 = Valid request with Valid VAT Number
		200 = Valid request with an Invalid VAT Number
		201 = Error : INVALID_INPUT
		202 = Error : INVALID_REQUESTER_INFO
		300 = Error : SERVICE_UNAVAILABLE
		301 = Error : MS_UNAVAILABLE
		302 = Error : TIMEOUT
		400 = Error : VAT_BLOCKED
		401 = Error : IP_BLOCKED
		500 = Error : GLOBAL_MAX_CONCURRENT_REQ
		501 = Error : GLOBAL_MAX_CONCURRENT_REQ_TIME
		600 = Error : MS_MAX_CONCURRENT_REQ
		601 = Error : MS_MAX_CONCURRENT_REQ_TIME
		
		For all the other cases, The web service will responds with a "SERVICE_UNAVAILABLE" error.
    </xsd:documentation>
  
  <wsdl:types>
    <xsd:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="urn:ec.europa.eu:taxud:vies:services:checkVat:types" xmlns="urn:ec.europa.eu:taxud:vies:services:checkVat:types">
            <xsd:element name="checkVat">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="countryCode" type="xsd:string"/>
                        <xsd:element name="vatNumber" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="checkVatResponse">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="countryCode" type="xsd:string"/>
                        <xsd:element name="vatNumber" type="xsd:string"/>
                        <xsd:element name="requestDate" type="xsd:date"/>
                        <xsd:element name="valid" type="xsd:boolean"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="name" nillable="true" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="address" nillable="true" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="checkVatApprox">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="countryCode" type="xsd:string"/>
                        <xsd:element name="vatNumber" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderName" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderCompanyType" type="tns1:companyTypeCode"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderStreet" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderPostcode" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderCity" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="requesterCountryCode" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="requesterVatNumber" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="checkVatApproxResponse">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="countryCode" type="xsd:string"/>
                        <xsd:element name="vatNumber" type="xsd:string"/>
                        <xsd:element name="requestDate" type="xsd:date"/>
                        <xsd:element name="valid" type="xsd:boolean"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderName" nillable="true" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderCompanyType" nillable="true" type="tns1:companyTypeCode"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderAddress" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderStreet" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderPostcode" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderCity" type="xsd:string"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderNameMatch" type="tns1:matchCode"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderCompanyTypeMatch" type="tns1:matchCode"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderStreetMatch" type="tns1:matchCode"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderPostcodeMatch" type="tns1:matchCode"/>
                        <xsd:element maxOccurs="1" minOccurs="0" name="traderCityMatch" type="tns1:matchCode"/>
                        <xsd:element name="requestIdentifier" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:simpleType name="companyTypeCode">
                <xsd:restriction base="xsd:string">
                    <xsd:pattern value="[A-Z]{2}\-[1-9][0-9]?"/>
                </xsd:restriction>
            </xsd:simpleType>
            <xsd:simpleType name="matchCode">
                <xsd:restriction base="xsd:string">
                    <xsd:enumeration value="1">
                        <xsd:annotation>
                            <xsd:documentation>VALID</xsd:documentation>
                        </xsd:annotation>
                    </xsd:enumeration>
                    <xsd:enumeration value="2">
                        <xsd:annotation>
                            <xsd:documentation>INVALID</xsd:documentation>
                        </xsd:annotation>
                    </xsd:enumeration>
                    <xsd:enumeration value="3">
                        <xsd:annotation>
                            <xsd:documentation>NOT_PROCESSED</xsd:documentation>
                        </xsd:annotation>
                    </xsd:enumeration>
                </xsd:restriction>
            </xsd:simpleType>
        </xsd:schema>
  </wsdl:types>
  <wsdl:message name="checkVatRequest">
    <wsdl:part name="parameters" element="tns1:checkVat">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="checkVatApproxResponse">
    <wsdl:part name="parameters" element="tns1:checkVatApproxResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="checkVatApproxRequest">
    <wsdl:part name="parameters" element="tns1:checkVatApprox">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="checkVatResponse">
    <wsdl:part name="parameters" element="tns1:checkVatResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="checkVatPortType">
    <wsdl:operation name="checkVat">
      <wsdl:input name="checkVatRequest" message="impl:checkVatRequest">
    </wsdl:input>
      <wsdl:output name="checkVatResponse" message="impl:checkVatResponse">
    </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="checkVatApprox">
      <wsdl:input name="checkVatApproxRequest" message="impl:checkVatApproxRequest">
    </wsdl:input>
      <wsdl:output name="checkVatApproxResponse" message="impl:checkVatApproxResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="checkVatTestBinding" type="impl:checkVatPortType">
    <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="checkVat">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="checkVatRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="checkVatResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="checkVatApprox">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="checkVatApproxRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="checkVatApproxResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="checkVatTestService">
    <wsdl:port name="checkVatPort" binding="impl:checkVatTestBinding">
      <wsdlsoap:address location="http://ec.europa.eu/taxation_customs/vies/services/checkVatTestService"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
KevinP
Alteryx Alumni (Retired)

@speedway the wsdl document just describes the soap api. Think of it as the help manual. It provides information on the the available endpoints, what each endpoint expects for input, and possible responses. The xml returned by postman and the download tool when accessing this URL isn't helpful beyond this and won't return the VAT validation you are looking for. If I have some time I will see if I can get a working SOAP example created. Please keep in mind though that this will take a lot more effort to get working than the REST example I provided, and in the mean time it might be worth while to see if there is another REST API wrapper for the VIES validation service.

speedway
7 - Meteor

thanks for the effort Kevin, I will definitely have a look.

 

Kr,

 

Tom

KevinP
Alteryx Alumni (Retired)

@speedway So I spent some time with the SOAP api this morning. After going through the WSDL and some examples I found online I was able to get a working SOAP request without having to replicate the form data used by the interactive website. The example injects the VAT number and country code into an XML request body for the SOAP api and passes it to the VIES service. The response back is an XML response with the validation information. I didn't bother parsing the response so you will need to do that on your own but this example should at least get you started with the SOAP api instead of using the alternative REST provider I originally recommended. 

speedway
7 - Meteor

Great! thank you for your time!

ck2019
9 - Comet

Hello  - just stumbled on this when searching for VAT related use cases and I really like this one.

 

I wasn't quite sure how to make this work for multiple VAT numbers and I wondered if you had developed this process further since posting and would be happy to share your workflow if so?  Thanks a lot

Mahadevaswamyb
7 - Meteor

@KevinP this is really a great effort and helps lot if Indirect Tax teams, and can enhance the scope if it works to check the multiple VAT Id validation and download the data into form.

Labels