quote → cash
EN/FR Contact

Pattern · Tax

Bill-To driven taxation

Make the tax rate follow the billing profile rather than the order address — and know why that is the correct reading of the model, not a workaround.

Salesforce docs documented by SalesforceField experience observed on a real orgRecommended pattern what we recommendTo verify unverified

The problem

A seller operating across several countries needs each invoice to carry the right VAT. The obvious model — take the address on the transaction — produces inconsistent results, because the same customer can be delivered in one country and invoiced in another.

Context

One legal entity, customers in and outside the EU, and an existing rate table to carry over. The requirement is that finance can explain any rate on any invoice from the customer record alone.

Recommended architecture

Resolve tax from the billing profile, not from the transaction. The billing profile is the record that answers “who is being invoiced, where, under which tax identity” — which is exactly the question VAT asks.

The rate then resolves at TaxRate level on code × country, and the treatment carries the code. With a single legal entity, TaxPolicy.TreatmentSelection = LegalEntity has nothing to discriminate on, so the discrimination has to live in the rates.

Implementation

  1. Give every account a billing profile with a country. Without BillToContactId, a payment term on the order and a delivery address, the profile produces nothing at all.
  2. Load the rates with the Revenue Cloud usage type, one row per code × country × period. Rows with a zero rate are still worth loading explicitly — a missing row and a zero row look identical on the invoice but mean different things.
  3. Attach the tax policy to the product, not to the line. A reprice re-derives the treatment from the product, so anything set only on the line is lost.
  4. Prove it in both directions with two orders carrying different addresses and the same billing profile. They must return the same rate.

Trade-offs

The cost is that a customer needing two tax behaviours needs two billing profiles. In exchange, the rate becomes explainable from one record, and a change of billing country is a data change rather than a reconfiguration.

The alternative — reading the transaction address — is only right when the invoice always follows the delivery, which is rarer than it sounds.

Watch out

  • Verified in production in both directions: two orders with different addresses and the same billing profile return the same rate. The order address does not command VAT.
  • The engine reads addresses from the line, never from the header.
  • On one org the tax request arrived with every address null, which forced the adapter to resolve the country itself from the transaction's account. Check what the engine actually receives before designing around it.

Salesforce components

Salesforce resources