You land your first EU B2B customer on a Friday afternoon. Stripe checkout works, the invoice pipeline exists, and you think the only missing field is “company identification number.”
Then the customer asks for reverse charge treatment, gives you a VAT number that looks valid enough, and your clean billing flow turns into a compliance problem.
That's the trap behind the question what is a company identification number. In practice, it isn't one thing. It's a bucket term for several identifiers that come from different authorities, use different formats, and serve different jobs in tax, invoicing, registration, and supplier verification. If you're building SaaS billing for EU business customers, the hard part isn't defining the acronym soup. The hard part is deciding which identifier matters at which point in your flow, then validating it in a way that won't break checkout when an upstream government service has a bad day.
Most explainers stop at definitions. That's not enough when you need to decide whether to charge VAT, what to print on an invoice, and how to handle a timeout from VIES without blocking a legitimate customer. The engineering problem is bigger than the glossary.
Table of Contents
- Your First EU Customer Is a Compliance Challenge
- Decoding Company IDs vs VAT Numbers and Tax IDs
- A Tour of Global and Country-Specific ID Formats
- Why ID Validation Is Critical for EU SaaS Billing
- How to Validate Company IDs Programmatically
- API Validation Best Practices and Error Handling
Your First EU Customer Is a Compliance Challenge
A common path looks like this. You sell to domestic customers first, your billing logic is simple, and “business customer” mostly means adding a company name field to the checkout form. Then an EU buyer enters a VAT number and expects you not to charge local VAT because the purchase qualifies as a cross-border B2B transaction.
At that point, your code has to answer a question your UI never framed correctly. What did the customer provide? A local company registration number? A tax number? A VAT number? A legal entity identifier used somewhere else in their finance stack?
The field name is already wrong
“Company identification number” sounds singular, but the underlying reality is plural. Different countries issue different identifiers for incorporation, tax administration, and VAT registration. Some are useful for identity resolution. Some are useful for invoicing. Some are only meaningful inside one jurisdiction.
If your payload just stores company_id: "12345678", you've already thrown away context your system will need later.
Practical rule: Never store the raw value alone. Store the identifier type, issuing country, original input, normalized value, validation state, and timestamp of the last check.
That matters because billing decisions are stateful. A value that looked acceptable during signup may not be enough when you generate an invoice, process a refund, or respond to an audit request from finance.
Billing logic and compliance logic are not the same
Developers often start with format validation because it's cheap. Regex the string, maybe trim spaces, maybe uppercase the prefix, and move on. That works for frontend hygiene. It doesn't work for tax treatment.
For EU B2B billing, you usually need a validation flow that distinguishes at least three outcomes:
- Valid for tax purposes right now
- Invalid or malformed
- Temporarily unverifiable because the authority or network is unavailable
Those aren't the same business outcome. The first may allow reverse charge treatment. The second should usually block exemption. The third needs fallback logic instead of a brittle hard fail.
The term company identification number is useful as a starting label. It's a bad implementation model. Once money, invoices, and tax rules enter the picture, you need a more explicit schema than one generic field and one green checkmark.
Decoding Company IDs vs VAT Numbers and Tax IDs
The cleanest way to think about business identifiers is to compare them to personal documents. A person can have a birth certificate, a tax number, and a driver's license. Each identifies the same person from a different angle, but they aren't interchangeable.
Businesses work the same way.

