solidus icon indicating copy to clipboard operation
solidus copied to clipboard

[COMPLIANCE] Currently it is not possible to calculate B2B VAT rates correctly for orders within the European Union

Open fthobe opened this issue 11 months ago • 3 comments

Concerns: #3852 #3234 solidus_braintree #226

Overview (TL;DR)

As outlined in #6111 the European Union has serveral different tax schemes, some of them can not be calculated right now: most notably it's currently not possible to calculate reverse charge (sales without value added tax).

This is due to multiple issues:

  • [ ] Insufficient information inside the address as documented in #6110
  • [ ] Proper calculation mechanisms are missing to distinguish orders made by consumers from orders made by companies when applying value added tax

Cases to be considered

Reverse charge became the dominant VAT mechanism in Europe for transactions between companies (located in different countries). Hereby three major cases are to be considered:

  1. A Solidus Merchant who sells to a private customer or consumer indifferent to the location needs to charge VAT always;
  2. A Solidus Merchant who sells to a company abroad is in most cases not allowed to charge VAT.
  3. A Solidus Merchant who sells to company in the same country can sometimes avoid charging VAT depending on the category of goods sold.

The current address system does not allow to account for that difference.

Solidus Version: All versions

Current behavior It is not possible to distinguish between business and private customers therefor taxes can not be calculated.

Expected behavior Taxes can be calculated according to:

  • Location of the customer
  • Category of the customer (Business or Not)
  • VAT-ID of the customer

fthobe avatar Feb 10 '25 00:02 fthobe

  1. Taxes per location of customer is currently already possible. Solidus will create VAT prices (prices marked as with included tax) for each member of your tax categories zones. Just keep the "calculate vat prices" checkbox checked when adding or updating the master product price.

  2. VAT ID handling and validating is something that currently has to be build on your own. But I think we should add this into core now as this is a very common scenario nowadays.

  3. A business customer can be considered as someone with a VAT ID. This how we handle it on our European client stores. But I can imagine that there is more to it than just a VAT ID. I am also willing to support this in Core.

We could consider building a more generic Tax Exemption system. Generically a VAT ID is nothing else than a proof of Free Tax and there might be more stores interested in it than just Europeans.

tvdeyen avatar Feb 14 '25 22:02 tvdeyen

Some notes:

  1. the VAT-ID (German Ust.ID) and the VIES (reverse charge) participation are not the same thing.

  2. reverse charge is an opt in program, if the customer and merchant are opted in you MUST make a reverse charge invoice

  3. if the customer or the merchant are not opted in you MUST make the invoice with regular VAT (though I am unsure how often still happens). Reaching certain tresholds you must create a domestic VATID in the market you sell to.

  4. there's

  • domestic VAT without VAT-ID in some countries using the regular fiscal ID as they are the same;
  • there's no reverse charge without reverse charge option (VIES).

The only really reliable factor is: did the EU API by validating the VAT ID of both merchant and customer return that the reverse charge procedure needs to be applied.

So in my opinion we should start with

  1. reverse charge status and vat ID on the store and customer address.

fthobe avatar Feb 15 '25 10:02 fthobe

Hey, soooo, some more distilled thoughts: I will give you the most extreme example.

Premise:

  • Multi Store Environment with two stores;
  • one reverse charge licensed the other one not (absolute edge case);
  • handling B2B as well as B2C orders.
  • the vat ID reverse charge eligibility status of all parties can change over time
  • we can assume that some people to integrate with the EU validation service via Solidus or a 3rd party system and others don't

Approach to solution:

  • Introduce a Reverse Charge status to addresses and stores (enabled / disabled / unknown), the reason we can't go for a boolean is that some (as many do) might not check or not have a technical tool to check and accept the risk.
  • Extend the address model behind a flag
  • Implement tax models with an optional validation mechanism (control_reverse_charge_status true or false)

We have started playing around here is the first proposal for a reverse_charge_status on stores: #6136

fthobe avatar Feb 19 '25 10:02 fthobe