There are many reasons you might want to update a WooCommerce product price programmatically. For instance, in Bookings for WooCommerce the booking (product) price is set dynamically according to certain parameters – e.g. length of stay, etc. In Product Extras, you can specify extra fields for your products (like checkboxes and text fields) which will add extra cost to the product when selected. In this article, I’ll share some simple code to achieve this.

How to update WooCommerce product prices programmatically

Let’s say, as an example, that you are selling computers on your WooCommerce store and you want to add an option to each product that, when selected, will update the product price in the cart.

If we take a look at an example product from the Product Extras demo (screenshot below), we can see that if the user chooses the ‘Add extended warranty’ checkbox, another £250 will be added to the product price.

WooCommerce update product price programmatically

The product price is updated programmatically in the cart by using two WooCommerce hooks:



The woocommerce_add_cart_item_data filter

The woocommerce_add_cart_item_data filter allows us to add custom data to products when they’re added to the cart. When the user clicks the ‘Add to cart’ button, we use the filter to set a new variable in the product’s item data that defines the updated price. Like this:

function add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
// Has our option been selected?
if( ! empty( $_POST['extended_warranty'] ) ) {
$product = wc_get_product( $product_id );
$price = $product->get_price();
// Store the overall price for the product, including the cost of the warranty
$cart_item_data['warranty_price'] = $price + 250;
return $cart_item_data;
add_filter( 'woocommerce_add_cart_item_data', 'add_cart_item_data', 10, 3 );

When the user adds the product to their cart, this code checks to see if a checkbox with the extended_warranty name attribute has been set.

If the checkbox has been set then we used the $product_id variable passed by the filter to get the $product object, then use the get_price method to get the product price:

$product = wc_get_product( $product_id );
$price = $product->get_price();

Then we store our updated price in a new element in the $cart_item_data object.

$cart_item_data['warranty_price'] = $price + 250;

Note that I’ve hardcoded a value here. You will undoubtedly want to use your own value.

The woocommerce_before_calculate_totals action

Now that we have our updated price stored as a variable in the cart item data, we can use it when the user arrives on the cart page. We do that like this:

function before_calculate_totals( $cart_obj ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
// Iterate through each cart item
foreach( $cart_obj->get_cart() as $key=>$value ) {
if( isset( $value['warranty_price'] ) ) {
$price = $value['warranty_price'];
$value['data']->set_price( ( $price ) );
add_action( 'woocommerce_before_calculate_totals', 'before_calculate_totals', 10, 1 );

As you can guess from the name of the action, woocommerce_before_calculate_totals runs just before the cart total is calculated. We pass it the cart object, then iterate through each item in the cart to check for our extended_warranty variable. If we find it, we update the price for the product using the set_price method.

Why not set the price variable at the cart page?

If you try to calculate the updated price directly in the cart using woocommerce_before_calculate_totals, you might find that the extra price is added twice or even multiple times. That’s because woocommerce_before_calculate_totals can be called more than once on the cart page.

Further resources



Photo by Samuel Zeller on Unsplash. It has no relevance to the content of the article.

Extra fields, options and addons for WooCommerce products

Do you develop plugins?

You should try Wisdom, a plugin designed specifically for plugin developers that allows you to track your plugin's usage and provides invaluable data on how your plugin is being used. Find out more.

Leave a Reply

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