Woocommerce - Product price depending on country

10,403

For the 2nd part of your question: If you are only using simple product types (without variations) then you can add custom price fields to the product data page and filter the price using woocommerce_get_price_html.

add_filter('woocommerce_get_price_html','so24863612_custom_price');
function so24863612_custom_price(){
   global $post;
   $_postID = $post->ID;
   $product = get_product( $_postID );
   $UK_price = get_post_meta($_postID, '_UK_price', true); //loads custom meta data 
   $return_price = $product->get_regular_price(); //default to regular price
   if (!empty($UK_price)) { 
      $return_price = $UK_price;
   }
   return $return_price;
}

You can create and save custom fields on the product page like this:

//Display custom fields on product data page in admin
add_action( 'woocommerce_product_options_general_product_data', 'so24963039_display_custom_general_tab_fields' );
function so24963039_display_custom_general_tab_fields() {
    global $woocommerce, $post;
    $UK_price = get_post_meta( $post->ID, '_UK_price', true );

    woocommerce_wp_text_input(
        array(
        'id' => '_UK_price',
        'label' => __( 'UK Price (£)', 'woocommerce' ),
        'value' => $UK_price,
        'desc_tip' => 'false'
        )
    );
}

//Save custom fields to access via get_post_meta
add_action( 'woocommerce_process_product_meta', 'so24963039_save_custom_general_tab_fields' );
function so24963039_save_custom_general_tab_fields ($post_id) {

    $woocommerce_UK_price = $_POST['_UK_price'];
    if( !empty( $woocommerce_UK_price ) )
    update_post_meta( $post_id, '_UK_price', esc_attr( $woocommerce_UK_price ) );   

}

-----------------For products with Variations----------------------------

WARNING: Variable products are much more complicated and I'm not nearly as confident in this answer as I am with the simple products part above, but here's my current understanding either way. I had some mini-cart display issues that I had to hack around when using this method (which I will explain at the end), but the totals are calculated correctly in both the mini-cart and the regular cart.

First we want to add new fields to each variant on the variation tab of existing products:

add_action( 'woocommerce_product_after_variable_attributes', 'so24963039_variable_fields', 10, 2 ); //Display Fields
function so24963039_variable_fields( $loop, $variation_data ) {

echo '<tr><td>';
woocommerce_wp_text_input(
    array(
        'id' => '_variant_UK_price['.$loop.']',
        'label' => __( 'UK Price (£)', 'woocommerce' ),
        'desc_tip' => 'false',
        'value' => $variation_data['_variant_UK_price'][0]
    )
);
echo '</td></tr>';
}

We also need to add them dynamically whenever the user adds new variants on the edit product page:

add_action( 'woocommerce_product_after_variable_attributes_js', 'so24963039_variable_fields_js' ); //JS to add fields for dynamically added new variations
function so24963039_variable_fields_js(){ //add fields to new variations that get added 
echo '<tr><td>';
woocommerce_wp_text_input(
    array(
        'id' => '_variant_UK_price[ + loop + ]',
        'label' => __( 'UK Price (£)', 'woocommerce' ),
        'desc_tip' => 'false',
        'value' => $variation_data['_variant_UK_price'][0]
    )
);
echo '</td></tr>';
}

Then we save changes to the custom fields in the variation meta data:

add_action( 'woocommerce_process_product_meta_variable', 'so24963039_save_variable_fields', 10, 1 ); //Save variation fields
function so24963039_save_variable_fields( $post_id ) {
if (isset( $_POST['variable_sku'] ) ) {
    $variable_sku = $_POST['variable_sku'];
    $variable_post_id = $_POST['variable_post_id'];

    // Variant Tier 1 Price
    $_variant_UK_price = $_POST['_variant_UK_price'];
    for ( $i = 0; $i < sizeof( $variable_sku ); $i++) {
        $variation_id = (int) $variable_post_id[$i];
        if ( isset( $_variant_UK_price[$i] ) ) {
        update_post_meta( $variation_id, '_variant_UK_price', stripslashes($_variant_UK_price[$i] ) );
        }
    }
}
}

Now that we have our custom variation meta data, we can access it in the custom price module like so:

add_filter('woocommerce_get_price_html','so24863612_custom_price');
function so24863612_custom_price(){
   global $post;
   $_postID = $post->ID;
   $product = get_product( $_postID );
   $product_type = $product->product_type;

   $UK_price = get_post_meta($_postID, '_UK_price', true); //covers simple products 
   if($product_type == 'variation'){ //override with variant prices
            $UK_price = get_post_meta($_postID, '_variant_$UK_price', true);
    }

   $return_price = $product->get_regular_price(); //default to regular price
   if (!empty($UK_price)) { 
      $return_price = $UK_price;
   }
   return $return_price;
}

