• Hi guys,

    I’m having a weird issue here, using this combo:
    – WooCommerce
    – WooCommerce Subscriptions
    – EU VAT Assistant

    (everything up to date)

    A client made filled for a subscription with a VIES validated VAT number at the time of the order and the exemption was correctly applied.

    That subscription was created without VAT, of course:
    https://snipboard.io/hB4xYc.jpg

    One year later (yesterday), the subscription was automatically renewed and the values are automatically copied over to the new order (so no VAT is applied on this new automatic order also), but now the VAT number no longer validates on VIES:

    VAT number was not valid, or could not be validated for this renewal. Validation result: “not-valid“. RAW VIES Response: “{
    “valid”: false,
    “company_name”: “”,
    “company_address”: “”,
    “errors”: [],
    “requestidentifier”: “”,
    “raw_response”: {
    “countrycode”: “NL”,
    “vatnumber”: “REMOVED”,
    “requestdate”: “2021-06-09+02:00”,
    “valid”: “false”,
    “tradername”: “”,
    “tradercompanytype”: “—“,
    “traderaddress”: “”,
    “requestidentifier”: “”
    },
    “validation_source”: “vies”
    }”. It would be advisable to contact the client to verify that their details are correct.

    I’ve checked the number on VIES manually and I can confirm it no longer validates. I’ve also tried to checkout on my website with that VAT number and I can’t get the exemption.

    In short: when subscriptions are renewed the fact that VAT exists or not is copied over to the new order without any previous validation, even if the VAT number no longer validates.

    Update: This also happens when renewing earlier (manually on “My Account”) and using the “modal” option of WooCommerce Subscriptions, but not when the modal is deactivated and the regular checkout happens (in that scenario the VAT number is properly validated again before the payment occurs).

    Anyone else with this issue, or has an idea on how to solve it?

