A checkout can look perfect and still be wrong. A Berlin SaaS team can collect a French customer's VAT number, flip the invoice to 0% VAT, and ship the receipt with confidence, only to discover later that nobody checked whether the VAT ID was valid at the moment of supply, or whether the reverse-charge treatment was documented well enough to survive an audit.
That gap is the whole problem with intra Community VAT in software billing. The tax logic is simple on paper, but production systems have to deal with VIES outages, stale customer records, recurring subscriptions, and invoices that need to prove why no VAT was charged in the first place.
Table of Contents
- Why Intra Community VAT Trips Up SaaS and E-Commerce Teams
- Intra Community Supplies vs Acquisitions Explained
- How the Reverse Charge Mechanism Works in Practice
- VIES Validation Limits and the Evidence Problem
- Building Reliable VAT Validation with the TaxID API
- Common Intra Community VAT Mistakes and How to Avoid Them
- Your Intra Community VAT Implementation Checklist
Why Intra Community VAT Trips Up SaaS and E-Commerce Teams
A developer usually meets this problem at the worst possible time, right after shipping a new checkout flow. The customer enters a VAT number, the UI accepts it, the billing engine applies 0% VAT, and everyone moves on. The issue is that a formatted VAT ID isn't the same thing as a valid, active VAT ID, and the seller still has to prove the cross-border conditions were met before treating the sale as an intra-Community supply.
That distinction matters because the EU system is destination-based. For a B2B sale of goods shipped from one Member State to another, the seller typically zero-rates at departure, while the buyer accounts for the tax in the destination country through an intra-Community acquisition and reverse charge, as described in the European Commission's VAT framework and summarized in the practical guidance on intra-Community transactions. The same logic is what makes SaaS billing tricky, because teams often mix up B2B and B2C treatment, or assume a VAT number alone is enough to justify exemption.

The commercial stakes aren't abstract. The European Commission estimated total VAT revenue in 2023 at €1,223 billion, while the VAT compliance gap was still €128 billion, equal to 9.5% of total liability, and the gap worsened by 1.6 percentage points versus 2022, even though it improved from 11.1% in 2019 to 9.5% in 2023 overall (European Commission estimate, via Eurofiscalis). If your product bills EU businesses, that's not a background policy issue, it's a control problem inside checkout, invoicing, and evidence capture.
For teams wanting a broader accounting checklist around tax-heavy workflows, the 2026 crowdfunding tax guide from PledgeBox is a useful companion resource because it frames compliance as an operational system, not a one-off tax decision.
Practical rule: if the VAT decision happens after the invoice is generated, the implementation is already too late.
Intra Community Supplies vs Acquisitions Explained
An intra-Community supply is the seller-side event. A business sells goods or, in the B2B cross-border context, supplies services to a VAT-registered customer in another Member State, and the seller can zero-rate the invoice only when the legal conditions are satisfied, including customer VAT registration, cross-border movement, and proof of that movement (KMLZ overview).
An intra-Community acquisition is the buyer-side mirror. The customer receives the goods or services in its own Member State and accounts for VAT there, usually through reverse charge, so the seller doesn't collect destination VAT and the buyer self-assesses it locally. That split is what keeps the internal market moving without forcing the seller to register everywhere the customer buys from.
For a concrete example, take a Dutch software company selling a B2B subscription to a Spanish manufacturing firm. If the Spanish customer is VAT-registered and the supply meets the cross-border conditions, the Dutch seller issues a zero-rated invoice and records the sale as an intra-Community supply. The Spanish buyer then treats the purchase as an acquisition in Spain and accounts for VAT on its local return.
Supply side and acquisition side
| Aspect | Intra Community Supply (Seller) | Intra Community Acquisition (Buyer) |
|---|---|---|
| Tax treatment | Typically zero-rated or exempt when conditions are met | VAT is self-assessed in the destination country |
| Main responsibility | Prove the customer's VAT status and the cross-border nature of the supply | Report the acquired value in the local VAT return |
| Invoice flow | Issue invoice without charging domestic VAT | Use the invoice as the basis for local accounting entries |
| Evidence needed | VAT ID, transport or service evidence, transaction record | Local VAT return support and supplier invoice |
| Common failure mode | Zero-rating without proof | Missing or delayed self-assessment |
For goods, the transport evidence is critical. For digital services and SaaS, the physical movement piece disappears, but the customer classification still matters because B2B and B2C rules aren't interchangeable. If the buyer is not VAT-registered, you're usually outside this framework and into a different tax treatment entirely.
The invoice doesn't create the exemption. The evidence behind the invoice does.
How the Reverse Charge Mechanism Works in Practice
The reverse charge shifts the reporting burden from seller to buyer. The seller issues an invoice without VAT, the buyer self-assesses the VAT in its own country, and the local VAT return typically shows both the output VAT and, if deductible, the input VAT. That's why reverse charge often feels cash-neutral for the buyer, even though the reporting obligation is very real.

