The Hidden Complexity of E-invoicing: A Developer's Guide to Data Validations

Building e-invoicing across countries means conditional rules, regex patterns, cross-field checks, and constant change. Here are 7 validation patterns developers must handle.

Antonio Kristicevic
Antonio Kristicevic
Engineering Manager
Published
Dec 5, 2025
Last update
Dec 5, 2025
The Hidden Complexity of E-invoicing: A Developer's Guide to Data ValidationsThe Hidden Complexity of E-invoicing: A Developer's Guide to Data Validations

Your invoice just failed submission to the Saudi Arabian tax authority. It's 2am. Your internal validation passed everything: correct data types, required fields present, amounts balanced. But somewhere between your API and Riyadh, something went wrong.

The error message arrives 40 minutes later: "Customer information missing for export transactions." Your system didn't catch this because it's not a universal rule. It's a Saudi-specific requirement that only applies to certain transaction types. You add a conditional check. Deploy. Submit again. This time it fails in Romania because your payment dates don't align with your partial payment amounts. Another conditional check. Another deployment.

This is the reality of building e-invoicing systems across multiple jurisdictions. Each tax authority enforces its own data rules, and those rules interact in complex ways. What looks like simple field validation quickly becomes a maze of conditional logic, format requirements, and cross-field dependencies that vary by country.

Why standard validation isn't enough

Most e-invoicing providers take a pass-through approach: you send them data in each country's exact format, and they forward it to tax authorities. If something fails, you find out when the authority rejects it.

The problem isn't just the delay. It's that you're now maintaining country-specific validation logic in your application code. When India changes its GST rules or Portugal updates its invoice numbering requirements, you're updating your codebase. Multiply this across 10, 20, or 50 countries, and you're building a compliance engine instead of your actual product.

Seven patterns of e-invoicing validation

Looking across jurisdictions, validation rules fall into recognizable patterns. Understanding these patterns shows why this problem is harder than it appears.

1. Mandatory field logic

Simple required field checks become complicated when requirements change based on context.

Global baseline: transaction identifiers are always required and capped at 150 characters.

Saudi Arabia requires customer information for export transactions. Romania requires payment due dates when no payment is provided or when partial payments don't sum to the total. India requires country subdivision codes like "DL" for Delhi, but only for domestic transactions.

Your validation logic needs to know not just what fields exist, but what type of transaction is happening and where.

2. Enumerated values

Some fields only accept values from a fixed list.

Transaction types globally: FULL, SIMPLIFIED, RECEIPT, RECEIPT_INVOICE.

Kenya allows three tax rates: 0, 8, or 16. Italy's operation regime must be GENERAL, EXPORT, SELF_BILLING, or SPECIAL.

These lists change. Italy might add new regime types. Kenya might adjust rates. Your validation needs to stay current with each authority's accepted values.

3. Format and pattern enforcement

Tax authorities care deeply about format. Not just data type (string vs. integer), but exact character patterns.

Portugal requires transaction numbers in this format: [DocumentCode] [Series]/[SequenceNumber]. So FT A/123 passes, but FT-A-123 fails.

Saudi Arabia wants postal codes as exactly 5 digits: 12345 works, 1234 doesn't.

Kenya's entity tax numbers must match either P123456789Y or A123456789Y.

Italy validates Codice Fiscale for individuals: exactly 16 characters following a regex structure like PVLMLI96R51Z158L.

India requires transaction numbers starting with an alphanumeric, max 16 characters, optionally containing / or -.

Each of these requires regex patterns tailored to local rules.

4. Conditional and contextual rules

Validations that depend on other fields create branching logic trees.

  • Globally: If Fonoa manages your transaction numbers, the transaction_number field must be empty. If you manage them, it's required.
  • Saudi Arabia: Customer must be classified as BUSINESS when processing exports.
  • Romania: If the state is RO-B (Bucharest), the city field must be a valid sector like "Sector 1" or "Sector 2".
  • India: For exports, country_subdivision_code must be OC or blank. Operation regime details like EXPORT_WITH_PAYMENT can only be set for actual exports.
  • Mexico: Transaction dates can't be in the future and can't be older than 72 hours.

Each conditional rule multiplies your validation complexity. You're not just checking fields but checking fields against other fields against transaction context against country rules.

5. Cross-field consistency

Data must be internally coherent across the entire invoice.

The sum of individual payment amounts must exactly equal the total transaction amount. All line item numbers must be distinct.

Portugal requires that any discounts you declare reference valid item numbers that actually exist in the invoice.

Saudi Arabia and Kenya require each line item to have exactly one tax rate.

These validations require examining the entire invoice structure, not just individual fields. You're validating relationships and mathematical consistency across potentially hundreds of line items.

6. Length and precision limits