Company ID usually means registration identity
A company identification number often refers to the legal registration number assigned when an entity is incorporated or entered into an official register. This is the “you exist as an entity” identifier.
That number is useful for legal lookup, contracts, procurement forms, and registry searches. It's often country-specific and tied to a domestic authority. In many systems, it's stable and long-lived, which makes it good for entity matching and terrible as a shortcut for tax status.
A company can have a valid registration number and still fail the tax check you need for cross-border invoicing.
Tax ID is broader than most checkout forms imply
A Tax Identification Number is a broader administrative concept. Depending on the country, it may refer to a business tax number, a personal tax number, or a number used across several tax processes.
That's why a checkout label that says “Tax ID” can be ambiguous. Some buyers will enter a local tax number that their accountant uses domestically, while your billing flow may specifically need a VAT registration for intra-EU B2B handling.
If you want a grounded overview of that broader category, this guide on what a tax identification number is is useful as background. The key implementation point is simpler: don't assume “tax ID” means “VAT ID.”
VAT number is the one that usually matters for EU B2B invoices
For EU SaaS billing, the VAT identification number is usually the identifier that drives tax treatment. In the European Union, the VAT identification number follows a syntax built from an ISO 3166-1 alpha-2 country code plus 2 to 13 alphanumeric characters, with exceptions such as Greece using EL and Northern Ireland using XI for intra-EU trade, as described in the VAT identification number reference.
That same reference also notes something developers often miss. VIES does more than check whether a string looks plausible. It validates syntax and allocation status and can return the registered legal name and address. But it does not confirm the legal identity of the person presenting the TIN or the physical existence of the business entity. That creates a real syntax-versus-identity gap.
A VAT number can be valid in the system and still be the wrong trust signal for your use case.
A practical model for your data layer
Instead of one generic field, model these separately:
| Identifier type | What it answers | Typical use in product |
|---|---|---|
| Company registration number | Is this entity registered in its local registry? | Vendor onboarding, legal docs, KYC enrichment |
| Tax ID | What number does the tax authority use administratively? | Country-specific tax workflows |
| VAT number | Can this business be handled correctly for VAT invoicing? | Checkout, invoice generation, reverse charge logic |
That separation saves you from a lot of downstream hacks. When support asks why a buyer was charged tax, you want the audit trail to show which identifier was provided, what you validated, and what state the authority returned.
A Tour of Global and Country-Specific ID Formats
Once you move past definitions, the fragmentation shows up fast. Some identifiers are global in scope. Others are strictly local. Some are built for trade and supplier networks. Others only make sense inside a tax authority's own system.
A good example of a global identifier is the D-U-N-S Number. Dun & Bradstreet describes it as a universal business identification system that uniquely identifies, validates, and links more than 300 million businesses worldwide, assigned at the lowest organizational level and used across sole proprietorships, corporations, and government entities, as explained in the D-U-N-S Number factsheet. That's useful context because it shows what “global standard” looks like when one system is designed to normalize business identity across borders.
Why one regex won't save you
In the EU, even before you call any validation service, format handling is already uneven. Country prefixes differ. Character lengths differ. Some formats are numeric-heavy. Others mix letters and digits. Some users paste spaces, punctuation, or lowercase values from PDFs and email signatures.
That makes a single generic validator brittle. A broad regex can accept bad input. A strict regex can reject legitimate input because it doesn't account for country-specific syntax or exceptions.
Here's a practical sample table you can use as a reminder that “VAT number” is a family of formats, not one format.
Sample EU VAT Number Formats
| Country | ID Name | Format | Example |
|---|---|---|---|
| Germany | VAT Number | DE + digits |
DE123456789 |
| France | VAT Number | FR + alphanumeric sequence |
FR12345678901 |
| Spain | VAT Number | ES + alphanumeric sequence |
ESX1234567X |
| Italy | VAT Number | IT + digits |
IT12345678901 |
| Netherlands | VAT Number | NL + alphanumeric sequence |
NL123456789B01 |
| Belgium | VAT Number | BE + digits |
BE0123456789 |
| Sweden | VAT Number | SE + digits |
SE123456789001 |
| Poland | VAT Number | PL + digits |
PL1234567890 |
These are sample patterns, not a substitute for country-specific validation logic or authoritative checks.
Global identifiers don't replace local tax checks
You'll also run into efforts to standardize legal entity identity across jurisdictions. The International Business Registration Number, defined in ISO 8000-116:2019, converts domestic registration numbers into globally recognizable identifiers by attaching a jurisdictional prefix to the local authoritative number, as summarized in the IBRN overview. Structurally, that helps with machine-readable cross-border identification.
That doesn't solve your checkout problem by itself.
A normalized global identifier can help with entity matching, procurement, and interoperability. It still doesn't answer the narrow billing question your app cares about at purchase time: should this invoice carry VAT, reverse charge language, or domestic tax?
The engineering mistake is treating all business identifiers as if they solve the same problem. They don't. Registration identity, tax administration, and VAT eligibility overlap, but they are not identical.
If you're building validation logic, split your system into layers. Use one layer for normalization, another for format rules, and another for authority checks. That architecture handles fragmentation far better than one giant validator function full of country branches.
Why ID Validation Is Critical for EU SaaS Billing
If you sell software to EU businesses, identifier validation isn't a nice compliance extra. It directly affects whether your invoice is legally and operationally correct.

