Change Product Prices Via a Hook in Woocommerce 3+

Change product prices via a hook in WooCommerce 3+

Update (December 2020)

  • 2 code versions for themes and plugins (works in Woocommerce 3.3.x too)
  • Cached variations prices in Woocommerce 3 (Update and addition):
    Now using woocommerce_get_variation_prices_hash filter hook much more efficient, instead of wc_delete_product_transients()… See this related thread
  • Added product price filter widget hooks (see at the end).

1) Plugin version with a constructor function:

The hooks that you are using are deprecated in WooCommerce 3+

To make it work for all products prices, including variations prices, you should use this:

## The following goes inside the constructor ##

// Simple, grouped and external products
add_filter('woocommerce_product_get_price', array( $this, 'custom_price' ), 99, 2 );
add_filter('woocommerce_product_get_regular_price', array( $this, 'custom_price' ), 99, 2 );
// Variations
add_filter('woocommerce_product_variation_get_regular_price', array( $this, 'custom_price' ), 99, 2 );
add_filter('woocommerce_product_variation_get_price', array( $this, 'custom_price' ), 99, 2 );

// Variable (price range)
add_filter('woocommerce_variation_prices_price', array( $this, 'custom_variable_price' ), 99, 3 );
add_filter('woocommerce_variation_prices_regular_price', array( $this, 'custom_variable_price' ), 99, 3 );

// Handling price caching (see explanations at the end)
add_filter( 'woocommerce_get_variation_prices_hash', array( $this, 'add_price_multiplier_to_variation_prices_hash' ), 99, 3 );


## This goes outside the constructor ##

// Utility function to change the prices with a multiplier (number)
public function get_price_multiplier() {
return 2; // x2 for testing
}

public function custom_price( $price, $product ) {
return (float) $price * get_price_multiplier();
}

public function custom_variable_price( $price, $variation, $product ) {
return (float) $price * get_price_multiplier();
}

public function add_price_multiplier_to_variation_prices_hash( $price_hash, $product, $for_display ) {
$price_hash[] = get_price_multiplier();
return $price_hash;
}

The code tested and perfectly works (only) in WooCommerce 3+.


2) For theme version: functions.php file on active child theme (or active theme):

// Utility function to change the prices with a multiplier (number)
function get_price_multiplier() {
return 2; // x2 for testing
}