Viewing 13 replies - 1 through 13 (of 13 total)
  • Plugin Author Diego

    (@daigo75)

    The EU VAT Assistant validates the VAT number at every renewal (manual or automatic), just like it does when the subscription is created, and doesn’t apply an exemption if the number is not valid. You can find the result of such validation in the following meta:
    vat_number
    _vat_country
    _vat_number_validated

    If the exemption is applied to a renewal without a valid VAT number, I would expect that the cause is one of the following:
    1. Something is filtering the validation result, returning a valid response.
    2. The original order contains meta is_vat_exempt, which WooCommerce copies over.
    3. When the renewal order is created, the Subscriptions plugin doesn’t recalculate the takes on the renewal.

    Checking #1 and #2 should be simple enough
    1. For #1, you can look for a filter for wc_aelia_eu_vat_assistant_customer_vat_exemption, which is the hook that the EU VAT Assistant uses to allow 3rd parties to alter the result of a validation.
    2. For #2, you can simply check the meta in the renewal order.
    3. For #3, the test is slightly more complex. The EU VAT Assistant determines if an order should be exempt or not, and it acts in two possible ways:
    1. Order exempt -> Set the exemption status. This is what prevent taxes from being added to an order.
    2. Order not exempt -> Do nothing.

    The EU VAT Assistant doesn’t trigger a calculation, or recalculation of taxes, when an order is not exempt. The assumption is that the calculation always taxes place, but it’s skipped when the “exempt” flag is set. However, the plugin doesn’t check if that actually happens. For example, if a renewal is copied verbatim from a previous subscription, and the tax calculation is not triggered, the EU VAT Assistant won’t know about it.

    One useful test could be to trigger the renewal after disabling the EU VAT Assistant. If the renewal is created without taxes, it could mean that the tax calculation was not performed at all.

    Thread Starter Marco Almeida | Webdados

    (@webdados)

    Hi @daigo75 and thanks for your answer,

    1. Something is filtering the validation result, returning a valid response.

    It’s not that, because I get the validation error on the order notes.

    2. The original order contains meta is_vat_exempt, which WooCommerce copies over.

    Yes, that’s definitely happening, as that field is not exempt in the wcs_copy_order_meta function: https://snipboard.io/GyxJjA.jpg

    3. When the renewal order is created, the Subscriptions plugin doesn’t recalculate the takes on the renewal.

    Probably that too.

    if a renewal is copied verbatim from a previous subscription, and the tax calculation is not triggered, the EU VAT Assistant won’t know about it

    It seems to be the case, as order items are just copied over from the subscription order including the taxes in the wcs_copy_order_item function: https://snipboard.io/dY5um4.jpg

    Is this the first time someone raises this issue?
    Have you ever looked into this?

    Plugin Author Diego

    (@daigo75)

    If the meta is_vat_exempt is set against the renewal, and it contains “yes”, then that will make the order exempt from VAT, preventing WooCommerce from adding it. However, that doesn’t come from the EU VAT Assistant, as the plugin doesn’t populate the is_vat_exempt meta. The plugin leaves that meta alone, whatever it contains, and determines an order’s VAT exemption on the fly instead, using a filter for woocommerce_order_is_vat_exempt. That filter is linked to the VAT number validation, therefore it won’t return “exempt” if the VAT number is not valid.

    Whether the Subscriptions plugin triggers the recalculation of taxes or not, we wouldn’t be able to say. Technically, it should, because it’s generating a new order, and VAT rates could have changed since last time. For example, a subscription could be renewed in February, and the VAT rate could have changed at the end of the previous year. The VAT would have to be recalculated.

    I don’t think we tested that the tax calculation would actually take place, as it was outside the scope of our solution. As explained, the EU VAT Assistant either sets a VAT exemption, or does nothing, but it’s not the one who calculates the taxes.

    The logic is simple:
    1. WooCommerce creates an order.
    2. The EU VAT Assistant checks if an exemption should be applied or not. If yes, it informs WooCommerce. If not, it does nothing.
    3. WooCommerce starts the tax calculation. If the “exempt” flag is there, this operation should be skipped. If not, it should go ahead and add the taxes (unless something else prevents it).

    The EU VAT Assistant won’t know if step #3 takes place, as it’s not responsible for ensuring the calculation of taxes.

    This is indeed the first time that this issue is reported. When we tested the subscriptions integration, it worked fine. As of today, no other user reported this issue. Also, although we originally developed the EU VAT Assistant for internal use, and we have been running for years, we don’t use subscriptions, therefore we never came across that scenario.

    I would still recommend to try the test I described earlier, i.e. to trigger the renewal after disabling the EU VAT Assistant. If the renewal is created without taxes, it could mean that the tax calculation was not performed at all.

    Thread Starter Marco Almeida | Webdados

    (@webdados)

    Hi again @daigo75,

    Thanks again for your reply.
    I know the EU VAT plugin does not calculate the taxes itself ??

    I opened this ticket not as a bug report but as a heads up and trying to understand if this issue as arose before and there was a known solution or anything could be done on this plugin side, and help to achieve it, either by helping investigate the issue causes or by financially sponsoring the solution.

    Whether the Subscriptions plugin triggers the recalculation of taxes or not, we wouldn’t be able to say. Technically, it should, because it’s generating a new order, and VAT rates could have changed since last time. For example, a subscription could be renewed in February, and the VAT rate could have changed at the end of the previous year. The VAT would have to be recalculated.

    Exactly! I will now contact the WooCommerce Subscriptions support to check on this and will get back here with feedback when and if I get it.

    Plugin Author Diego

    (@daigo75)

    If you need help to investigate the issue, we could also schedule a consultation. Since the Subscriptions plugin is not developed by us, that would be a paid service. If you would like to avail of it, please feel free to get in touch by using our contact form (https://aelia.co/contact) and we will get back to you with more information.

    Important
    Before spending further time investigating, I would like to repeat my suggestion of running a test with the EU VAT Assistant disabled, before contacting the support team for the Subscriptions plugin. This is important to verify that the issue persists without our solution. Without that information, you could receive an answer like “ask the authors of the other plugin”, which would bring you back to square one.

    Thread Starter Marco Almeida | Webdados

    (@webdados)

    I just did that test.

    1) Created a subscription with a valid VAT number for exemption:
    https://snipboard.io/T5i2rH.jpg
    https://snipboard.io/pkEQhC.jpg

    2) Disabled the EU VAT Assistant plugin

    3) Renewed the subscription using the Modal (which is basically the same as the automatic renewal, because it doesn’t go through the checkout), and the VAT is not there:
    https://snipboard.io/PvNxSn.jpg

    If I do a regular checkout manual renewal, the VAT is correctly calculated on the order:
    https://snipboard.io/diqOaZ.jpg

    Thread Starter Marco Almeida | Webdados

    (@webdados)

    Hi again @daigo75,

    Can you add an action to plugin-main.php, after line 1281, so that developers can do “something” when this happens?

    Something like:
    do_action( 'wc_aelia_wcs_renewal_order_created_vat_not_valid', $renewal_order, $subscription );

    This way, a shop owner could easily set up a proper email alert for this situation, or maybe even use this action to cancel this order and advise the customer via email to do a manual renewal via the regular checkout, where the VAT is always properly calculated.

    This will have zero impact on anyone not using this action but could solve the problem for those who use it.

    The reason I ask you this is that I’ve done some extra tests and realize it is not easily possible for the WooCommerce Subscriptions developers to solve the issue because on the original order there’s no information whatsoever about which tax class to use (because it was removed at checkout), so calling the calculate_totals or calculate_taxes order methods will not have any impact at all. The only solution would be to completely rebuild the order from the product itself so that the correct tax classes would be fetched, which I think is easier to say than to do.

    Plugin Author Diego

    (@daigo75)

    I tend to avoid adding overly specific filters, especially when they are related to 3rd party plugins. You shouldn’t need that filter, either, as you can use the one from the Subscriptions plugin. Example:

    add_action('wcs_renewal_order_created', function($renewal_order, $subscription) {
    	// The following will tell you if the order is VAT exempt. The EU VAT Assistant
    	// intercepts the filter, in case there is a valid VAT number
    	$order_is_vat_exempt = apply_filters('woocommerce_order_is_vat_exempt', $renewal_order->get_meta('is_vat_exempt' ), $renewal_order);
    
    	// This gives you the result of the VAT number validation, if any. This is a less recommended
    	// approach, as it's more tightly coupled with how the EU VAT Assistant works. If the meta will
    	// change in the future, the code might not work properly
    	$validation_result = $renewal_order->get_meta('_vat_number_validated');
    
    	// Perform other operations, depending on the above data
    }, 999, 2);

    This will allow you to intercept the creation of a renewal, whether the EU VAT Assistant is running or not, and do what you like with it.

    Thread Starter Marco Almeida | Webdados

    (@webdados)

    Or maybe I can use the exact same test you’re using on your plugin wcs_renewal_order_created method?

    if(!empty($vat_number) && ($this->vat_number_validated !== Definitions::VAT_NUMBER_VALIDATION_VALID)) {

    Plugin Author Diego

    (@daigo75)

    You can’t use the same code, because $this refers to the VAT Assistant instance. Even if it worked, it would be even more tightly coupled with the plugin implementation, which may or may not change in the future.

    If you wish to perform the exact same test, the code is the one I sent you earlier. The call would be something like this:

    if($renewal_order->get_meta('_vat_number_validated') !== 'valid') {
      // Do something
    }

    Still, I don’t recommend this approach, both because (again) it’s tightly coupled with the plugin logic, and because it would not cover you if the order happens to be vat exempt for some other reason.

    Thread Starter Marco Almeida | Webdados

    (@webdados)

    Got it.

    I’ve hooked into wcs_renewal_order_created after you (priority 30) and I get valid for $renewal_order->get_meta('_vat_number_validated'), which is odd.

    This happens because you run save_eu_vat_data inside wcs_renewal_order_created at line 1264 and the order is saved to the database, but the $renewal_order object that is returned is not affected by these changes.

    Just for reference, I needed to get the order from the database with $renewal_order = wc_get_order( $renewal_order->get_id() );, instead of using the object that comes from the filter, to get the updated meta value for _vat_number_validated.

    I’m now getting an email each time this happens, but my goal is to avoid the renewal order at all and inform the customer that he needs to do it manually.

    Plugin Author Diego

    (@daigo75)

    Indeed, the $renewal_order object passed to the filter might not “see” the new meta, because WooCommerce uses a caching system and doesn’t read the meta after it has been added. In this case, either forcing a refresh of the meta on the order, or creating a new instance with wc_get_order(), like you did, should be sufficient to address the issue.

    Note
    I wouldn’t recommend to replace the $renewal_order variable with a new instance. I would use a new variable name instead. Something like this:
    $tmp_order = wc_get_order($renewal_order->get_id());
    This is so that the original one generated by the Subscriptions plugin is unaltered.

    Thread Starter Marco Almeida | Webdados

    (@webdados)

    Good tip, thanks.

Viewing 13 replies - 1 through 13 (of 13 total)
  • The topic ‘Exemption being applied incorrectly to subscriptions’ is closed to new replies.