KVKBase

Valider un numéro de TVA néerlandais : guide VIES développeur

Comment valider les numéros de TVA (BTW) néerlandais avec l'API VIES : formats courants et schémas d'intégration pour la vérification client et la facturation.

tvabtwviesvalidationconformité

Si votre application gère la facturation, les paiements ou l’intégration de clients pour des entreprises néerlandaises, valider les numéros de TVA n’est pas facultatif. Le droit fiscal européen exige que vous vérifiiez le statut TVA de vos clients professionnels avant d’appliquer le mécanisme d’autoliquidation aux transactions transfrontalières. Si vous vous trompez, vous risquez de devoir la TVA vous-même.

Ce guide présente le format du numéro de TVA (BTW) néerlandais, le fonctionnement de la validation VIES et du code concret pour l’intégrer à votre processus.

Comprendre le format du numéro de TVA néerlandais

Aux Pays-Bas, le numéro de TVA s’appelle BTW-nummer (Belasting Toegevoegde Waarde). Il suit un format précis :

NL + 9 digits + B + 2 digits

Par exemple : NL123456789B01

Voici ce que signifie chaque partie :

  • NL : le préfixe du pays (Pays-Bas)
  • 9 chiffres : dérivés du RSIN de l’entreprise (un numéro d’identification administratif)
  • B : un séparateur fixe qui signifie « BTW »
  • 2 chiffres : un numéro d’ordre, généralement 01 pour l’entité principale

Une même entité juridique peut avoir plusieurs numéros de TVA si elle exploite des divisions distinctes ; les deux derniers chiffres s’incrémentent alors (B02, B03, etc.). C’est peu fréquent, mais bon à savoir.

Validation du format

Avant tout appel d’API, vous pouvez faire un contrôle rapide du format :

function isValidBtwFormat(vatNumber) {
  const pattern = /^NL\d{9}B\d{2}$/;
  return pattern.test(vatNumber.replace(/\s/g, '').toUpperCase());
}

// Exemples
isValidBtwFormat('NL123456789B01'); // true
isValidBtwFormat('NL 1234 5678 9B01'); // true (espaces supprimés)
isValidBtwFormat('DE123456789'); // false (mauvais pays)
isValidBtwFormat('NL12345678B01'); // false (seulement 8 chiffres)

La validation du format détecte immédiatement les erreurs évidentes, sans aller-retour avec l’API. Mais elle ne vous dit pas si le numéro est réellement enregistré et actif. Pour cela, il vous faut VIES.

Qu’est-ce que VIES ?

VIES (VAT Information Exchange System, système d’échange d’informations sur la TVA) est un service exploité par la Commission européenne qui permet de vérifier si un numéro de TVA est valide et actuellement enregistré. Il couvre tous les États membres de l’UE, Pays-Bas compris.

Lorsque vous interrogez VIES avec un numéro de TVA néerlandais, il vous indique :

  • Si le numéro est valide (enregistré et actif)
  • Le nom de l’entreprise associée au numéro
  • L’adresse enregistrée

VIES est la source faisant autorité. Si VIES indique qu’un numéro est valide, vous pouvez appliquer l’autoliquidation en toute confiance.

Le problème de l’utilisation directe de VIES

Le service VIES officiel présente quelques limites pratiques :

  • Fiabilité : le point d’accès SOAP de VIES connaît des indisponibilités régulières, surtout pendant les périodes de déclaration fiscale
  • Vitesse : les temps de réponse varient beaucoup, de moins d’une seconde à plusieurs secondes
  • Limitation du débit : une utilisation intensive peut faire bloquer votre IP sans préavis
  • Interface SOAP : l’API officielle utilise SOAP/XML, peu pratique à manipuler dans les applications modernes

Ces défauts rendent VIES peu fiable comme étape de validation en temps réel dans un tunnel de paiement ou d’intégration.

Valider via l’API KVKBase

KVKBase propose un point d’accès REST qui encapsule VIES avec mise en cache, logique de nouvelle tentative et une interface JSON propre. Vous obtenez ainsi une validation fiable sans avoir à gérer SOAP ni les indisponibilités de VIES :

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.kvkbase.nl/api/v1/vat/NL123456789B01"

Réponse :

{
  "valid": true,
  "vatNumber": "NL123456789B01",
  "tradeName": "Voorbeeld BV",
  "address": "Herengracht 500, 1017CB Amsterdam",
  "countryCode": "NL"
}

Si le numéro est invalide ou radié :

{
  "valid": false,
  "vatNumber": "NL000000000B00",
  "tradeName": null,
  "address": null,
  "countryCode": "NL"
}

