How to display different prices for different countries WooCommerce

One thing that WooCommerce does not do out of the box, is to allow you to display different prices depending on the country your customer is located. This is a very important functionality, if you have to include to the price sliding tax rates, or export fees.

With the following code, you can achieve displaying a different price for your products, depending on where your customer is based on.

First, let’s add a text area with the alternative price:

add_action( 'woocommerce_product_options_pricing', 'tl_add_can_price_box' );
function tl_add_can_price_box() {
    woocommerce_wp_text_input( array( 'id' => 'can_price', 'class' => 'wc_input_price_extra_info short', 'label' => __( 'Price in Canadian , 'woocommerce' ) ) );
}

Then, let’s save the above fields as custom post meta data:

// This one is for saving above fields
add_action('woocommerce_process_product_meta', 'tl_save_can_price', 2, 2);
function tl_save_can_price($post_id, $post) {
    update_post_meta($post_id, 'can_price', stripslashes($_POST['can_price']));
}

Finally, we will add a function that checks the customer country and conditionally shows either the default, or the custom price.

// Here is the logic for price
if(!is_admin()) {
    add_filter( 'woocommerce_get_price', 'change_price', 10, 2 );
    function change_price($price, $product) {
        global $woocommerce;
        $customer_country = $woocommerce->customer->get_country();
        if($customer_country == "CA") {
            return get_post_meta($product->id, 'can_price', true); 
        } else {
            return $price;
        }
        
    }
}

If you have more than one countries with custom prices, you can add another if condition with an elseif statement:

// Here is the logic for price
if(!is_admin()) {
    add_filter( 'woocommerce_get_price', 'change_price', 10, 2 );
    function change_price($price, $product) {
        global $woocommerce;
        $customer_country = $woocommerce->customer->get_country();
        if($customer_country == "CA") {
            return get_post_meta($product->id, 'can_price', true);
        } elseif ($customer_country == "US") {
            return get_post_meta($product->id, 'us_price', true);
        } else {
            return $price;
        }
        
    }
}

Here is the entire snippet together:

add_action( 'woocommerce_product_options_pricing', 'tl_add_can_price_box' );
function tl_add_can_price_box() {
    woocommerce_wp_text_input( array( 'id' => 'can_price', 'class' => 'wc_input_price_extra_info short', 'label' => __( 'Price in Canadian , 'woocommerce' ) ) );
}
// This one is for saving above fields
add_action('woocommerce_process_product_meta', 'tl_save_can_price', 2, 2);
function tl_save_can_price($post_id, $post) {
    update_post_meta($post_id, 'can_price', stripslashes($_POST['can_price']));
}

// Here is the logic for price
if(!is_admin()) {
    add_filter( 'woocommerce_get_price', 'change_price', 10, 2 );
    function change_price($price, $product) {
        global $woocommerce;
        $customer_country = $woocommerce->customer->get_country();
        if($customer_country == "CA") {
            return get_post_meta($product->id, 'can_price', true); 
        } else {
            return $price;
        }
        
    }
}

Waqas

I hope you enjoy reading this blog post. If you want my team to do WooCommerce Maintenance for you, click here.

1 thought on “How to display different prices for different countries WooCommerce”

  1. Great! Thanks for this article.

    Two ideas to improve it:
    1. change_price(): Return can_price only, if it’s filled (> 0)
    2. can_price can’t have decimal places in this example, only whole numbers. Too add decimals change line 3 of the “entire snippet” to:

    woocommerce_wp_text_input(array(‘id’ => ‘can_price’, ‘class’ => ‘wc_input_price_extra_info short’, ‘label’ => ‘Price in Canada’, ‘type’ => ‘number’, ‘custom_attributes’ => array( ‘step’ => ‘any’, ‘min’ => ‘0’ )));

Leave a Comment

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