skip to Main Content

I want to have third price available in WooCommerce:

  1. Regular price
  2. Discounted price
  3. Super Sale Price

So far I added it in the admin area and frontend to be visible, but whatever I try I can’t make it work with cart, because I need it to check from 3, to one, like: If there is option 3 (Super Sale PRice), make that price, if there is 2 (Discounted price) make that price, if there is 1 (Regular price only), make that price.
And all of this should not mess up with variable products and be only for simple products.

Here is my code:

/**
 * Function to render UI in Admin Product add/edit page
 */
function show_custom_price_admin() {

    global $thepostid;

    woocommerce_wp_text_input(
        array(
            'id'    => 'custom_price',
            'name'  => '_custom_price',
            'value' => get_post_meta( $thepostid, '_custom_price', true ),
            'class' => 'wc_input_price short',
            'label' => __( 'Custom Price ($)', 'vg' ),
        )
    );
}
add_action( 'woocommerce_product_options_pricing', 'show_custom_price_admin' );

/**
 * Function to update custom price Admin Product add/edit page
 *
 * @param int $post_id Product's post id.
 */
function process_product_custom_data( $post_id ) {

    $product = wc_get_product( $post_id );

    $product->update_meta_data(
        '_custom_price',
        wc_clean( wp_unslash( filter_input( INPUT_POST, '_custom_price' ) ) )
    );
    $product->save();
}
add_action( 'woocommerce_process_product_meta', 'process_product_custom_data' );

/**
 * Function to show custom price front end page
 */
function show_custom_price_frontend() {
    global $post;

    $custom_price = get_post_meta( $post->ID, '_custom_price', true );

    if ( $custom_price ) {
        $custom_price = wc_price( $custom_price );

        printf( '<p class="price">%s</p>', $custom_price );
    }
}
add_action( 'woocommerce_before_add_to_cart_form', 'show_custom_price_frontend' );

So far I added it in the admin area and frontend to be visible, but whatever I try I can’t make it work with cart, because I need it to check from 3, to one, like: If there is option 3 (Super Sale PRice), make that price, if there is 2 (Discounted price) make that price, if there is 1 (Regular price only), make that price.
And all of this should not mess up with variable products and be only for simple products.

2

