Cross-border B2B & reverse charge

When a business guest books across an EU border, the instinct is 'reverse charge the VAT'. For a hotel room, that instinct is wrong. The room is always taxed with local VAT. Reverse charge applies only to the OTA's commission line — and TaxLens models it precisely.

Place of supply: the room is special

The room and the commission are two different supplies with two different place-of-supply rules, and that difference is the whole story.

Two supplies, two rules
The ROOMservice tied to propertyEU VAT Directive Art. 47LOCAL VAT — alwaysnever reverse-chargedThe COMMISSIONOTA intermediary serviceArt. 44 / 196REVERSE CHARGEwhen cross-border B2B
The room is connected to immovable property (Art. 47) → local VAT, always. The intermediary's commission (Art. 44/196) → reverse charge when cross-border B2B.

A hotel room is a service connected to immovable property (EU VAT Directive Article 47), so it is taxed where the property is — local VAT — even for a cross-border business guest. The room is never reverse-charged. Reverse charge (Articles 44/196) applies to the OTA's commission / intermediary service, which is taxed where the recipient is established.

There is no reverse-charge rule on room VAT
A reverse-charge rule must attach to a commission VAT rate (base_type=commission_amount), never the room VAT. TaxLens deliberately ships no seeded reverse-charge rule on room VAT — an earlier room-level rule was removed as an Article 47 bug. Commission-line reverse-charge rules are authored per OTA establishment.

How it's authored: override to zero

Reverse charge is not an exempt action, and it is not gated on having a VAT id alone. It is authored as an override to rate_value: 0 that carries an exemption_reason of "reverse_charge", on the commission VAT rate, gated on the cross-border B2B condition:

{
  "rule_type": "override",
  "conditions": {
    "operator": "AND",
    "rules": [
      { "field": "is_cross_border_b2b", "op": "==", "value": true }
    ]
  },
  "action": {
    "rate_value": 0,
    "exemption_reason": "reverse_charge"
  }
}

Why override-to-zero and not an exemption?

  • An exempt action nulls the taxable_amount, which breaks reconciliation — the reverse-charged base must stay on the invoice.
  • The override keeps the base, charges 0 VAT, and tags the component so the invoice projection emits the right category.

The tag flows all the way through: rule.action → RuleApplicationResult → TaxComponentResult → TaxComponent, and the component surfaces is_exempt: false with a non-null taxable_amount and exemption_reason: "reverse_charge" — detect reverse charge via exemption_reason, not is_exempt (the override keeps the taxable base for AE reconciliation). On the e-invoice this becomes EN 16931 category AE (rate 0, code VATEX-EU-AE, reason "Reverse charge") — not category Z, which a naive 0% would mis-map to.

Don't gate on the VAT id alone
Gating on has_valid_vat_id alone would wrongly reverse-charge a domestic B2B booking. The gate must be the cross-border condition.

The fields that drive it

You signal a business booking with two fields; the engine derives the cross-border test from them (and from the property country):

FieldTypeDescription
customer_type"business" | …Set to business for a B2B booking. Exposes has_valid_vat_id and the cross-border derivation.
business_tax_idstringThe guest's VAT id (e.g. DE…). The country prefix derives customer_vat_country (EL maps to GR).
is_cross_border_b2bderivedEngine-derived from the property country (head of the jurisdiction code) vs. the VAT-id country. The gate for the commission reverse charge.
commission_supplier_countryISO countryThe OTA / intermediary's country. When present, the commission gate uses is_commission_cross_border_b2b (supplier-vs-property), independent of the guest — so a non-EU OTA acting as MoR for an EU hotel still reverse-charges its commission. Falls back to the guest-derived test when omitted.

So a US OTA acting as merchant of record for a German hotel reverse-charges its commission (category AE) even when the guest is a non-EU consumer — because commission_supplier_country drives the commission gate. The room, again, is unaffected: local German VAT.

What isn't validated yet

Detail
There is no live VIES validation yet. Reverse charge trusts the caller-supplied VAT id structurally — the prefix and shape feed is_cross_border_b2b, but the id is not checked against the VIES registry. Treat VAT-id validation as your responsibility upstream for now. See Limitations.

Where to go next

The commission line itself and MoR routing are in Channels & merchant of record. How the AE category lands on the document is in E-invoice standards, and override actions in general are in Rules.