Authorities set boundaries on data size and decimal precision.

Globally, transaction notes max out at 3,000 characters. Transaction amounts can have at most 9 decimal places.

Saudi Arabia allows entity legal names up to 1,000 characters. Romania caps email addresses at 100 characters. Italy varies by entity type: 80 characters for businesses, 120 for individuals.

These limits reflect the constraints of government systems. Exceed them and your data gets truncated or rejected, often with unclear error messages.

7. Unsupported fields

Some countries reject certain fields entirely, even if they're standard elsewhere.

Romania doesn't support transaction_number or series fields. Portugal doesn't recognize the tax_reason field. Kenya doesn't support payment codes.

This creates a problem: you need a data model comprehensive enough for all countries, but flexible enough to omit fields that specific countries don't accept.

The cost to build and maintain this yourself

Let's estimate the engineering effort. Seven validation pattern types across 20 countries. That's not 140 validation rules but 140 categories of rules, each containing multiple specific checks.

For India alone: mandatory fields vary by transaction type, format patterns for transaction numbers and tax IDs, conditional logic for exports vs. domestic, state code mappings, and cross-field consistency checks. That's dozens of specific validation rules for one country.

Multiply across jurisdictions. Add the maintenance burden when rules change, and they do change frequently. Portugal updates invoice numbering requirements. Saudi Arabia modifies export documentation rules. You're tracking regulatory updates for every country you operate in, then updating your validation logic to match.

Then comes the part teams underestimate: change management. Rules change, and the hard part isn’t updating logic, it’s: knowing what changed, updating validation behavior safely, updating test cases, and handling mismatches between “what you validate” and “what the authority actually enforces.”

Now add testing. You need test cases for every validation rule, every conditional branch, every cross-field dependency. A single invoice might trigger 30+ validation checks.

Technology that solves validation problems

Instead of building country-specific validation into your application, you can work with a system that accepts invoices in a single standard model and applies the necessary validations before submission.

You send invoice data in one consistent format. The validation layer checks it against the specific requirements of the destination country. If something's wrong, you get immediate feedback in a fraction of a second, not minutes or hours later when the tax authority responds.

This matters for three reasons:

  1. Faster troubleshooting: Tax authority processing is slow. Their error messages are often cryptic. When validation happens before submission, you can iterate quickly instead of waiting for round-trip responses from government systems.
  2. Prevention of silent errors: We've seen cases where providers missed critical issues like incorrect rounding that resulted in revenue losses. The tax authority's system didn't catch it, so the error persisted. Proper validation catches these problems before they become financial discrepancies.
  3. No maintenance burden: When India updates GST rules or Kenya changes tax rates, the validation system updates, not your codebase. Your application logic stays focused on your business domain, not on tracking regulatory changes across multiple countries.

What this means for your architecture

If you're building e-invoicing integration, you face a decision: where does country-specific validation logic live?

Option one:

In your application code. You maintain the rules, update them when regulations change, and handle the complexity of conditional logic across jurisdictions. This gives you control but creates a significant maintenance burden.

Option two:

In a validation layer between your application and tax authorities. You send standardized data, the layer validates against local requirements, and you get immediate feedback if something's wrong.

The second approach treats validation as infrastructure rather than application logic. You're not building a compliance engine but integrating with one.

For teams building products in SaaS, gaming, or ecommerce, this matters. E-invoicing is a requirement, not your core competency. The faster you can offload the complexity of multi-jurisdiction validation, the more you can focus on what you're actually building.

Final thoughts

E-invoicing validation looks simple until you implement it. Seven patterns of validation rules, multiplied across countries, with frequent regulatory updates, create a maintenance problem that compounds over time.

The question isn't whether you need robust validation. Tax authorities enforce their rules regardless. The question is whether you build and maintain that validation logic yourself, or whether you treat it as infrastructure and integrate with a system designed for that specific purpose.

Your invoice failing at 2am becomes a lot less stressful when validation happens before submission rather than after.

What’s covered
Learn about related Fonoa solutions

SYNAPSE 2026: Where Tax Meets Intelligence

Date: February 24, 2026 — 9:00 AM GMT
Location: London, UK

Join your peers at Fonoa’s annual conference. A day for tax, payments, and finance leaders to learn and network, coming to international locations in 2026.

Register now →

SYNAPSE networking photo 1 SYNAPSE networking photo 2 SYNAPSE networking photo 3
Antonio Kristicevic

Antonio Kristicevic

Engineering Manager

Fonoa’s founding engineer and Engineering Manager. He specializes in distributed systems design and has experience operating large-scale systems. He enjoys simplifying complex technical topics for internal and external audiences. Say hello to him to grab a coffee if you’re ever in Split Croatia.

Privacy Policy Cookie Policy