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 usingwoocommerce_get_variation_prices_hash
filter hook much more efficient, instead ofwc_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
forproduct
post typewoocommerce_product_variation_get_price
forproduct_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
to1000
(or even2000
) 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
How to Remove Both .PHP and .Html Extensions from Url Using Nginx
How to Prevent Code Injection Attacks in PHP
PHP Class Instantiation. to Use or Not to Use the Parentheses
PHP Output Showing Little Black Diamonds With a Question Mark
PHP Threading Call to a PHP Function Asynchronously
Remove the Last Character from a String
Amazon S3 - How to Fix 'The Request Signature We Calculated Does Not Match the Signature' Error
Jquery Ui Sortable, Then Write Order into a Database
Date Difference in PHP on Days
How to Get Random Value Out of an Array
PHP Login System: Remember Me (Persistent Cookie)
Posting Raw Image Data as Multipart/Form-Data in Curl
Listing All the Folders Subfolders and Files in a Directory Using PHP
MySQLi Count(*) Always Returns 1
What Is Autoloading; How to Use Spl_Autoload, _Autoload and Spl_Autoload_Register