Answers


  1. Your code is a bit outdated, and there are some missing things. To set and display a custom price (if it is defined in the backend, for simple products), try the following:

    /**
     * Display custom price input field in Admin Product add/edit page
    **/
     add_action( 'woocommerce_product_options_pricing', 'admin_product_custom_price_input_field' );
    function admin_product_custom_price_input_field() {
        global $post, $product_object;
    
        echo '<div class="pricing show_if_simple hidden">'; // Only on simple product
    
        woocommerce_wp_text_input(  array(
            'id'        => 'custom_price',
            'value'     => $product_object->get_meta( '_custom_price' ),
            'class'     => 'wc_input_price short',
            'label'     => __( 'Custom Price', 'vg' ) . ' (' . get_woocommerce_currency_symbol() . ')',
            'data_type' => 'price',
        ) );
    
        echo '</div>';
    }
    
    /**
     * Save/update custom price Admin Product add/edit page
     *
     * @param object $product  WC_Product instance object
    **/
    function saves_product_custom_metadata( $product ) {
        $price_value = isset( $_POST['custom_price'] ) ? wc_clean( wp_unslash( $_POST['custom_price'] ) ) : null;
        $product->update_meta_data('_custom_price', $price_value );
    }
    add_action( 'woocommerce_admin_process_product_object', 'saves_product_custom_metadata' );
    
    /**
     * Display formatted custom price on front end 
     * 
     * @param string $price_html  Formatted custom price html
     * @param object $product  WC_Product instance object
    **/
    function custom_get_price_html( $price_html, $product ) {
        if ( ! $product->is_type('simple') ) {
            return $price_html;
        }
        if ( $custom_price = $product->get_meta( '_custom_price' ) ) {
            return wc_price( wc_get_price_to_display( $product, array( 'price' => $custom_price ) ) ) 
                . $product->get_price_suffix();
        }
        return $price_html;
    }
    add_filter( 'woocommerce_get_price_html', 'custom_get_price_html', 100, 2 );
    
    /**
     * Set custom cart item price
     *
     * @param object $cart  WC_Cart instance object
    **/ 
    function add_( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        // Loop through cart items
        foreach ( $cart->get_cart() as $item ) {
            $product = $item['data'];
            if ( $custom_price = $product->get_meta( '_custom_price' ) ) {
                $product->set_price( $custom_price );
            }
        }
    }
    add_action( 'woocommerce_before_calculate_totals', 'cart_set_custom_price', 1000 );
    
    /**
     * Display custom cart item price
     * 
     * @param object $cart  WC_Cart instance object
     * @param array $cart_item  cart item data
    **/
    function filter_cart_item_price( $price, $cart_item ) {
    
        if ( $custom_price = $cart_item['data']->get_meta( '_custom_price' ) ) {
            $args = array( 'price' => $custom_price );
    
            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;
    }
    add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 100, 2 );
    

    Code goes in functions.php file of your child theme (or in a plugin). Now it will work.

    Login or Signup to reply.
  2. There are some issues with your hooks. I tested this code it’s working. Put it in child-theme’s functions.php file.

    // Function to render UI in Admin Product add/edit page
    function show_custom_price_admin() {
        global $post_id;
    
        woocommerce_wp_text_input(
            array(
                'id'    => 'price_1',
                'name'  => '_price_1',
                'value' => get_post_meta( $post_id, '_price_1', true ),
                'class' => 'wc_input_price short',
                'label' => __( 'Discounted Price ($)', 'vg' ),
            )
        );
    
        woocommerce_wp_text_input(
            array(
                'id'    => 'price_2',
                'name'  => '_price_2',
                'value' => get_post_meta( $post_id, '_price_2', true ),
                'class' => 'wc_input_price short',
                'label' => __( 'Super Sale Price ($)', 'vg' ),
            )
        );
    }
    add_action( 'woocommerce_product_options_pricing', 'show_custom_price_admin' );
    
    // Function to update custom price Admin Product add/edit page
    function process_product_custom_data( $post_id ) {
        $product = wc_get_product( $post_id );
    
        if ( isset( $_POST['_price_1'] ) ) {
            $product->update_meta_data( '_price_1', wc_clean( $_POST['_price_1'] ) );
        }
    
        if ( isset( $_POST['_price_2'] ) ) {
            $product->update_meta_data( '_price_2', wc_clean( $_POST['_price_2'] ) );
        }
    
        $product->save();
    }
    add_action( 'woocommerce_process_product_meta', 'process_product_custom_data' );
    
    
    
    // Function to show the correct price on the frontend
    function show_custom_price_frontend() {
        global $product;
    
        if ( $product->is_type( 'simple' ) ) {
            $price_2   = get_post_meta( $product->get_id(), '_price_2', true );
            $price_1   = get_post_meta( $product->get_id(), '_price_1', true );
            $regular_price      = $product->get_regular_price();
    
            $display_price = $price_2 ?: ( $price_1 ?: $regular_price );
    
            if ( $display_price ) {
                echo sprintf( '<p class="price">%s</p>', wc_price( $display_price ) );
            }
        }
    }
    add_action( 'woocommerce_single_product_summary', 'show_custom_price_frontend', 10 );
    
    
    
    // Override cart item price for simple products
    function override_cart_price( $cart_object ) {
        foreach ( $cart_object->get_cart() as $cart_item ) {
            $product = $cart_item['data'];
    
            if ( $product->is_type( 'simple' ) ) {
                $price_2   = get_post_meta( $product->get_id(), '_price_2', true );
                $price_1   = get_post_meta( $product->get_id(), '_price_1', true );
    
                $price = $price_2 ?: ( $price_1 ?: $product->get_regular_price() );
    
                if ( $price ) {
                    $cart_item['data']->set_price( $price );
                }
            }
        }
    }
    add_action( 'woocommerce_before_calculate_totals', 'override_cart_price', 10, 1 );
    

    @LoicTheAztec answer is right you can also try his code if this code does not works.
    Happy Coding!!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search