Now, I believe that part should have everything working except for the mini-cart display. For some reason it seems like I just couldn't figure out how to get access to the variation meta data to force it to display properly in the mini cart - like I found where the mini-cart display was being generated but I was having trouble getting the right context path to access the custom variable so I ended up having to do that in the template-tags.php and pass an array of custom values to an optional parameter in my custom price function. This feels very 'wrong' in terms of how we should do things, but it gets the job done. I'm very open to hearing the 'correct' solution to this part of the problem.

In template-tags.php:

<div class="small-7 large-7 columns"><?php 
                                            $product_title = $_product->get_title();
                                            echo '<a class="cart_list_product_title" href="'.get_permalink($cart_item['product_id']).'">' . apply_filters('woocommerce_cart_widget_product_title', $product_title, $_product) . '</a>';
                                            echo '<div class="cart_list_product_price">';
                                            //original line: echo woocommerce_price($_product->get_price());

                                            /*Custom Price Override Block*/
                                            $_productID = $_product->id;
                                            $product_type = $_product->product_type;
                                            if($product_type == 'variation') {
                                                $custom_field_data = $_product->product_custom_fields;
                                                $regular_price = $custom_field_data['_regular_price'];
                                                $custom_UK_price = $custom_field_data['_variant_UK_price'];
                                                $custom_variant_prices = [$regular_price[0], $custom_UK_price[0]];
                                                echo so24863612_get_custom_price($_productID,  $custom_variant_prices ); 
                                            } else {
                                                echo so24863612_get_custom_price($_productID );
                                            }
                                            /*End Custom Price Override Block*/

                                            echo ' /</div>';
                                            echo '<div class="cart_list_product_quantity">'.__('Quantity', 'woocommerce').': '.$cart_item['quantity'].'</div>';

                                        ?></div>
Share:
10,403
Admin
Author by

Admin

Updated on June 17, 2022

Comments

  • Admin
    Admin almost 2 years

    I have 2 questions regarding Woocommerce for Wordpress.

    I'm working on a site that sells speakers to the Danish market.

    Question one:

    Can I detect the IP of a visitor and detect which country the person is from? I guess this can be done with some ClientLocation api.

    Can I then disable all shopping relatet pages and buttons if a person is not from Denmark. Fx: hiding the add to cart, cart and checkout. I still want the persons to be able to see the prices, they should just not have the option to buy them.

    Question 2:

    Lets say that question one was sucessfull made. Then I would like to show different prices for other contries than Denmark. So if you are visiting the site from one country, the price is XXX and from another country the price is XXXX.
    Let's say:

    In USA the price is = $500 
    And in UK the price = £400
    

    (This has nothing to do with currency. The market price is just different in different countries.)

    I've looked at this plugin: http://wordpress.org/plugins/woocomerce-price-by-country/ It allowed me to write different prices for each product, but when I testet it with http://geopeeker.com/ I hadn't worked at all.

    Can you give me some pointets or some links to some plugins that you know of?

    UPDATE

    I managed to solve question 1. I store the visitors country in a cookie with IP location XML API And then I could just create an if statement, saying that if the country was not equal to Denmark, then the add to cart, cart etc. should be removed.

    So yeah, I would really appreciate it if anyknow could give me an idea on how I can solve question 2.

    I'm able to detect country, but not able to specify a price of each product to the given country.

    2'nd update:

    Just to let any interested readers know, I ended up buying this plugin. which is working perfectly!

  • Admin
    Admin almost 10 years
    Hi. Thank you for your answer. And I'm sorry for the late reply. Unfortunately I have product variations, and not just simple products.
  • FascistDonut
    FascistDonut almost 10 years
    I was afraid you were going to say that. My client needed the same thing and I struggled with it for a week or so. I got it working, but it is a little hacky when it comes to the mini-cart display. (I had to edit a template file rather than fix it with a hook because I couldn't figure out how to get access to the variant meta data from within my plugin yet) Let me know if you happen to figure out a better way to do it!
  • Admin
    Admin almost 10 years
    Thank you. That has got me far! But I still haven't crossed the finishline. But I have acceptet your answer. Thanks for all the help. I'll let you know if I find an optimised way.
  • SolaceBeforeDawn
    SolaceBeforeDawn over 9 years
    FYI there is also an additional plugin by Roy Ho which appears to offer some additional options for you in that you can show specific products based on country IP wordpress.org/plugins/woocommerce-geolocation-based-products