// Simple, grouped and external products
add_filter('woocommerce_product_get_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_get_regular_price', 'custom_price', 99, 2 );
// Variations
add_filter('woocommerce_product_variation_get_regular_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
function custom_price( $price, $product ) {
return (float) $price * get_price_multiplier();
}

// Variable (price range)
add_filter('woocommerce_variation_prices_price', 'custom_variable_price', 99, 3 );
add_filter('woocommerce_variation_prices_regular_price', 'custom_variable_price', 99, 3 );
function custom_variable_price( $price, $variation, $product ) {
// Delete product cached price (if needed)
// wc_delete_product_transients($variation->get_id());

return (float) $price * get_price_multiplier();
}

// Handling price caching (see explanations at the end)
add_filter( 'woocommerce_get_variation_prices_hash', 'add_price_multiplier_to_variation_prices_hash', 99, 3 );
function add_price_multiplier_to_variation_prices_hash( $price_hash, $product, $for_display ) {
$price_hash[] = get_price_multiplier();
return $price_hash;
}

Tested and works on woocommerce 3+


For products in sale you have those hooks:

  • woocommerce_product_get_sale_price (Simple, grouped and external products)
  • woocommerce_variation_prices_sale_price (Variable products (min-max))
  • woocommerce_product_variation_get_sale_price (Products variations)


Cached prices and woocommerce 3:

The 3 filters hooks involved in variations cached prices are:

  • woocommerce_variation_prices_price
  • woocommerce_variation_prices_regular_price
  • woocommerce_variation_prices_sale_price

Introduced in Woocommerce 3, woocommerce_get_variation_prices_hash filter hook will allow to refresh variations cached prices in a much more efficient way, without deleting related transients anytime that this hooks are executed.

So performances will stay boosted (Thanks to Matthew Clark that pointed this better way)

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


For filtering product prices with a widget (min and max price), use the following hooks:

  • woocommerce_price_filter_widget_min_amount that has one argument $price
  • woocommerce_price_filter_widget_max_amount that has one argument $price

Change product prices via a hook for specific categories in WooCommerce 3+

There are multiple mistakes in your code and since WooCommerce 3, the hook woocommerce_get_price is obsolete, deprecated and replaced by:

  • woocommerce_product_get_price for product post type
  • woocommerce_product_variation_get_price for product_variation post type

Based on Change product prices via a hook in WooCommerce 3+, here is the way to change product prices for specific product category (that requires much more code):

// Simple, grouped and external products (and product variations)
add_filter( 'woocommerce_product_get_price', 'custom_product_price', 100, 2 );
add_filter( 'woocommerce_product_get_regular_price', 'custom_product_price', 100, 2 );
add_filter( 'woocommerce_product_variation_get_price', 'custom_product_price', 100, 2 );
add_filter( 'woocommerce_product_variation_get_regular_price', 'custom_product_price', 100, 2 );
function custom_product_price( $price, $product ) {
$category_terms = array('laminat');

// Get the parent variable product for product variations
$product_id = $product->get_parent_id() ? $product->get_parent_id() : $product->get_id();

if( has_term( $category_terms, 'product_cat', $product_id ) ) {
$price *= 1.67; // новая цена
}
return $price;
}

// Variable products (price range)
add_filter('woocommerce_variation_prices_price', 'custom_variable_price_range', 100, 3 );
add_filter('woocommerce_variation_prices_regular_price', 'custom_variable_price_range', 100, 3 );
function custom_variable_price_range( $price, $variation, $product ) {
$category_terms = array('laminat');

if( has_term( $category_terms, 'product_cat', $product->get_id() ) ) {
$price *= 1.67; // новая цена
}
return $price;
}

// Handling price caching, for better performances
add_filter( 'woocommerce_get_variation_prices_hash', 'custom_variable_product_prices_hash', 100, 3 );
function custom_variable_product_prices_hash( $price_hash, $product, $for_display ) {
$category_terms = array('laminat');

if( has_term( $category_terms, 'product_cat', $product->get_id() ) ) {
$price_hash[] = '1.67';
}
return $price_hash;
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

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

Change product variation prices via a hook in WooCommerce 3.3

The linked code still work for Woocommerce 3.3.x, see this related recent accepted working answer tested on Woocommerce 3.3.x … Your code is just uncompleted…

You need to use:

// Variable
add_filter('woocommerce_product_variation_get_regular_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'custom_price' , 99, 2 );

// Variations (of a variable product)
add_filter('woocommerce_variation_prices_price', 'custom_variation_price', 99, 3 );
add_filter('woocommerce_variation_prices_regular_price', 'custom_variation_price', 99, 3 );

function custom_price( $price, $product ) {
// Delete product cached price (if needed)
wc_delete_product_transients($product->get_id());

return $price * 3; // X3 for testing
}

function custom_variation_price( $price, $variation, $product ) {
// Delete product cached price (if needed)
wc_delete_product_transients($variation->get_id());

return $price * 3; // X3 for testing
}

Update product price using a hook in WooCommerce

Updated (August 2018)

Your code is correct but the hook is made for Metaboxes custom fields.

You should use instead save_post_{$post->post_type} Wordpress hook targeting product post type only.

Also You may need to update the active price and to refresh the product transient cache with the function wc_delete_product_transients().

So your code will be:

add_action( 'save_post', 'update_the_product_price', 10, 3 );
function update_the_product_price( $post_id, $post, $update ) {

if ( $post->post_type != 'product') return; // Only products

// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;

// Check the user's permissions.
if ( ! current_user_can( 'edit_product', $post_id ) )
return $post_id;

$price = 50; // <=== <=== <=== <=== <=== <=== Set your price

$product = wc_get_product( $post_id ); // The WC_Product object

// if product is not on sale
if( ! $product->is_on_sale() ){
update_post_meta( $post_id, '_price', $price ); // Update active price
}
update_post_meta( $post_id, '_regular_price', $price ); // Update regular price
wc_delete_product_transients( $post_id ); // Update product cache
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works…

Change all product prices from a specific product tag in Woocommerce 3

I have revisited your code… I have merged the pricing updates in a separated utility function…

To avoid your problems is necessary to define the product ID (checking the product type before).

Then we set this correct defined product ID in WordPress has_term() conditional function.

Now your prices will work on cart and checkout pages too…

Your revisited code:

// Utility pricing function
function filtering_product_prices( $price, $product ) {
// Get the product ID
$product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();

// Only for Woocomerce Product Tag "ama"
if ( ! has_term( 'ama', 'product_tag', $product_id ) ) return $price; // Exit

if ( $price < 5 ) {
$price *= 2.5;
} elseif ( $price >= 5 && $price < 10 ) {
$price *= 2;
} elseif ( $price >= 10 && $price < 20 ) {
$price *= 1.75;
} elseif ( $price >= 20 && $price < 40 ) {
$price *= 1.5;
} elseif ( $price >= 40 && $price < 60 ) {
$price *= 1.35;
} elseif ( $price >= 60 && $price < 80 ) {
$price *= 1.25;
} elseif ( $price >= 80 && $price < 1000 ) {
$price *= 1.20;
}
return ceil($price + 0.01) - 0.01;
}

// Simple, grouped and external products
add_filter('woocommerce_product_get_price', 'custom_price', 90, 2 );
add_filter('woocommerce_product_get_regular_price', 'custom_price', 90, 2 );

// Product variations (of a variable product)
add_filter('woocommerce_product_variation_get_regular_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'custom_price', 90, 2 );

function custom_variation_price( $price, $variation, $product ) {
return filtering_product_prices( $price, $product );
}

// Variable product price range
add_filter('woocommerce_variation_prices_price', 'custom_variation_price', 90, 3 );
add_filter('woocommerce_variation_prices_regular_price', 'custom_variation_price', 90, 3 );

function custom_price( $price, $product ) {
return filtering_product_prices( $price, $product );
}

Code goes in function.php file of your active child theme (or active theme). Tested and work.

Related answer: Conditional product prices cart issue in WooCommerce 3

Change cart item prices in Woocommerce 3

Update 2021 (Handling mini cart custom item price)

With WooCommerce version 3.0+ you need:

  • To use woocommerce_before_calculate_totals hook instead.
  • To use WC_Cart get_cart() method instead
  • To use WC_product set_price() method instead

Here is the code:

// Set custom cart item price
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 1000, 1);
function add_custom_price( $cart ) {
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

// Avoiding hook repetition (when using price calculations for example | optional)
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;

// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
$cart_item['data']->set_price( 40 );
}
}

And for mini cart (update):

// Mini cart: Display custom price 
add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 3 );
function filter_cart_item_price( $price_html, $cart_item, $cart_item_key ) {

if( isset( $cart_item['custom_price'] ) ) {
$args = array( 'price' => 40 );

if ( WC()->cart->display_prices_including_tax() ) {
$product_price = wc_get_price_including_tax( $cart_item['data'], $args );
} else {
$product_price = wc_get_price_excluding_tax( $cart_item['data'], $args );
}
return wc_price( $product_price );
}
return $price_html;
}

Code goes in functions.php file of your active child theme (or active theme).

This code is tested and works (still works on WooCommerce 5.1.x).

Note: you can increase the hook priority from 20 to 1000 (or even 2000) when using some few specific plugins or others customizations.

Related:

  • Set cart item price from a hidden input field custom price in Woocommerce 3
  • Change cart item prices based on custom cart item data in Woocommerce
  • Set a specific product price conditionally on Woocommerce single product page & cart
  • Add a select field that will change price in Woocommerce simple products

Need to change price against individual quantity of the product in woocommerce

You need to research a little more. I ran what your asking thru Google here are the first three results. Anyone of these three links can get you started.

Change cart item prices in Woocommerce 3

https://rudrastyh.com/woocommerce/change-product-prices-in-cart.html

https://www.webroomtech.com/change-product-price-when-other-product-is-in-cart-woocommerce/



Related Topics



Leave a reply



Submit