UK VAT validation in Shopify B2B
Validate UK VAT numbers for B2B customers in Shopify. Required under UK Making Tax Digital rules for businesses selling cross-border to UK companies.
Since Brexit, UK VAT registration is administered by HMRC independently of the EU VIES system. UK VAT numbers follow the format GB + 9 digits and are validated against HMRC's API. B2B sellers shipping goods or supplying digital services to UK-registered businesses can zero-rate those supplies, but only if the buyer's VAT number is verified and recorded at the time of sale.
In Shopify, the integration happens either through a checkout extension that calls your backend on address confirmation, or via an order-created webhook. The webhook approach is safer because it fires for all order channels. Your handler calls GET /api/v1/validate/GB/:vatNumber, and if the response returns status: 'active', you use the Shopify Admin API to set tax_exempt: true on the customer and add a metafield storing the validated VAT number and timestamp.
Making Tax Digital for VAT mandates that the VAT number used to justify a zero-rated supply is recorded in your VAT account. Storing the TaxID request_id alongside the order is good practice: it gives you an audit-ready reference showing which third-party validation confirmed the number's status on a specific date.
Implementation steps
- 1
Add VAT number field to billing address
Use a Shopify Checkout UI Extension or a custom storefront to add a 'UK VAT number' input to the billing address step. Persist the value in a customer metafield (namespace: 'tax', key: 'vat_number') so it is available to webhooks and future orders without asking again.
- 2
Validate on order creation via webhook
Subscribe to the orders/create webhook in your Shopify Partner app. When it fires, read the vat_number metafield, call GET /api/v1/validate/GB/:vatNumber, and handle the three possible status values: 'active' proceeds to exemption, 'invalid' triggers a follow-up email to the customer, and 'service_unavailable' queues a retry job to avoid incorrectly exempting an unverified number.
- 3
Tag customer as B2B if valid
On a valid response, use the Shopify Admin REST API (PUT /admin/api/2024-01/customers/:id.json) or GraphQL mutation to add the tag 'b2b-verified' to the customer. This tag can drive Shopify discount scripts, price list assignments, and B2B metafield visibility without re-querying the VAT status on every session.
- 4
Apply tax exemption
Update the customer object with tax_exempt: true via the Shopify Admin API to suppress VAT on subsequent orders. Store the validated VAT number, the company_name from the TaxID response, and the validation date in customer metafields for Making Tax Digital record-keeping; HMRC requires you to retain evidence of VAT validation for at least six years.
Code example
Node.js
const res = await fetch(
'http://localhost:3000/api/v1/validate/DE/GB123456789',
{ headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);
const { valid, status, company_name, company_address } = await res.json();
if (valid) {
console.log(`Valid EU business: ${company_name}`);
} else if (status === 'service_unavailable') {
// VIES is temporarily down — retry or allow with manual check
console.log('VIES unavailable — check back in a few minutes');
} else {
console.log('Invalid VAT number — charge local tax rate');
}Python
import requests
res = requests.get(
"http://localhost:3000/api/v1/validate/DE/GB123456789",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = res.json()
if data["valid"]:
print(f"Valid: {data['company_name']}")
elif data["status"] == "service_unavailable":
print("VIES temporarily unavailable")
else:
print("Invalid VAT number")API response
The TaxID API returns a consistent JSON response for every validation request:
{
"valid": true,
"status": "active",
"country_code": "DE",
"vat_number": "123456789",
"company_name": "Example GmbH",
"company_address": "Musterstraße 1, 10115 Berlin",
"request_date": "2026-05-10T00:00:00.000Z",
"cached": false,
"request_id": "req_01j..."
}Error handling
The API uses a consistent Stripe-style error format. Always handle service_unavailable separately — VIES has occasional downtime and you should not reject valid customers during outages.
activeVAT number is valid and the business is registered
invalidVAT number format is wrong or not registered in VIES
service_unavailableVIES or the national system is temporarily down — retry later
Country-specific guides
Further reading
EU VAT Number Validation: The Complete Developer Guide (2026)
VIES is SOAP-based, unreliable, and has no caching. This guide explains how EU VAT validation works end-to-end, how to h…
How to Check Tax ID Numbers Reliably
Learn how to check tax ID numbers reliably. Our guide covers local formats, VIES/IRS lookups, and using an API for billi…
API reference for Shopify:
Shopify VAT Validation API
EU VAT validation for Shopify B2B storefronts
Evaluating EU VAT APIs? Compare TaxID with:
Related use cases
Stripe EU VAT: Validate Tax IDs Before Charging Customers
Stripe EU VAT integration guide: validate EU VAT numbers server-side before applying zero-rate B2B e...
WooCommerce Spain NIF/CIF validation
Validate Spanish NIF and CIF numbers in WooCommerce checkout. Automatically apply B2B tax exemptions...
EU VAT compliance for SaaS billing
Handle EU VAT for SaaS subscriptions. Validate customer VAT numbers at signup, determine B2B vs B2C ...