Vérifier un numéro de TVA belge avec VIES : guide pas à pas
Vérifier un numéro de TVA belge avec VIES : contrôle du format, dérivation, interprétation du résultat, preuve conservée et code curl et JavaScript.
Avant de facturer sans TVA une société d’un autre État membre, ou d’enregistrer un nouveau fournisseur, vous devez savoir si son numéro de TVA est valide. Pour la Belgique, le contrôle tient en quelques étapes : un test de format local, la dérivation du numéro à partir du numéro d’entreprise, puis une interrogation de VIES, le service de la Commission européenne. Ce guide détaille chaque étape, ce que le résultat signifie et ce qu’il ne dit pas.
Étape 1 : contrôler le format
Un numéro de TVA belge se compose de BE suivi de 10 chiffres. Le premier chiffre est 0 ou 1. Avant d’appeler un service, éliminez les erreurs évidentes :
- retirez les espaces, points et tirets (
BE 0123.456.789devientBE0123456789) ; - si vous avez 9 chiffres (anciens numéros ou zéro perdu dans un tableur), ajoutez un
0devant ; - vérifiez la paire de contrôle : les deux derniers chiffres valent 97 moins le reste de la division des huit premiers chiffres par 97.
Les numéros de cet article sont illustratifs. Remplacez-les par un numéro réel que vous avez reçu de votre contact.
function parseBelgianVat(input) {
let digits = String(input).toUpperCase().replace(/^BE/, "").replace(/\D/g, "");
if (digits.length === 9) digits = "0" + digits;
if (!/^[01]\d{9}$/.test(digits)) return null;
const checksumOk = 97 - (Number(digits.slice(0, 8)) % 97) === Number(digits.slice(8));
return { vatNumber: `BE${digits}`, enterpriseNumber: digits, checksumOk };
}
Si checksumOk vaut false, arrêtez-vous là : le numéro est mal saisi. Cela évite un appel inutile. L’API fait la même vérification et rejette un numéro mal formé avant toute recherche, sans consommer de token.
Étape 2 : dériver le numéro de TVA candidat
Si votre contact ne vous a fourni que le numéro d’entreprise, le numéro de TVA se déduit en ajoutant BE. Le résultat n’est qu’un candidat : toutes les entreprises n’ont pas de TVA active. C’est le cas de certaines ASBL, de certaines professions exemptées et des indépendants sous le régime de la franchise. La différence est expliquée dans numéro d’entreprise et numéro de TVA : la différence.
Étape 3 : interroger VIES
Vous pouvez interroger VIES directement sur le site de la Commission, ou passer par l’outil gratuit vérifier un numéro de TVA. Pour automatiser, l’API de KVKBase expose un endpoint dédié :
curl -s "https://api.kvkbase.nl/v1/be/validate/vat/BE0821015819" \
-H "Authorization: Bearer YOUR_API_KEY"
La réponse contient vatNumber, valid, name, address, validatedAt et status. Une validation coûte 1 token, comme une consultation ou une recherche. Le plan gratuit offre 50 tokens par mois sans carte bancaire : créez un compte pour obtenir une clé.
En JavaScript :
async function validateVat(vatNumber) {
const res = await fetch(
`https://api.kvkbase.nl/v1/be/validate/vat/${encodeURIComponent(vatNumber)}`,
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
const body = await res.json();
if (!res.ok) {
const code = body.error?.code ?? `HTTP_${res.status}`;
const retryable = ["UPSTREAM_ERROR", "UPSTREAM_BUDGET", "QUOTA_EXCEEDED"].includes(code);
return { ok: false, code, retryable };
}
return { ok: true, result: body };
}
Si vous avez déjà besoin de la fiche complète, la consultation GET /v1/be/lookup/{numero} renvoie aussi un objet vat avec number, valid, status, validatedAt et checksumValid. Un seul appel peut donc suffire, voir rechercher un numéro d’entreprise belge.
Étape 4 : interpréter le résultat
| Résultat | Signification | Action |
|---|---|---|
valid: true | Le numéro est enregistré comme numéro de TVA actif | Comparez name et address avec ce que votre client a indiqué, puis conservez le résultat |
valid: false | Le numéro n’est pas un numéro de TVA actif | Demandez un autre numéro, ou vérifiez si l’entreprise est exemptée de TVA |
| Erreur 502 ou 503 | Le service sous-jacent est indisponible ou limité | Réessayez plus tard (voir plus bas) |
| Erreur 400 | Numéro mal formé | Corrigez la saisie, aucun coût |
Pour la Belgique, VIES renvoie en général aussi la dénomination et l’adresse. Comparez-les avec les informations de votre contrat ou de votre bon de commande. Une différence de nom n’est pas forcément une anomalie (dénomination commerciale, société rebaptisée), mais elle mérite une question.
Ce que VIES dit, et ce qu’il ne dit pas
VIES répond à une seule question : ce numéro est-il actuellement valide ? Il ne dit pas :
- que l’entreprise est solvable ou en bonne santé financière ;
- que la personne qui vous écrit est bien celle qu’elle prétend être : quelqu’un peut utiliser le numéro d’une autre société ;
- que le numéro était valide à une date passée : la réponse vaut pour le moment de l’interrogation.
Pour la situation de l’entreprise, regardez isActive et juridicalSituation dans la consultation (situation normale, en liquidation, faillite, dissolution…). Pour une certitude juridique, une vérification dans les publications officielles, comme le Moniteur belge, reste nécessaire. Ces données aident au tri, sans garantie de complétude ni de temps réel. Sur ce sujet plus large, lisez vérifier un client ou un fournisseur belge.
Livraisons intracommunautaires : vérifier et conserver la preuve
Quand vous livrez des biens à une entreprise d’un autre État membre sans TVA, la validité de son numéro est un élément central du dossier. En pratique, vérifiez le numéro au moment de la transaction et gardez la trace du contrôle : sans preuve, vous aurez du mal à démontrer votre bonne foi lors d’un contrôle fiscal. Les règles détaillées dépendent de votre situation, donc confirmez-les avec votre comptable ou votre conseiller fiscal.
Ce que vous devriez stocker pour chaque contrôle :
| Champ | Exemple |
|---|---|
| Numéro vérifié | BE0123456789 (illustratif) |
| Résultat | valid: true |
| Date et heure du contrôle | validatedAt renvoyé par l’API |
| Nom et adresse renvoyés | tels que reçus |
| Transaction liée | numéro de facture ou de commande |
Conservez la réponse brute (JSON) à côté d’un horodatage, et ne la réécrivez jamais. Une nouvelle vérification crée une nouvelle ligne.
Gérer les pannes de VIES
VIES peut être indisponible ou limité pour un État membre, parfois pendant plusieurs heures. Une panne n’est pas un résultat négatif. Une approche prudente :
- Distinguez une réponse
valid: falsed’une erreur technique (502 ou 503). - Réessayez avec un délai croissant : par exemple 1 minute, 5 minutes, puis 30 minutes.
- Si la panne dure, bloquez l’opération sensible (la livraison sans TVA) plutôt que de la valider sans contrôle.
- Enregistrez chaque tentative avec sa date, y compris les échecs.
async function validateWithRetry(vatNumber, attempts = 4) {
for (let i = 0; i < attempts; i++) {
const r = await validateVat(vatNumber);
if (r.ok || !r.retryable) return { ...r, checkedAt: new Date().toISOString() };
await new Promise((resolve) => setTimeout(resolve, 2 ** i * 60_000));
}
return { ok: false, code: "VIES_UNAVAILABLE", checkedAt: new Date().toISOString() };
}
Pour traiter beaucoup de numéros à la fois, voyez intégrer une API de données d’entreprises belges. Les tarifs sont sur la page prix et la référence complète dans la documentation de l’API.