1

I have a couple of products with some variations. On the homepage, archive page and single product page I am showing the price range of the variations.

I want to change the prices of my variations based on the customer's zipcode. In the variation itself I have a custom field. In this field I can set the price for different zipcodes, for example: 1256PO:120,9856IE:150 -> zipcode:price

I already have the code to check the zipcode and update the price for the variation itself on the productpage and checkoutpage. This works.

add_filter('woocommerce_product_variation_get_price', 'filter_product_variation_price', 10, 2);

function filter_product_variation_price($price, $variation) {
    if (WC()->session) {
        $customer_zipcode = WC()->session->get('customer')['postcode'];
        if (!$customer_zipcode) {
            return $price;

        }
        $zipcode_prices = $variation->get_meta('_zipcode_prices');
        if (!$zipcode_prices) {
            return $price;
        }
        $zipcode_prices = explode(',', $zipcode_prices);
        foreach ($zipcode_prices as $zipcode_price) {
            list($zipcode, $zipcode_price) = explode(':', $zipcode_price);
            if ($zipcode == $customer_zipcode) {
                return $zipcode_price;
            }
        }
    }
    return $price;
}

This code does not update the displayed price range for the parent product. I tried this:

add_filter('woocommerce_variation_prices_price', 'filter_variation_prices_price', 10, 2);

function filter_variation_prices_price($price, $variation) {
    return filter_product_variation_price($price, $variation);
}

This does update the price range but it just checks the lowest and highest price. It does not check the zipcode for some reason.

What I need is to change all prices displayed based on the customers zipcode. Is there anyone who can tell me whats wrong with the filter_variation_prices_price function.

luukd
  • 356
  • 8

1 Answers1

1

All Variable Product price range are cached in WooCommerce for better performance display, so you need to use woocommerce_get_variation_prices_hash filter hook, that will allow to refresh variations cached prices in a much more efficient way, without deleting related transients anytime that this hooks are executed.

Here is your revisited code:

// Custom function that get the customer zipcode
function get_customer_zipcode(){
    if ( WC()->session ) {
        $customer_data = WC()->session->get('customer');
        if ( isset($customer_data['postcode']) ) {
            return $customer_data['postcode'];
        }
    }
    return false;
}

add_filter('woocommerce_product_variation_get_price', 'filter_product_variation_price', 99, 2 ); // Product Variation price
add_filter('woocommerce_variation_prices_price', 'filter_product_variation_price', 99, 2 ); // Variable product displayed price range
function filter_product_variation_price( $price, $variation ) {
    $zipcode = get_customer_zipcode();
    
    if ( $zipcode ) {
        $zipcode_prices = $variation->get_meta('_zipcode_prices');
        
        if ( ! $zipcode_prices ) {
            return $price;
        }
        
        $zipcode_prices = explode(',', $zipcode_prices);
        
        foreach ($zipcode_prices as $zipcode_price) {
            list($zipcode, $zipcode_price) = explode(':', $zipcode_price);
            if ($zipcode == $customer_zipcode) {
                return $zipcode_price;
            }
        }
    }
    return $price;
}

// Handling price caching (see explanations at the end)
add_filter( 'woocommerce_get_variation_prices_hash', 'filter_get_variation_price_hash', 99, 3 );
function filter_get_variation_price_hash( $price_hash, $product, $for_display ) {
    $zipcode = get_customer_zipcode();
    
    if ( $zipcode ) {
        $zipcode_prices = $variation->get_meta('_zipcode_prices');
        
        if ( ! $zipcode_prices ) {
            return $price_hash;
        }
    }
    $price_hash[] = $zipcode;
    
    return $price_hash;
}

Code goes in functions.php file of the active child theme (or active theme). It should work.

See: Caching and dynamic pricing – upcoming changes to the get_variation_prices method

Related: Change product prices via a hook in WooCommerce 3+

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399