The registration number is not enough
A lot of teams validate the company number field the way they'd validate a coupon code. Check format, store value, continue checkout. For EU B2B billing, that's too shallow.
A key issue is the gap between a static entity registration number and dynamic VAT validity. The Aura analysis of company identifier validation points out that a valid registration number does not automatically mean the entity is authorized for cross-border VAT transactions, and it reports that 40% of VAT fraud cases stem from using inactive companies that still possess valid registration numbers.
That's exactly why “company exists” and “VAT treatment is safe” must be separate checks in your system.
Reverse charge depends on the validation state you can prove
When a business customer asks for reverse charge handling, your application is making a tax decision, not just collecting profile data. That decision needs support from the right identifier and the right validation path.
In practical terms, if you apply reverse charge without validating the VAT side properly, you create several problems at once:
- Invoice risk: The invoice may be missing the right tax treatment or support.
- Revenue leakage: You may undercharge tax when you should have collected it.
- Customer friction: You may overcharge a legitimate B2B buyer and trigger refund work.
- Ops mess: Finance has to reconcile avoidable billing exceptions by hand.
A failed validation path usually doesn't stay isolated. It leaks into support tickets, credit notes, ERP sync issues, and month-end review.
The billing flow has to survive real-world failures
Developers often discover this too late, after they wire validation directly into checkout and treat any upstream issue as a hard rejection.
That doesn't hold up in production. Validation services can be unavailable. Responses can be delayed. A country registry can return less data than you expect. Users can paste values with spaces or local formatting.
Later in the flow, it helps to give teams shared context on how the official system behaves in practice:
If your only states are valid and invalid, your billing system is missing the state that causes the most production pain: unverifiable right now.
The teams that handle this well separate customer experience from compliance enforcement. They let the user continue in controlled cases, flag the account for revalidation, and prevent irreversible tax assumptions until the authority check succeeds or a fallback process completes.
How to Validate Company IDs Programmatically
The naïve implementation looks simple. User enters a VAT number, you hit VIES, and you trust the response. The production implementation is not simple.
VIES is the official path for many EU VAT checks, but from an engineering perspective it feels like infrastructure from another era. SOAP payloads, inconsistent error surfaces, country-dependent behavior, and no promise that your checkout traffic conveniently aligns with upstream availability. If you're building a modern SaaS stack in Node.js, Python, or a serverless environment, the mismatch is obvious.

