WooCommerce: Tax Exempt User Based on Checkout Field Value

There is a nice WooCommerce function you can use to exempt someone from Tax/VAT calculations. You could, for example, enable exemption once they enter a Tax/VAT number, or maybe if they specify a given ZIP code.

Such function is called set_is_vat_exempt(), and together with a little trick to “get” a checkout field on the go, the snippet is pretty simple to build and test. Enjoy!

WooCommerce: zero tax/vat if ZIP code equals ‘XYZ’

PHP Snippet: Remove Tax @ WooCommerce Checkout if Field Value Exists

Explanation of the Code:

  1. Hook:
    • The first line uses add_action to hook the function bbloomer_taxexempt_checkout_based_on_zip to the action woocommerce_checkout_update_order_review.
    • This means the function will be executed whenever the checkout review is updated during the checkout process.
  2. Function bbloomer_taxexempt_checkout_based_on_zip:
    • This function takes an argument $post_data which is an array containing the data submitted during the checkout update.
  3. Reset VAT Exemption:
    • Inside the function, the line WC()->customer->set_is_vat_exempt( false ); resets the customer’s VAT exemption status to false initially.
  4. Parse Checkout Data:
    • The line parse_str( $post_data, $output ); parses the $post_data into an associative array named $output. Each key in the $output array represents a field name from the checkout form (e.g., billing_postcode).
  5. Check Billing Postcode:
    • The if statement checks if the value of the billing_postcode key in the $output array matches the specific code '32444'.
  6. Set VAT Exemption (if matched):
    • If the postcode matches, the line WC()->customer->set_is_vat_exempt( true ); sets the customer’s VAT exemption status to true. This will potentially affect the calculation of taxes during checkout.

In summary, this code snippet checks the billing postcode entered during checkout. If it matches the specified code, the customer is marked as VAT exempt, potentially impacting the final checkout total.

/**
 * @snippet       Remove Tax if Field Value - WooCommerce Checkout
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli, BusinessBloomer.com
 * @testedwith    WooCommerce 8
 * @community     https://businessbloomer.com/club/
 */
 
add_action( 'woocommerce_checkout_update_order_review', 'bbloomer_taxexempt_checkout_based_on_zip' );
 
