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']); } }}