Schémas d’intégration

Processus de facturation

Le cas d’usage le plus courant consiste à valider le numéro de TVA d’un client avant d’émettre une facture B2B. Si le client possède un numéro de TVA européen valide et se trouve dans un autre État membre, vous appliquez l’autoliquidation (pas de TVA facturée). Si le numéro est invalide, vous facturez le taux néerlandais standard (21 %).

import requests

API_KEY = "your-api-key"
BASE_URL = "https://api.kvkbase.nl/api/v1"

def validate_vat(vat_number):
    response = requests.get(
        f"{BASE_URL}/vat/{vat_number}",
        headers={"Authorization": f"Bearer {API_KEY}"}
    )
    response.raise_for_status()
    return response.json()

def calculate_vat(amount, customer_vat, seller_country="NL"):
    if not customer_vat:
        # B2C : toujours facturer la TVA
        return amount * 0.21

    result = validate_vat(customer_vat)
    if not result["valid"]:
        raise ValueError(f"Invalid VAT number: {customer_vat}")

    if result["countryCode"] != seller_country:
        # Autoliquidation : numéro de TVA UE valide, autre pays
        return 0.0

    # Même pays : facturer la TVA néerlandaise
    return amount * 0.21

Intégration des clients

Lors de l’inscription, validez le numéro de TVA et utilisez-le pour récupérer des données d’entreprise supplémentaires :

async function onboardCustomer(vatNumber) {
  // Étape 1 : valider la TVA
  const vatResult = await fetch(
    `${BASE_URL}/vat/${vatNumber}`,
    { headers: { 'Authorization': `Bearer ${API_KEY}` } }
  ).then(r => r.json());

  if (!vatResult.valid) {
    return { error: 'Invalid VAT number. Please check and try again.' };
  }

  // Étape 2 : si néerlandais, rechercher aussi les données KVK pour un profil complet
  if (vatResult.countryCode === 'NL') {
    const kvkResult = await fetch(
      `${BASE_URL}/search?q=${encodeURIComponent(vatResult.tradeName)}&limit=1`,
      { headers: { 'Authorization': `Bearer ${API_KEY}` } }
    ).then(r => r.json());

    return {
      vatValid: true,
      companyName: vatResult.tradeName,
      address: vatResult.address,
      kvkNumber: kvkResult[0]?.kvkNumber || null
    };
  }

  return {
    vatValid: true,
    companyName: vatResult.tradeName,
    address: vatResult.address
  };
}

Validation par lots

Si vous devez valider une liste de numéros de TVA (par exemple pour nettoyer votre base clients), parcourez-les avec une limitation de débit :

async function validateBatch(vatNumbers) {
  const results = [];

  for (const vat of vatNumbers) {
    try {
      const result = await fetch(
        `${BASE_URL}/vat/${vat}`,
        { headers: { 'Authorization': `Bearer ${API_KEY}` } }
      ).then(r => r.json());

      results.push({ vat, ...result });
    } catch (err) {
      results.push({ vat, valid: false, error: err.message });
    }

    // Respecter les limites de débit
    await new Promise(resolve => setTimeout(resolve, 100));
  }

  return results;
}

Pièges courants

Quelques éléments qui font trébucher les développeurs travaillant avec des numéros de TVA néerlandais :

  • Espaces dans le numéro. Les utilisateurs saisissent souvent NL 1234 5678 9 B01. Supprimez tous les espaces avant la validation.
  • Saisie en minuscules. nl123456789b01 est le même numéro. Normalisez en majuscules.
  • Confusion entre numéro KVK et numéro de TVA. Un numéro KVK compte 8 chiffres. Un numéro de TVA commence par NL et est plus long. Ce sont deux identifiants différents pour la même entreprise.
  • Validation périmée. Un numéro de TVA valide le mois dernier peut être radié aujourd’hui. Revalidez périodiquement si vous stockez le résultat.
  • Indisponibilité de VIES. Gérez toujours le cas où la validation est temporairement indisponible. Mettez en file d’attente et réessayez plutôt que de bloquer l’utilisateur.

En résumé

La validation de la TVA néerlandaise est indispensable à toute application B2B qui opère dans l’UE. Commencez par la validation du format pour repérer les fautes de frappe, puis utilisez l’API KVKBase pour des contrôles VIES faisant autorité, sans les tracas de SOAP ni les problèmes de fiabilité. Combinez la validation de TVA avec les recherches KVK pour une vue complète de vos clients professionnels néerlandais.

Démarrez avec une clé d’API gratuite sur kvkbase.nl. La référence de l’API documente tous les points d’accès TVA et KVK.