function bbloomer_taxexempt_checkout_based_on_zip( $post_data ) {
        WC()->customer->set_is_vat_exempt( false );
        parse_str( $post_data, $output );
        if ( $output['billing_postcode'] === '32444' ) WC()->customer->set_is_vat_exempt( true );
}

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

  • WooCommerce: Cart and Checkout on the Same Page
    This is your ultimate guide – complete with shortcodes, snippets and workarounds – to completely skip the Cart page and have both cart table and checkout form on the same (Checkout) page. But first… why’d you want to do this? Well, if you sell high ticket products (i.e. on average, you sell no more than […]
  • WooCommerce: Disable Payment Method If Product Category @ Cart
    Today we take a look at the WooCommerce Checkout and specifically at how to disable a payment gateway (e.g. PayPal) if a specific product category is in the Cart. There are two tasks to code in this case: (1) based on all the products in the Cart, calculate the list of product categories in the […]
  • WooCommerce: Add Privacy Policy Checkbox @ Checkout
    Here’s a snippet regarding the checkout page. If you’ve been affected by GDPR, you will know you now need users to give you Privacy Policy consent. Or, you might need customer to acknowledge special shipping requirements for example. So, how do we display an additional tick box on the Checkout page (together with the existing […]
  • WooCommerce: Redirect to Custom Thank you Page
    How can you redirect customers to a beautifully looking, custom, thank you page? Thankfully you can add some PHP code to your functions.php or install a simple plugin and define a redirect to a custom WordPress page (as opposed to the default order-received endpoint). This is a great way for you to add specific up-sells, […]
  • WooCommerce: Disable Payment Gateway by Country
    You might want to disable PayPal for non-local customers or enable a specific gateway for only one country… Either way, this is a very common requirement for all of those who trade internationally. Here’s a simple snippet you can further customize to achieve your objective. Simply pick the payment gateway “slug” you want to disable/enable […]

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

59 thoughts on “WooCommerce: Tax Exempt User Based on Checkout Field Value

  1. The code doesn’t work in 2024. I’ve tried it and there is no error and issue and still doesn’t work.

    1. Actually, it works perfectly and sets the tax to $0 – it must be something else

  2. For me, the “Tax” field disappears completely. Is that correct? I would like it to be displayed as “Tax 0% – 0,00€”.

    Is it possible? Thank you very much for your time.

    1. No, this does not hide the tax, it sets it to 0. So it must be something else

  3. Hi, what if i need this to work if a specific field is not empty? What would this line look like?

    if ( $output['billing_postcode'] === '32444' ) 
    1. if ( $output['billing_postcode'] !== '' )
  4. So, I’m using the following code since I have a custom field with a dropdown options: “Residential” and “Commercial” with name: billing_category but it’s not updating the Checkout page.

    add_action( 'woocommerce_checkout_update_order_review', 'checkout_based_on_category' );
      
    function checkout_based_on_category( $post_data ) {
            WC()->customer->set_is_vat_exempt( false );
            parse_str( $post_data, $output );
            if ( $output['billing_category'] === 'Commercial' ) WC()->customer->set_is_vat_exempt( true );
    }

    What am I doing wrong?

    1. Hi Obaidullah thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  5. How to remove tax on specific payment gateway selection?

    1. Hi Ankit, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  6. Hi Rodolfo, i tried with this code for a custom field with value of Yes or No, thats mean add tax or not, its working fine, but how could i refresh total price alfter the selection changes? The post code field could refresh the total price as what it is with woocommerce, but i’m looking for a solution for custom field.

    Thanks a lot

    1. Hi Enzo, you need to rename your custom field ID or name (don’t remember which one, so try both). Make it start with “billing_” or something like that. Let me know if that does the trick

  7. add_action( 'woocommerce_checkout_update_order_review', 'bbloomer_taxexempt_checkout_based_on_zip' );
      
    function bbloomer_taxexempt_checkout_based_on_zip( $post_data ) {
            WC()->customer->set_is_vat_exempt( false );
            parse_str( $post_data, $output );
            if ( $output['billing_country'] === 'New Zealand' || $output['billing_country'] === 'NZ' ) {
    			WC()->customer->set_is_vat_exempt( false );
    		} else {
    			WC()->customer->set_is_vat_exempt( true );
    		};
    }
    

    Hey there! this is my adapted version of the code so that it only charges tax in NZ (New Zealand), I’m trying to make it so that instead of the tax being removed as such, the total value stays the same, it’s just not labelled as tax.

    For example:
    In New Zealand the tax rate is 15%, it’s known as GST.
    I want to sell a product for $20.
    So when I sell said product for $20 in New Zealand, I receive $17 after GST/Tax.
    When I sell the same product to someone in Australia, or Canada (or literally any other country), I sell it for $20, and recieve $20 with no tax charged.

    How can I adapt my code to do this?

    Thanks,
    Ben Elwood

    1. Hey Ben, if I understand well, you can do that from the Woo settings alone without code

  8. Hi here is my code with changes:
    I added isset to not give php error and check if Vat is set.
    and check if country is not spain. Code gives 0% Vat based on correct Eu Vat number

    add_action( 'woocommerce_checkout_update_order_review', 'bbloomer_taxexempt_checkout_based_on_vat' );
    
    function bbloomer_taxexempt_checkout_based_on_vat( $post_data ) {
            WC()->customer->set_is_vat_exempt( false );
            parse_str( $post_data, $output );
            if ( isset($output['_billing_vat_number']) === '*' and $output['_billing_country'] !== 'Spain') WC()->customer->set_is_vat_exempt( true );
    }
    
    1. combining it wit EU VAT assistant plugin which checks VAT number in VIES

        1. Thanks, and thanks for the snippet

  9. Hi I would like to ask what if instead of postcode, I want the whole Oregon State? How to do that?
    if ( $output[‘billing_state’] === ‘oregon’ ) WC()->customer->set_is_vat_exempt( true ); is not working.

    Please help. Thank You.

    1. You need the 2-letter state code there

  10. Hi Rodolfo,
    Thank you for your contribution.
    I used this snippet to disable tax from users outside EU, based on their choice on invoice dropdown field,
    Although tax is disabled on checkout page. On payment success page the total includes tax.

    1. Thanks George. Is the customer charges the right amount once they pay? If yes, than maybe it’s only a display issue that would need to be fixed either by me or by you (try disabling ALL plugins but WooCommerce and test again)

  11. Hi, The code didnt work for me. THe code still working?

    1. Yep, try disabling all your plugins and theme temporarily and test again

      1. I think the problem is the plugin multi step checkout.
        How do I get the direct value of the input in the onchange event or something? Because the value is not changing when I change the field value. I have to press F5 to work.

        1. Hello there, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  12. Man… I am just not good at this… but I really need this function if a simple checkbox is checked upon checkout. Is it as easy as creating a checkbox and applying custom CSS to the checkbox??

    1. Matt, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  13. update the function please

    Error:
    parse_str(): Calling parse_str() without the result argument is deprecated

    1. Done, thank you. Can you test again?

  14. So this works on the checkout page, but the second I actually go through with the order and hit the order-received page the order includes a VAT value that’s saved in the record and will mess up our accounting.

    What else do I need to tweak to make this work?

    1. Hi Jason, thanks so much for your comment! Yes, this is possible, I haven’t tested it after checkout. It can be fixed in case it’s not a plugin/theme conflict but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  15. Hi ! I’m trying to set the tax 0 if the billing company field is set, but I don’t know how, can you help me?
    Thank you so much !

    1. Hello Jose, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  16. Hello!
    How can I make this work if I want students and non profits with tax ID to be exempt at checkout without having them to register as users?

    thank you!

    1. Hello George, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  17. Hey,
    Thanks a lot, I am using your solution and many other piece of code you share. I have noticed a undesirable behaviour of this code: if customer go back and forth between the payment page and the checkout page, a new custom field is_vat_exempt is set. That means that this custom field add up. I had the case where there was so many of them that it broke the payment validation. Is there a way to make sure there is a unic is_vat_exempt custom field for a given order?

    1. Hi Jonathan – if you remove my snippet does that happen as well? If yes, and if you disable all plugins but Woo and swith temporarily to 2017 theme, does that happen again? Let me know

  18. Hi. I am trying to use this on a custom radio button, but it’s not working.

    Here is the code for the button which works.

    function add_radio_field(){
      	$radioFile   = "";
     	$radioFile   .='<div class="customfield_cover"><label for="some_field_name" class="">Tax Exempt? </label><div id="radio_cover_id">';
     	$radioFile .='<input name="uhave_tax_exempt" id="uhave_tax_exempt" class="tax_exempt" type="radio" value="1" >Yes&nbsp;&nbsp;&nbsp;&nbsp;<input class="tax_exempt" name="uhave_tax_exempt" type="radio" value="2" >No';
     	$radioFile .='</div></div>';
     	echo $radioFile;
     }
    add_action('woocommerce_before_order_notes','add_radio_field');

    But the code to remove the taxes isn’t working for me. I probably did something wrong.

    add_action( 'woocommerce_checkout_update_order_review', 'bbloomer_taxexempt_checkout_based_on_zip' );
     
    function bbloomer_taxexempt_checkout_based_on_zip( $post_data ) {
            global $woocommerce;
            $woocommerce->customer->set_is_vat_exempt( false );
            parse_str($post_data);
            if ( $uhave_tax_exempt == 1 ) $woocommerce->customer->set_is_vat_exempt( true );
    }
    1. Hi Boston – it could be your field is not “posting” or that the $post_data variable needs to be debugged. Let me know

  19. I love this script and it works as expected, would that work with any other fields? I have added a custom field and I want to remove the tax when a checkbox is checked.

    1. Thanks Nik 🙂 Yes, it should

  20. Hi Rodolfo,

    Great Code!
    is there any way to update product subtotal too?

    Thanks

    1. Hello Sigma, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  21. Thanks Rodolfo, I use your code but unfortunatly it doesn’t work when you place an order. The thank-you page diplays the price with the tax even if at the check out it’s zero. Don’t know why… 🙁

    1. Hey Federico 🙂 Try disabling all plugins and switching theme temporarily – does the snippet work then?

      1. Hi Rodolfo, I have same issue of Federico. On checkout form your snippet works as expected, but on Thankyou page taxes are not exempted and the same happens on admin order page. I tried deactivating all plugins and changing theme but with no luck. How can i do to solve the issue?
        Thanks, Fabrizio

        1. Hey Fabrizio, thanks for your comment! I just tested this again with Storefront theme and it works perfectly. Maybe your theme (or another plugin) is messing/conflicting with my snippet?

          To troubleshoot, disable all plugins but WooCommerce and also switch temporarily to “Twentyseventeen” theme (load the snippet there in functions.php) – does it work? If yes, you have a problem with your current theme or one of the plugins.

          Hope this helps!

          R

  22. Hi Rodolfo
    excellent snippet
    one question , would this work for specific category of products ?

    thanks in advance

  23. Dear Rodolfo Melogli,

    Many thanks for this contribution! It works when I apply this rule to the following fields:

    billing_address_1
    billing_postcode
    billing_city

    Unfortunately it doesn’t work when I want to apply it to any other fields. Somehow those fields don’t get validated automatically. In face I want to apply it to a new field which is the tax number of the customer. Once the customer has entered a tax number the additional tax should be removed.

    Can you help me? Many thanks in advance!

    Best,

    Matthieu

    1. Matthieu, thanks so much for your comment! Unfortunately this is custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~R

  24. Hi ROdolfo, is there a way to Remove Tax if customer selects payment method cash?
    Thanks,
    Sandra

    1. Sandra, thanks for your comment! Yes, there is of course, you will need a little edit to the PHP of this snippet. Unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  25. Hello dear Rodolfo,

    you are great! Can you please give example how to use this function with Tax/VAT number field? I have setup field for UIC, but i have to remove VAT for order outside the country when VAT number is entered…

    Thank you for this awesome piece of code! 🙂

    1. Hey Vladimir, thanks for your comment! You’ll need to change the line:

      if ( $billing_postcode == ___ )
      

      … with the name of the variable generated by your new Tax field, which is custom to your code and I can’t help with in here I’m afraid! 🙂

  26. How about hide Sale Tax if Sale Tax is zero?

    1. Hey Vuster, thanks for your comment! I’m not sure I fully understand – could you send over a screenshot?

    2. I agree. In some stores, there is no tax at all… yet WooCommerce still shows Tax: $0.00 in cart and checkout. I’d like to hide the Tax row if there is a $0 tax value for the cart/order.

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

Your email address will not be published. Required fields are marked *