Take a €10,000 B2B service from a German provider to an Italian client. The German company issues an invoice for €10,000 with no VAT charge, includes both VAT numbers, and adds the reverse-charge statement required by the invoicing rules. The Italian client records €10,000 as an acquisition and self-assesses Italian VAT at its domestic rate, then deducts it as input tax if it's entitled to do so.
The most common production mistake is treating SaaS like a domestic service just because nothing physical moves. For B2B digital services, the place-of-supply logic still pushes the tax treatment to the customer side when the buyer is a taxable business, so the billing system needs a reliable way to decide whether the customer is VAT-registered before it suppresses VAT.
What the invoice needs
- Both VAT numbers, so the transaction can be tied to each party.
- A reverse-charge reference, because the customer needs the legal basis for self-assessment.
- A clean transaction record, because finance teams and auditors will ask why VAT was not charged.
For a practical development view of invoice handling and accounting flow, the reverse charge VAT guide from TaxID's documentation is a good implementation companion, especially if you're wiring this into Stripe billing or a custom checkout.
VIES Validation Limits and the Evidence Problem
A customer validates their VAT number at onboarding. Six months later, that number has been deactivated, and your audit record still shows it as valid. That is the gap VIES creates for product teams if they treat a registry lookup as proof instead of a point-in-time check.
VIES is the official lookup often used for checking VAT numbers, but it is not the same thing as audit-grade proof. Format validation only tells you the string looks right for a country pattern. Substantive validation tells you whether the VAT number was active, registered, and supportable at the moment you relied on it.
One successful lookup at onboarding does not cover recurring billing forever. EU guidance says the seller needs to prove the customer is VAT-identified in another Member State and that the conditions for zero-rating are met, while legal commentary also notes the VAT-ID must be valid at the time of delivery or transport start (European Commission VAT Directive guidance). In practice, that means a timestamped record matters more than a generic “passed validation” flag from months ago, especially when subscriptions renew without a fresh check.
Ireland's audit data shows why this is not academic. Between January 2010 and December 2011, companies reported intra-community supplies totaling €17.1 billion, and VAT numbers that failed either first or second-level checks accounted for nearly €1.3 billion of that value; the report also says 270 of 1,533 transactions were incorrect in one sample period, or 17.6%, and 1,267 of 17,148 in another, or 7.4% (audit report). Those figures show why “we checked the format” is nowhere near enough.
What breaks when VIES is down
When VIES is unavailable during checkout, you need a policy, not a hope. Some teams block the order until validation succeeds, some let the order through with VAT applied provisionally, and some let the customer proceed but mark the invoice for manual review. The right choice depends on your tolerance for conversion loss versus tax risk, but the system must record which path it took and why.
Operational truth: if the validation result is not saved with a timestamp, you do not really have evidence, you have a memory.
For recurring billing, the useful control is not “did VIES ever return yes,” it is “what did we know at the moment we priced and invoiced this transaction.” That is where a timestamped validation record helps during later review, especially if you also keep the result alongside the subscription event and the invoice reference. A practical guide like how to check a VAT number in VIES is useful here because the problem is not the lookup itself, it is preserving the decision trail when the customer keeps paying on autopilot.
Building Reliable VAT Validation with the TaxID API
A modern billing stack needs a thin, reliable wrapper around VIES, not direct dependence on a fragile endpoint. TaxID is one option for that layer, because it applies country-specific format checks, wraps the EU Commission's SOAP-based registry lookup, and caches successful validations so repeated checkout and invoicing flows don't keep hitting the registry for the same ID.
In practice, the workflow should be simple. First, validate the string format locally. Then call the validation API. Then store the result, the timestamp, and the customer reference so finance can prove what happened later. If the lookup returns a machine-readable vat_invalid error, you keep VAT on the invoice. If it returns service_unavailable, you follow the fallback policy you already defined, instead of inventing one in production.
Node.js example
import fetch from "node-fetch";
async function validateVat(vatId) {
const res = await fetch("https://api.taxid.dev/v1/vat/validate", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${process.env.TAXID_API_KEY}`
},
body: JSON.stringify({ vat_id: vatId })
});
const data = await res.json();
if (data.error_code === "vat_invalid") {
return { decision: "charge_vat", status: "invalid", checked_at: new Date().toISOString() };
}
if (data.error_code === "service_unavailable") {
return { decision: "manual_review", status: "unavailable", checked_at: new Date().toISOString() };
}
return {
decision: data.valid ? "reverse_charge" : "charge_vat",
status: data.valid ? "valid" : "invalid",
company_name: data.company_name,
checked_at: new Date().toISOString()
};
}
Python example
import requests
from datetime import datetime
def validate_vat(vat_id):
response = requests.post(
"https://api.taxid.dev/v1/vat/validate",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"vat_id": vat_id},
timeout=5
)
data = response.json()
checked_at = datetime.utcnow().isoformat() + "Z"
if data.get("error_code") == "service_unavailable":
return {"decision": "manual_review", "checked_at": checked_at}
return {
"decision": "reverse_charge" if data.get("valid") else "charge_vat",
"checked_at": checked_at,
"company_name": data.get("company_name")
}
In a Stripe checkout flow, this sits right before tax calculation. The customer submits the VAT number, your app validates it, and only then do you decide whether to apply the exemption or collect VAT. TaxID's VAT validation API documentation is the place to check the response shape, caching behavior, and error handling patterns before you wire it into your billing service.
Common Intra Community VAT Mistakes and How to Avoid Them
The mistakes here are usually boring, which is why they survive code review. Teams ship them because the checkout works, the invoice looks clean, and nobody simulates a failed registry call until after the first audit query.
Applying 0% VAT without validating the VAT number.
Correct approach, validate before invoicing and store the response with the transaction record. If you skip that step, you're relying on customer input instead of proof.Caching validation forever.
Correct approach, re-check periodically and re-check on meaningful billing events. A VAT ID can't be treated like a static profile field if the legal treatment depends on current status.Leaving out the reverse-charge wording.
Correct approach, generate invoice templates that include the right legal reference and both VAT numbers when reverse charge applies. A technically correct tax decision can still produce a non-compliant invoice if the wording is missing.Treating B2B and B2C SaaS the same way.
Correct approach, separate the checkout logic by customer type and tax status. A business customer with a valid VAT ID and a consumer without one do not belong on the same tax path.Assuming format equals validity.
Correct approach, use format checks only as a first filter. The format tells you the string looks plausible, not that the tax authority currently recognizes it.Ignoring goods-movement evidence.
Correct approach, store transport or delivery evidence for physical goods, not just invoice PDFs. The later audit discussion gets much easier when the shipment trail is already attached to the order.
The cheapest mistake to fix is the one you catch before the invoice leaves your system.
Your Intra Community VAT Implementation Checklist
Start with the setup that makes the rest possible. Register for VAT where your business needs it, map your product flows to the correct tax rules, and wire a validation layer into checkout before the first invoice is generated. If you're a founder or ops lead and need a practical accounting baseline alongside the engineering work, FastCorp accounting for founders is a useful reference for the broader compliance process.
Setup
- Confirm customer type rules. Separate B2B from B2C in your billing logic.
- Validate before exemption. Call the VAT validation API before applying a 0% rate and store the response with timestamp, customer ID, and transaction reference.
- Template invoices properly. Include the reverse-charge reference and both VAT IDs when required.
- Log the fallback path. Record whether a checkout was approved, blocked, or marked for manual review.
Transaction handling
- Verify on every meaningful event. Re-check VAT status before recurring renewal invoicing or a new cross-border order.
- Keep evidence together. Attach validation results, invoices, order IDs, and, for goods, delivery or transport evidence.
- Use a clear decision tree. If validation fails, charge VAT or hold the order until a human reviews it.
- Handle service outages explicitly. Don't let a registry timeout default to exempt treatment.
Ongoing compliance
- Re-validate periodically. Don't rely on onboarding-time checks alone.
- Retain audit logs. Save what was verified, when it was verified, and what system decision followed.
- File the required reports. Handle VAT returns, and where applicable Intrastat or EC Sales List obligations.
- Escalate when the flow is ambiguous. If the transaction mixes goods, services, stock movement, or multiple countries, bring in a tax advisor before shipping code.
TaxID offers a developer-first validation API for VAT and company IDs, with a free tier for early testing and a cleaner way to keep evidence attached to each decision. If you're building EU billing flows and want a system that helps your checkout survive VIES outages without guessing, visit TaxID and wire the validation step into your next release.