Build directly on VIES
There are reasons to do it yourself. You get direct contact with the authority check, complete control over retries, and no dependency on a third-party abstraction layer. If your volume is low and your team already has SOAP handling in place, that may be acceptable.
But you'll still need to build the missing reliability layer around it:
- Normalization before remote calls: Uppercase prefixes, strip spaces, split country from local value.
- Country-aware format checks: Reject malformed payloads before wasting remote requests.
- Timeout and retry policy: Treat authority slowness differently from true invalidity.
- Response mapping: Convert inconsistent authority output into stable internal states.
- Audit storage: Save the result, returned name, address, and validation timestamp.
That's not hard in theory. It's just annoying, easy to under-spec, and expensive to maintain relative to the business value it creates.
Buy a REST wrapper and focus on your billing logic
This is the classic build-versus-buy decision. If company ID and VAT validation aren't your product, wrapping VIES yourself is often a distraction.
A modern validation API should give you a few things the raw authority path doesn't:
| Capability | Direct authority integration | REST validation API |
|---|---|---|
| Transport style | SOAP | JSON over REST |
| Error handling | Often cryptic or inconsistent | Stable machine-readable codes |
| Input checks | You build them | Usually included |
| Caching | You build it | Often included |
| Multi-country support | Fragmented | Unified contract |
One option in that category is TaxID, which exposes a single REST endpoint for VAT and company ID validation across multiple countries, wrapping VIES with country-specific format checks, caching, and standardized error codes. That's useful if your actual goal is resilient checkout behavior, not becoming the maintainer of an EU tax-validation adapter.
If you're evaluating this path, this guide on validating company registration numbers programmatically is a practical companion because it frames the data-model and API concerns clearly.
Single-ID validation is becoming less safe
There's another reason simplistic validation is aging badly. The CoreSignal analysis of company identifier fragmentation argues that recent e-invoicing and compliance changes increasingly require multi-ID validation rather than trusting one identifier in isolation, and it reports that 28% of B2B payment failures in 2025 were tied to single-ID validation errors where the company ID matched but the associated LEI had been revoked.
You don't need to validate every possible identifier at checkout for every use case. But you do need to design your schema and services so they can support layered verification later.
A pragmatic validation pipeline
A solid implementation usually looks like this:
- Normalize input at the edge. Strip presentation junk, preserve the raw user input separately, and infer the country only when the prefix is authoritative.
- Run local format checks first. Fast failure beats a slow remote failure.
- Call the authoritative or wrapped validation endpoint. Store both the result and the evidence returned.
- Map outcomes to business states. Valid, invalid, service unavailable, unsupported jurisdiction, ambiguous.
- Make tax decisions from business states, not raw responses. Your invoice engine shouldn't parse transport-level errors.
That separation is what keeps checkout code sane. The validator service determines identity state. The billing service applies tax rules based on that state. Support and finance get an audit trail that makes sense.
API Validation Best Practices and Error Handling
A reliable validator isn't the function that says yes or no. It's the one that behaves predictably when the upstream world is messy.
Treat invalid and unavailable as different states
This is the most important implementation rule. An invalid number means the input failed. An unavailable service means your system couldn't establish truth at that moment.
Those states need different handling:
- Invalid identifier: block VAT exemption, show a fixable user message, log the normalized value.
- Service unavailable: avoid pretending the identifier is bad, queue a retry, and decide whether checkout should continue under a conservative tax rule.
- Unsupported type or jurisdiction: tell the user exactly what formats you accept instead of returning a generic failure.
If your API layer collapses all of those into 400 Bad Request, the rest of your stack will make bad decisions.
Cache aggressively, but keep the evidence
The publisher context for this article notes that Redis-backed 24-hour caching works well for repeat lookups because it balances freshness and performance for billing flows. That aligns with how many teams use validation. They don't need to hammer the authority every time the same customer opens the billing page. They need a recent validation state and a timestamp they can defend internally.
The trick is to cache both success and service-level failure carefully. Success can usually be reused for a period. Transient outage states should expire faster so the system can recover automatically.

Use interoperable identifier formats where required
In some B2B e-invoicing contexts, a company identification number is not just “some number in a field.” Under ISO 6523, a CIN is represented as SCHEME_ID:NUMBER, and in PEPPOL that scheme-qualified format is required because a raw number alone cannot be uniquely resolved across systems, as described in the Digiteal explanation of company identifiers.
That means your output model may need to store both a display value and an interoperable value. 12345678 might be what a user typed. It may still be technically invalid as the identifier you transmit downstream.
Prefer structured error payloads
A good validation API response should be easy to branch on in code. Something along these lines is what you want conceptually:
- Validation status
- Normalized identifier
- Country or scheme
- Registered name and address when available
- Machine-readable error code
- Timestamp of validation
For implementation patterns around retries, fallback states, and user messaging, this guide on VAT API error handling is worth keeping nearby.
Don't let your invoice engine parse human-readable error strings. Give it stable states and stable codes.
If you'd rather spend engineering time on billing logic than on wrapping SOAP, handling cache strategy, and normalizing authority responses, TaxID is a developer-first option for validating VAT and company identification numbers through a single REST API.