Rule reference

BR-CO-09 VAT identifiers must carry a country prefix

BT-31, BT-48 and BT-63 must start with the ISO 3166-1 alpha-2 code of the issuing country — with one famous exception: Greece uses EL, not GR.

Business term
BT-31 — Seller / buyer VAT identifier
Severity
fatal
Applies to
All profiles

What the rule requires

The seller VAT identifier (BT-31), the seller tax representative VAT identifier (BT-63) and the buyer VAT identifier (BT-48) must each start with the ISO 3166-1 alpha-2 code of the country that issued them: DE123456789, FR12345678901, NL123456789B01.

Greece is the one exception, and it is worth remembering. Greek VAT numbers carry the prefix EL, not the country’s ISO code GR. That mismatch long predates EN 16931, and the rule text calls it out explicitly.

One scoping note, so you look in the right place: this rule is only about the shape of an identifier that is already there. Whether a VAT identifier is required at all is decided by the VAT-category rules (BR-S-02, BR-AE-02, BR-IC-02 and the rest).

The Seller VAT identifier (BT-31), the Seller tax representative VAT identifier (BT-63) and the Buyer VAT identifier (BT-48) shall have a prefix in accordance with ISO code ISO 3166-1 alpha-2 by which the country of issue may be identified. Nevertheless, Greece may use the prefix 'EL'.

BR-CO-09 — EN 16931-1 conditions and calculations, via Peppol BIS Billing 3.0

Why it exists

The prefix is the thing that makes a VAT number resolvable at all. The same digits can be a valid identifier in two different member states, and VIES — the EU validation service — is keyed on country plus number. Strip the prefix and neither the buyer’s system nor a tax authority can tell which register to look in, so the identifier cannot do the one job it exists for. The prefix is also how a receiving system works out whether a supply is domestic or cross-border, and that changes the VAT treatment.

What the library returns

The exact object in result.errors when this rule fires. Generated by running @attestwire/en16931, not transcribed:

TeachingError
{
  "rule": "BR-CO-09",
  "field": "BT-31",
  "severity": "fatal",
  "message": "The seller VAT identifier (BT-31) must start with a country prefix in accordance with ISO 3166-1 alpha-2, but \"123456789\" does not. Greece is the one exception: it uses the prefix \"EL\" rather than \"GR\".",
  "fix": "Prefix the number with the issuing country's two-letter code — a German number 123456789 becomes \"DE123456789\". Store it prefixed; do not add the prefix only at render time.",
  "example": "\"vatId\": \"DE123456789\"",
  "xpath": "/ubl:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID",
  "docsUrl": "https://attestwire.com/rules/BR-CO-09"
}

xpath locates the element in the generated UBL document, which is where a KoSIT or Peppol validator will report the same problem.

Failing and passing

Fails — seller VAT ID stored without its prefix
validateInput({
  // ...
  seller: {
    name: "Acme GmbH",
    vatId: "123456789",        // <- BR-CO-09, no country prefix
    address: { city: "Berlin", postalCode: "10115", countryCode: "DE" },
  },
  // ...
});
// -> { valid: false, errors: [ { rule: "BR-CO-09", field: "BT-31", ... } ] }
Passes
validateInput({
  // ...
  seller: {
    name: "Acme GmbH",
    vatId: "DE123456789",      // prefix + national number, one string
    address: { city: "Berlin", postalCode: "10115", countryCode: "DE" },
  },
  // ...
});
// -> { valid: true, errors: [] }

The fix, in plain English

Store VAT identifiers prefixed, as one single string, everywhere in your system. Splitting them into a country column and a number column is the usual root cause of a stripped prefix — one code path reassembles them and another quietly forgets. And if your seller is Greek, the stored prefix is EL even though the country code in the postal address (BT-40) is GR. Those two fields disagreeing is correct here, so watch out: a well-meaning “consistency” check in your own code will break the invoice.

How our check differs

Two gaps here, both narrower than they sound. First, we check BT-31 and BT-48 but not BT-63, because the input model has no tax-representative party (BG-11) yet. Second, the prefix test accepts any two ASCII letters plus EL — so XX123456789 passes here and then fails at a real validator. We do not currently check the prefix against the ISO 3166-1 list, or against the country in the postal address.

Arrived from a stack trace? The docsUrl on every error links straight here. Something wrong on this page — tell us.