Skip to content
Advertisement

Calculate and update product price in cart – WooCommerce

I’m creating a WooCommerce (Version 5.6.0) site where users can buy foam products and the prices are calculated on the archive page. Basically, the users enter the dimensions and the price is calculated based on a formula. I’m currently struggling with updating the prices in cart, I don’t have previous experience in customizing the products and prices at this level, and so any help will be much appreciated.. Steps I’ve done so far:

1.Get (via Ajax) and set the custom product price in WC_Session

function get_custom_product_price_set_to_session(){
// Check that there is a 'foamPrice' and foamProductI _POST variable
if (isset($_POST['foamProductId']) && isset($_POST['foamPrice'])) {
    // Enable customer WC_Session (needed on first add to cart)
    if (!WC()->session->has_session()) {
        WC()->session->set_customer_session_cookie(true);
    }
    // Set the product_id and the custom price in WC_Session variable
    WC()->session->set('foam_price', [
        'id' => (int)wc_clean($_POST['foamProductId']),
        'price' => (float)wc_clean($_POST['foamPrice']),
    ]);
}}
add_action('wp_ajax_get_custom_product_price_set_to_session', 'get_custom_product_price_set_to_session');
add_action('wp_ajax_nopriv_get_custom_product_price_set_to_session', 'get_custom_product_price_set_to_session');

2.Change cart item price from WC_Session data:

add_action('woocommerce_before_calculate_totals', 'custom_cart_item_price', 20, 1);

function custom_cart_item_price($cart){
    if (is_admin() && !defined('DOING_AJAX'))
        return;

// Must be required since Woocommerce version 3.2 for cart items properties changes
if (did_action('woocommerce_before_calculate_totals') >= 2)
    return;

// Loop through our specific cart item keys
foreach ($cart->get_cart() as $cart_item) {
    // Get custom product price for the current item
    if (($data = WC()->session->get('foam_price')) && $cart_item['data']->get_id() == $data['id']) {
        // Set the new product price
        $cart_item['data']->set_price($data['price']);
    }
}}

The issue I’m running into, is that it’s working for the latest product added to cart only, the previous products added to cart are being re-set the 0 price every time I add a new product to cart. If anyone is able to provide some guidance, I will highly appreciate it. Thanks a mill!

Advertisement

Answer

With

    WC()->session->set('foam_price', [
        'id' => (int)wc_clean($_POST['foamProductId']),
        'price' => (float)wc_clean($_POST['foamPrice']),
    ]);

you’re basically overriding the previous “foam_price” with the latest added to cart.

You need to store, in my opinion, different values for different product IDs.

Try with (untested):

function get_custom_product_price_set_to_session(){
// Check that there is a 'foamPrice' and foamProductI _POST variable
if (isset($_POST['foamProductId']) && isset($_POST['foamPrice'])) {
    // Enable customer WC_Session (needed on first add to cart)
    if (!WC()->session->has_session()) {
        WC()->session->set_customer_session_cookie(true);
    }
    // Set the product_id and the custom price in WC_Session variable
    WC()->session->set('foam_price' . wc_clean($_POST['foamProductId']), [
        'id' => (int)wc_clean($_POST['foamProductId']),
        'price' => (float)wc_clean($_POST['foamPrice']),
    ]);
}}
add_action('wp_ajax_get_custom_product_price_set_to_session', 'get_custom_product_price_set_to_session');
add_action('wp_ajax_nopriv_get_custom_product_price_set_to_session', 'get_custom_product_price_set_to_session');

…and then:

add_action('woocommerce_before_calculate_totals', 'custom_cart_item_price', 20, 1);

function custom_cart_item_price($cart){
    if (is_admin() && !defined('DOING_AJAX'))
        return;

// Must be required since Woocommerce version 3.2 for cart items properties changes
if (did_action('woocommerce_before_calculate_totals') >= 2)
    return;

// Loop through our specific cart item keys
foreach ($cart->get_cart() as $cart_item) {
    // Get custom product price for the current item
    if (($data = WC()->session->get('foam_price' . $cart_item['data']->get_id())) && $cart_item['data']->get_id() == $data['id']) {
        // Set the new product price
        $cart_item['data']->set_price($data['price']);
    }
}}
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement