Romeo Patrick
Romeo Patrick

Reputation: 73

Disable VAT for specific countries in WooCommerce

Original code makes all prices set to the same, no matter what the VAT % is. So if a item cost 100$ with 25% VAT, it will cost 100$ with 80% VAT or even 0% VAT.

That works fine, however, some countries I would like to remove the VAT for.

Original code from this answer thread:

add_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );

My code that is not working:

add_filter( 'woocommerce_adjust_non_base_location_prices', 'custom_eu_vat_number_country_codes' );
function custom_eu_vat_number_country_codes( $vat_countries ) {

// Which countries should it be applide to?
    $countries = array( 'AX', 'AT', 'BE', 'BA', 'HR', 'CZ', 'DK', 'FI', 'GR', 'HU', 'IS', 'IE', 'IT', 'LU', 'NL', 'PO', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'CH', 'GB');

    // Avoiding errors on admin and on other pages
    if( is_admin() || WC()->cart->is_empty() )
        return $countries;

// Remove field $countries
if (($key = array_search($countries, $vat_countries)) !== false) {
    return false;
}
return $vat_countries;
}

What am I doing wrong?

Upvotes: 2

Views: 1600

Answers (2)

jgangso
jgangso

Reputation: 658

Adding this a as separate answer although it's mostly based on @LoicTheAztec's answer.

The only difference is that the code checks customers shipping country (not billing country), since VAT follows the "destination principle", that is, VAT is calculated based on the country where the product/service is consumed. (the case for EU at least).

add_filter( 'woocommerce_adjust_non_base_location_prices', 'custom_eu_vat_number_country_codes' );
function custom_eu_vat_number_country_codes( $boolean ) {
    // Avoiding errors on admin and on other pages
    if( is_admin() || WC()->cart->is_empty() )
        return $boolean;

    // Defined array of countries where the boolean value should be "false"
    $countries = array( 'AX', 'AT', 'BE', 'BA', 'HR', 'CZ', 'DK', 'FI', 'GR', 'HU', 'IS', 'IE', 'IT', 'LU', 'NL', 'PO', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'CH', 'GB');

    // Remove field $countries
    if ( in_array( WC()->customer->get_shipping_country(), $countries ) ) {
        $boolean = false;
    }
    return $boolean;
}

Upvotes: 0

LoicTheAztec
LoicTheAztec

Reputation: 253859

The main function argument is not related to countries, it's a boolean value (true by default), see that on wc_get_price_excluding_tax() function code..

You need to get the customer billing country from WC_Customer Object (or the shipping country).

So your code should be:

add_filter( 'woocommerce_adjust_non_base_location_prices', 'custom_eu_vat_number_country_codes' );
function custom_eu_vat_number_country_codes( $boolean ) {
    // Avoiding errors on admin and on other pages
    if( is_admin() || WC()->cart->is_empty() )
        return $boolean;

    // Defined array of countries where the boolean value should be "false"
    $countries = array( 'AX', 'AT', 'BE', 'BA', 'HR', 'CZ', 'DK', 'FI', 'GR', 'HU', 'IS', 'IE', 'IT', 'LU', 'NL', 'PO', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'CH', 'GB');

    // Remove field $countries
    if ( in_array( WC()->customer->get_billing_country(), $countries ) ) {
        $boolean = false;
    }
    return $boolean;
}

Code goes in functions.php file of your active child theme (or active theme). It should works (untested).

Upvotes: 1

Related Questions