Home / Use cases / WooCommerce

WooCommerce

WooCommerce Spain NIF/CIF validation

Validate Spanish NIF and CIF numbers in WooCommerce checkout. Automatically apply B2B tax exemptions for verified Spanish businesses and autonomos.

Spain uses three distinct tax identifier formats: NIF for legal entities (a letter + 7 digits + a control letter, e.g. A12345678), NIF persona física for individuals (8 digits + letter, i.e. the standard DNI), and NIE for foreign nationals (X, Y, or Z + 7 digits + letter). Validating Spanish tax IDs in WooCommerce requires handling all three formats and understanding that only legal entities appear in VIES with the ES prefix; individual NIFs are not VIES-registered and should be captured for invoicing purposes only.

The WooCommerce integration uses the woocommerce_checkout_fields filter to inject a NIF/CIF input, and the woocommerce_checkout_process action to validate it server-side before the order is placed. When the customer saves their billing address, your plugin calls GET /api/v1/validate/ES/:nif, checks the response, and either proceeds or returns a checkout error. For verified legal entities, the order meta is updated with the company_name from the TaxID response, enabling correct invoice rendering.

Spanish Hacienda requires that invoices issued to businesses include the recipient's NIF and registered company name. Storing the TaxID-validated company_name ensures your WooCommerce PDF invoices are compliant with Real Decreto 1619/2012, Spain's invoice regulation. If VIES returns service_unavailable for the ES node, fall back to format validation only and flag the order for manual review rather than blocking the purchase.

Implementation steps

  1. 1

    Add NIF/CIF field to checkout

    Use the woocommerce_checkout_fields filter to inject a custom 'billing_nif' field into the billing section. Set it as required for customers selecting Spain as their billing country by combining the filter with a conditional on billing_country === 'ES', so domestic buyers are always prompted while foreign buyers are not.

  2. 2

    Validate via TaxID API on save

    Hook into woocommerce_checkout_process to call GET /api/v1/validate/ES/:nif server-side before order creation. If status is 'active', store the company_name in order meta; if 'invalid', call wc_add_notice() with type 'error' to surface the failure inline; if 'service_unavailable', allow checkout but flag the order with a custom meta key (e.g. _vat_pending_verification: 1) for asynchronous re-validation.

  3. 3

    Display validation status to customer

    After the API call, render inline feedback using JavaScript and the WooCommerce checkout block's update_checkout event: show a green company name confirmation for valid numbers, a red 'VAT number not found in VIES' message for invalid ones, and a neutral 'Validation service temporarily unavailable' notice for service_unavailable responses, so the buyer understands why checkout proceeds without exemption.

  4. 4

    Auto-apply B2B pricing rules

    On successful validation, use the woocommerce_customer_taxable_class filter to return 'zero-rate' for the order, and assign the customer role 'b2b-verified' via wp_update_user. The zero-rate tax class suppresses WooCommerce's VAT calculation, and the role gates access to wholesale price lists or catalog discounts configured via WooCommerce Product Tables or a role-based pricing plugin.

Code example

Node.js

const res = await fetch(
  'http://localhost:3000/api/v1/validate/DE/ESA12345678',
  { 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/ESA12345678",
    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:

200 OK (active)valid
{
  "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.

active

VAT number is valid and the business is registered

invalid

VAT number format is wrong or not registered in VIES

service_unavailable

VIES or the national system is temporarily down — retry later

Country-specific guides

Further reading

Evaluating EU VAT APIs? Compare TaxID with:

Ready to implement?

Get your free API key and start validating EU VAT numbers today.

Get free API key

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...

UK VAT validation in Shopify B2B

Validate UK VAT numbers for B2B customers in Shopify. Required under UK Making Tax Digital rules for...

EU VAT compliance for SaaS billing

Handle EU VAT for SaaS subscriptions. Validate customer VAT numbers at signup, determine B2B vs B2C ...