Umsatzsteuer-Identifikationsnummer prüfen: Automatisierte Überprüfung mit PHP-Script und VIES-System

Technik
Umsatzsteuer-Identifikationsnummer prüfen: Automatisierte Überprüfung mit PHP-Script und VIES-System

Als Webshop-Betreiber ist es wichtig, die Umsatzsteuer-Identifikationsnummer (UID-Nummer, USt.-ID Nummer) von Geschäftskunden zu prüfen. Oftmals wird dies vom Gesetz vorgeschrieben, zum Beispiel bei innergemeinschaftlichen Lieferungen.

Eine manuelle Überprüfung ist mithilfe einer Website der EU möglich, dem sogenannten VIES System: VAT Information Exchange Service. Auf Deutsch: MwSt-Informationsaustauschsystem (MIAS). Die manuelle Prüfung kann man auf der offiziellen Website der EU (http://ec.europa.eu/taxation_customs/vies/) durchführen oder mit meinem viel benutzerfreundlicheren und kostenlosen USt.-ID-Tool prüfen Tool.

USt.-ID PHP Script

Besser ist es natürlich, wenn man die Überprüfung automatisieren kann. Dafür gibt es eine WSDL (Web Services Description Language) Schnittstelle, die einfach mittels PHP SOAP angesprochen werden kann.

Seit 2021 findet ihr hier 2 Skriptbeispiele. Einmal für das moderne und weit verbreitete Symfony Framework und einmal eine pure PHP Version für alle anderen Frameworks und CMS-Systeme.

Symfony

Einfach einen Controller erstellen, welcher bei entsprechender Anfrage, ein JSON Objekt zurückgibt: /vatid/api?vatid={VATID}. Durch die Beliebtheit von JavaScript ist eine solch dynamische Rückgabe höchst attraktiv und eignet sich hervorragend um die Validierung auch gleich visuell bei der Eingabe darzustellen.

/**
 * @Route("/vatid", name="vatid", methods={"GET"})
 * @Route("/vatid/api", name="vatid_api", methods={"GET"}, requirements={"_format": "json"}, defaults={"_format": "json"})
 * @return Response
 */
public function vatid(Request $request, $_format = 'html'): Response
{

    if ($_format == 'json') {

        $vatid = $request->query->getAlnum('vatid'); // The EU Vat Id

        try {
            // a valid vat id consists of an alpha country code and up to 12 alphanumeric characters
            $vatidRegex = "/^[a-z]{2}[a-z0-9]{0,12}$/i";

            if (preg_match($vatidRegex, $vatid) !== 1) {
                throw new InvalidVatIdException('Invalid Vat Id Format');
            }

            $client = new \SoapClient("https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl");

            // using checkVatApprox() as it tends to return a bit more information than checkVat()
            $params = [
                'countryCode' => substr($vatid, 0, 2),
                'vatNumber' => substr($vatid, 2),
            ];
            $result = $client->checkVatApprox($params);

        } catch (InvalidVatIdException $exception) {
            $result = [
                'error' => 'Ungültiges UID Nummer Format'
            ];
        } catch (\SoapFault $exception) {
            $result = [
                'error' => 'Der USt.-Service der EU scheint gerade nicht erreichbar zu sein'
            ];
        }

        // you may now check for $result->isValid, or you can print all the result fields by using print_r($result)
        // in this case, i simply return a json
        $response = new Response();
        $response->setContent(json_encode($result));

        return $response;
    }

    return $this->render('tools/vatid.html.twig', [
    ]);

}

...
class InvalidVatIdException extends \Exception
{

}

Mit der JavaScripts fetch api kann man dann einfach die Daten abrufen:

fetch(`/vatid/api?vatid=${vatid}`,
{
    headers: {
        'Content-Type': 'application/json'
    }
})
.then(response => {
    if (response.status === 200) {
        return response.json();
    } else {
        alert('Ungültiger Status')
    }
})
.then(data => {
    if (data.error) {
        alert(data.error);
    } else {
        // do something with your result data
        console.log(data);

    }
})

Pure PHP Version

Eine einfache pure PHP Variante des Scripts für ältere Seiten oder andere Frameworks, bei der nur die $vatid Variable durch den entsprechenden String ersetzt werden muss.

try {
    $vatid = "ATU123456789";

    $vatid = preg_replace("/[^a-zA-Z0-9]]/", "", $vatid); // remove non alphanum characters

    // a valid vat id consists of an alpha country code and up to 12 alphanumeric characters
    $vatidRegex = "/^[a-z]{2}[a-z0-9]{0,12}$/i";

    if (preg_match($vatidRegex, $vatid) !== 1) {
        throw new \Exception('Invalid Vat Id Format');
    }

    $client = new \SoapClient("https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl");

    // using checkVatApprox() as it tends to return a bit more information than checkVat()
    $params = [
        'countryCode' => substr($vatid, 0, 2),
        'vatNumber' => substr($vatid, 2),
    ];
    $result = $client->checkVatApprox($params);

    if ($result->valid) {
        // VAT ID is valid
        echo 'Valid';
        print_r($result);
    } else {
        // VAT ID is NOT valid
        echo 'Invalid';
    }

} catch (\Exception $exception) {
    echo 'Es ist ein Fehler aufgetreten!';
}
Permalink: https://to.ptmr.io/1oY7UET