BTW Nummer Valideren met VIES: Zo Doe Je Dat Programmatisch
· KVKBase Team

BTW Nummer Valideren met VIES: Zo Doe Je Dat Programmatisch

Leer hoe je Nederlandse en Europese BTW-nummers valideert via de VIES API. Inclusief code voorbeelden, foutafhandeling en caching strategieen.

btwviesvalidatie

BTW Nummer Valideren met VIES: Zo Doe Je Dat Programmatisch

Als je een B2B-platform bouwt of facturen verwerkt binnen de EU, ontkom je niet aan BTW-nummervalidatie. Het is niet alleen een technische vereiste, maar ook een wettelijke. Bij intracommunautaire leveringen moet je het BTW-nummer van je klant verplicht controleren.

In dit artikel leggen we uit hoe het VIES-systeem werkt, hoe je het programmatisch aanspreekt en welke valkuilen je kunt vermijden.

Wat is VIES?

VIES staat voor VAT Information Exchange System. Het is een dienst van de Europese Commissie waarmee je kunt controleren of een BTW-nummer geldig en actief is. Elke EU-lidstaat levert zijn eigen data aan het systeem.

Als je een BTW-nummer controleert via VIES, krijg je terug:

  • Of het nummer geldig is (ja/nee)
  • De naam van het bedrijf (in de meeste landen)
  • Het adres van het bedrijf (in de meeste landen)

Het format van een Nederlands BTW-nummer

Een Nederlands BTW-nummer volgt een specifiek format:

NL + 9 cijfers + B + 2 cijfers
Voorbeeld: NL123456789B01

Voordat je een aanvraag naar VIES stuurt, kun je lokaal al het format controleren:

function isValidDutchVatFormat(vatNumber) {
  return /^NL\d{9}B\d{2}$/.test(vatNumber.replace(/[\s.]/g, ''));
}

// Voorbeelden
isValidDutchVatFormat("NL123456789B01"); // true
isValidDutchVatFormat("NL12345678B01");  // false (te weinig cijfers)
isValidDutchVatFormat("DE123456789");    // false (niet Nederlands)

Andere EU-landen hanteren hun eigen format. Duitsland gebruikt DE + 9 cijfers, Belgie BE + 10 cijfers, enzovoort.

VIES API aanspreken

De Europese Commissie biedt een REST API aan voor VIES-validatie:

curl -X POST "https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number" \
  -H "Content-Type: application/json" \
  -d '{
    "countryCode": "NL",
    "vatNumber": "123456789B01"
  }'

Het antwoord ziet er ongeveer zo uit:

{
  "isValid": true,
  "requestDate": "2025-10-21",
  "userError": "VALID",
  "name": "VOORBEELD B.V.",
  "address": "VOORBEELDSTRAAT 1\n1234AB AMSTERDAM",
  "requestIdentifier": ""
}

JavaScript implementatie

async function validateVatNumber(countryCode, vatNumber) {
  const response = await fetch(
    'https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ countryCode, vatNumber })
    }
  );

  if (!response.ok) {
    throw new Error(`VIES API error: ${response.status}`);
  }

  return response.json();
}

// Gebruik
const result = await validateVatNumber('NL', '123456789B01');
if (result.isValid) {
  console.log(`Geldig! Bedrijf: ${result.name}`);
} else {
  console.log('Ongeldig BTW-nummer');
}

Veelvoorkomende problemen met VIES

1. Downtime en beschikbaarheid

VIES is afhankelijk van de systemen van elke lidstaat. Het komt regelmatig voor dat een specifiek land tijdelijk niet beschikbaar is. Je krijgt dan een foutmelding als MS_UNAVAILABLE of SERVICE_UNAVAILABLE.

Dit betekent niet dat het nummer ongeldig is — het betekent dat de controle op dat moment niet uitgevoerd kan worden.

2. Timeouts

De VIES API kan traag reageren, soms tot 10 seconden of langer. Stel een ruime timeout in en informeer je gebruikers dat de validatie even kan duren:

const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 15000);

try {
  const response = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ countryCode, vatNumber }),
    signal: controller.signal
  });
  // verwerk response
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('VIES timeout - probeer het later opnieuw');
  }
} finally {
  clearTimeout(timeout);
}

3. Rate limiting

VIES heeft geen officieel gedocumenteerde rate limits, maar bij veel aanvragen in korte tijd kun je geblokkeerd worden. Bouw altijd een wachtrij in bij bulkvalidaties.

Caching strategie

Omdat VIES-validatie traag en onbetrouwbaar kan zijn, is caching essentieel:

async function cachedVatValidation(countryCode, vatNumber) {
  const cacheKey = `vat:${countryCode}:${vatNumber}`;
  const cached = await cache.get(cacheKey);

  if (cached) {
    const age = Date.now() - cached.timestamp;
    // Geldige nummers: cache 7 dagen
    // Ongeldige nummers: cache 1 uur (kan tijdelijk zijn)
    const maxAge = cached.isValid ? 7 * 86400000 : 3600000;
    if (age < maxAge) return cached;
  }

  const result = await validateVatNumber(countryCode, vatNumber);
  await cache.set(cacheKey, { ...result, timestamp: Date.now() });
  return result;
}

De logica hierachter: een geldig BTW-nummer verandert zelden van status, dus een cache van 7 dagen is veilig. Een ongeldig resultaat kan veroorzaakt zijn door downtime, dus die cache je korter.

Waarom BTW-validatie ertoe doet

BTW-validatie is niet optioneel voor B2B-transacties binnen de EU. Bij intracommunautaire leveringen (ICL) moet je:

  1. Het BTW-nummer van je klant verplicht verifiieren
  2. Het geverifieerde nummer op je factuur vermelden
  3. De ICL-opgave correct indienen bij de Belastingdienst

Zonder geldige verificatie loop je het risico dat je alsnog BTW moet afdragen over de levering.

Combineer KVK en BTW-validatie

In de praktijk wil je vaak zowel het KVK-nummer als het BTW-nummer van een Nederlands bedrijf valideren. Met KVKBase kun je dit combineren in een enkele flow: zoek het bedrijf op via KVK-nummer, en je krijgt het bijbehorende BTW-nummer direct terug. Daarna kun je het BTW-nummer valideren via VIES voor de EU-registratie.

Conclusie

BTW-nummervalidatie via VIES is onmisbaar voor elke B2B-applicatie die binnen de EU opereert. De API is gratis en openbaar, maar niet altijd betrouwbaar. Investeer in goede foutafhandeling, caching en een fallback-strategie om je gebruikers een betrouwbare ervaring te bieden.

Door KVK-lookups en BTW-validatie te combineren, dek je zowel de Nederlandse bedrijfsregistratie als de EU-brede belastingidentificatie af in een enkele flow.