Justin Waulters
Justin Waulters

Reputation: 303

Update product price using a hook in WooCommerce

I am trying to update the product regular price using the meta key _regular_price with an integer or string when the product is updated in the wp-admin.

My desired user-flow is:

  1. Open the product edit page
  2. Click the update button
  3. See that the _regular_price is set to 20 after the page has reloaded.

add_action( 'woocommerce_process_product_meta', 'update_test' );
function update_test( $post_id ) {
    update_post_meta( $post_id, '_regular_price', 20 );
}

Please help me find what I'm doing wrong in the above function and let me know of any other ways to accomplish this.

Upvotes: 2

Views: 9040

Answers (2)

LoicTheAztec
LoicTheAztec

Reputation: 253911

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…


Addition (2024 update)

You can use woocommerce_admin_process_product_object action hook since WooCommerce 3 as following (which simplify the code):

add_action( 'woocommerce_admin_process_product_object', 'update_the_product_price', 100 );
function update_the_product_price( $product ) {
    $price = 50; // <=== Set your price

    if( ! $product->is_on_sale() ){
        $product->set_price($price); // Update active price
    }
    $product->set_regular_price($price); // Update active price

    // No need to delete product transients, as cache is auto refreshed here.
}

Upvotes: 4

mukesh
mukesh

Reputation: 26

To process woocommerce_process_product_meta, I guess you are missing the parameters. I hope the below code may suit your need.

add_action( 'woocommerce_process_product_meta',  $wc_meta_box_product_data_save,  $int,  $int ); 

Parameters (3)

  • $wc_meta_box_product_data_save (string) => 'WC_Meta_Box_Product_Data::save' The wc meta box product data save.
  • $int (int) => 10 The int.
  • $int (int) => 2 The int.

You can find the details in this link.

Upvotes: 0

Related Questions