DEV Community

Howth Technology Factory
Howth Technology Factory

Posted on

Designing VAT Validation That Fails Safely: A Three-State VIES Workflow

Why developers should treat VALID, INVALID and UNAVAILABLE as separate outcomes when integrating EU VAT checks

A dependable VAT workflow preserves valid, invalid and temporarily unavailable as separate operational states.

The dangerous shortcut: one boolean

A VAT-number lookup looks simple enough to model as a boolean: valid or invalid. That design works until the upstream service is unavailable, a national database times out, or a response omits optional fields. At that point, a two-state model forces your application to lie. It either treats uncertainty as invalid, rejecting a legitimate customer, or treats uncertainty as valid, allowing a transaction to continue without dependable evidence.

For developers building SaaS billing, e-invoicing, onboarding or finance workflows, the safer approach is to model VAT validation as a small state machine. The lookup should answer a narrow technical question: what did the official VIES service return for this normalised identifier at this time? Your business rules can then decide what happens next.

What VIES actually tells you

VIES is the European Commission's search service over national VAT databases. A successful valid response confirms that a VAT number is registered for cross-border EU trade at the time of the check. It may also include a business name or address, depending on what the relevant member state supplies.

That result is useful evidence, but it is not a complete tax decision. Your application may still need to consider the place of supply, the nature of the service or goods, the parties involved and local evidence requirements. Keep the validation layer narrow. It should report the lookup result accurately rather than pretending to determine the full VAT treatment of the transaction.

The three states your workflow needs

A reliable integration should preserve three operational outcomes: VALID, INVALID and UNAVAILABLE.

VALID means VIES confirmed the number at the time of the request. Store the normalised identifier, the timestamp, the returned status and any optional business details. When the requesting business's own VAT number is supplied, VIES may also return a consultation number. Retain it with the same check record when your process needs evidence of the lookup.

INVALID means the official service returned a negative result. That does not always mean fraud or a fake company. The number may be mistyped, not yet activated for intra-EU transactions or entered with the wrong country prefix. A useful UI should show the exact normalised value that was checked and give the customer or operator a path to correct it.

UNAVAILABLE means no dependable answer was obtained. A national service may be down, the request may time out or a retry budget may be exhausted. This state must never be silently converted into INVALID. The correct action is normally to pause, retain the error category and retry later.

Separate transport failure from business failure

The most important architectural boundary is between the lookup and the decision that follows it. A network timeout is a transport failure. A confirmed invalid VAT number is a business-data failure. They may both prevent an invoice from progressing immediately, but they require different messages, logs and recovery paths.

This separation also prevents infrastructure details from leaking into customer treatment. A buyer should not be told that their VAT number is invalid because a member-state system failed to answer. Conversely, a valid response should not automatically approve a transaction whose wider tax facts still require review.

Use bounded retries, not hopeful loops

Retries are appropriate for temporary upstream failures, but they should be bounded and visible. Immediate repeated calls can add pressure to a struggling service. An unbounded background loop can leave finance teams believing that a check is still progressing when it has effectively stalled.

Use a small retry budget with increasing delays. Record the first failure, the number of attempts and the final error category. When the budget is exhausted, return UNAVAILABLE to the calling workflow. A later job can retry only unresolved records instead of rerunning the entire batch.

Do not retry structural problems. A malformed country code, empty value or invalid input shape should fail before contacting VIES. Authentication, configuration and schema errors should surface to the operator. Reserve the UNAVAILABLE path for temporary upstream and transport conditions.

Make bulk checks reconcile one-to-one

Bulk validation introduces a second common mistake: treating the whole batch as one pass-or-fail operation. A more useful contract returns one output item for every input, using the same order or a stable correlation key.

Suppose a batch contains 100 VAT numbers. Eighty-six may be valid, ten invalid and four temporarily unavailable. The successful results should remain usable, the invalid rows should be sent for correction and only the four unresolved records should enter the retry queue. One country outage should not erase the rest of the batch or force a complete rerun.

Treat name and address as optional

Your schema should allow businessName and address to be null. Some national databases do not expose those fields through VIES, and data availability varies by member state. Their absence does not make an otherwise valid result defective.

This is a good example of why strict API contracts should distinguish required evidence from optional enrichment. The required fields are the identifier checked, the result state and the time of the check. Everything else should be handled according to the source's actual response.

A compact response contract

A response model can remain small while preserving the distinctions that matter:

{
"vatNumber": "IE1234567A",
"status": "VALID | INVALID | UNAVAILABLE",
"businessName": "string | null",
"address": "string | null",
"consultationNumber": "string | null",
"checkedAt": "ISO-8601 timestamp",
"error": "string | null"
}

The exact field names are less important than the semantics. Never collapse absence, invalidity and upstream failure into the same value. Every item should preserve the identifier and timestamp that were actually checked.

Five tests worth keeping

Before connecting VAT validation to invoicing or onboarding, keep at least these tests in your integration suite:

A valid VAT number where the member state returns a name and address.

A valid VAT number where the member state omits one or both optional fields.

An invalid number that remains invalid after deterministic normalisation.

A temporary national-service failure that produces UNAVAILABLE, never INVALID.

A mixed batch that returns one traceable result for every input.

Using a maintained workflow component

Howth Technology Factory's EU VAT Validator packages this pattern as a reusable service. It checks EU and Northern Ireland VAT numbers through VIES, supports individual and bulk inputs, returns one result per number and keeps temporary member-state failures separate from invalid results. The Apify version also supports an optional requester VAT number so a consultation number can be retained when VIES supplies one.

For developers, the main advantage is not avoiding a single HTTP request. It is avoiding the operational edge cases around normalisation, bounded retries, partial batch failure and typed output. The service is available through the product page, as an Apify Actor and as an MCP server for agent-driven workflows.

Build the state transition first

VAT validation is a small component, but it can affect invoicing, customer onboarding and finance operations. That makes honest failure handling more important than a convenient boolean.

Design the state transition before the tax decision. Preserve VALID, INVALID and UNAVAILABLE. Keep evidence that can be explained later. Retry only what is genuinely retryable. When the upstream service cannot answer, say so explicitly. That is the difference between a lookup that merely works in a demo and a workflow component that behaves safely in production.

EU VAT Validator product page

Top comments (0)