Skip to main content

Patterns

Intra-EU VAT and reverse charge

Authoritative server-side VAT category resolution and legal mentions

For a B2B intra-EU sale, VAT is in principle reverse-charged by the buyer: the seller invoices ex-VAT and adds a legal mention. Scell.io resolves the VAT category SERVER-side authoritatively (`buyers.vatContext`) by rules: VAT-exempt regime (CGI 293 B) → category E, intra-EU goods → K, intra-EU services → AE (reverse charge, art. 196 of directive 2006/112/EC), non-EU export → G. Resolution relies on the buyer's VAT status (VIES-checked) and the supply type (goods/services). Anti-pattern: trusting a client-supplied VAT category without control — the API returns a 409 `VAT_CORRECTION_REQUIRED` if the submitted category diverges from the authoritative resolution, unless a traced override (`vat_override_reason`) is provided. The emitted Factur-X then carries the BT-118 category code and the matching CGI/directive mention (BT-120), bilingual per the buyer's language.

Key facts

  • Authoritative server-side VAT resolution (`buyers.vatContext`)
  • Categories: E (293 B exempt), K (EU goods), AE (EU services), G (export)
  • Buyer VAT status checked via VIES
  • Guard 409 `VAT_CORRECTION_REQUIRED` on divergence (traced override)
  • Factur-X: BT-118 code + bilingual CGI/directive mention BT-120
  • EU services reverse charge = art. 196 of directive 2006/112/EC

Code example

import { ScellApiClient } from '@scell/sdk'; // v3.5.0

const client = new ScellApiClient({ apiKey: process.env.SCELL_API_KEY! });

// 1. Résolution autoritaire de la catégorie TVA pour un acheteur UE
const vat = await client.buyers.vatContext('buyer-uuid', {
  // type de fourniture : biens (goods) ou services
  supply_type: 'services',
});
console.log('Catégorie TVA résolue :', vat.category, '→ taux', vat.rate);
// services intra-UE → 'AE' (autoliquidation), taux 0

// 2. Facturer : laisser le serveur appliquer la catégorie autoritaire.
//    Soumettre une catégorie divergente → 409 VAT_CORRECTION_REQUIRED.
const invoice = await client.invoices.create({
  format: 'factur-x',
  profile: 'EN16931',
  currency: 'EUR',
  buyer: {
    name: 'Müller GmbH',
    vat_number: 'DE123456789',
    address: { street: 'Hauptstr. 1', city: 'Berlin', postal_code: '10115', country: 'DE' },
  },
  lines: [{ description: 'Prestation de conseil', quantity: 1, unit_price: 3000, vat_rate: 0 }],
  // Factur-X émis avec BT-118='AE' + mention autoliquidation BT-120
});
console.log('Facture autoliquidée :', invoice.id);

See also

Your cookie preferences

We use cookies to improve your experience. Essential cookies are always active. Cookie policy.