4
votes

I've seen many examples of adding an item to the WC cart with a customer price, but none dynamically. I am trying to do in a shortcode function that receives a POST variables....

if (isset($_POST['wmnf_add_donation'])) {
    global $woocommerce;
    $cart_object = $woocommerce->cart;
    $custom_price = ($_POST['donation_amount'] > 0 ? $_POST['donation_amount'] : 0);
    $target_product_id = 65986;
    $cart_object->add_to_cart($target_product_id, "1");
    foreach ( $cart_object->cart_contents as $key => $value ) {
        if ( $value['product_id'] == $target_product_id ) {
            $value['data']->price = $custom_price;
        }
    }
}

This adds the item to the cart of course, but the price is zero and I realize I need to somehow save this array back to the WC cart data. Is this method even possible or can it only be done via a filter or action hook? If so, how can I save the changed array back to the cart contents or make it work to add the one item with its posted price? Any guidance greatly appreciated.


Thanks for that answer doublesharp, I was not able to get it to work as described because the form was posting to the page with my shortcode, which has my form, instead of posting directly to the cart. The $_POST was not being seen and the product ended up zero. I did find another approach, but having a problem using wp_redirect. I changed the above shortcode to this:

if (isset($_POST['wmnf_add_donation'])) {
    global $woocommerce;
    $custom_price = ($_POST['donation_amount'] > 0 ? $_POST['donation_amount'] : 0);
    $target_product_id = 65986;
    $_SESSION['donation_amount'] = $custom_price;
    $woocommerce->cart->add_to_cart($target_product_id, "1");
    wp_redirect( site_url() . '/gifts/swag-bag/');
}

Then I added the following filters to functions.php:

add_filter('woocommerce_get_price','donation_price', 10, 2);
add_filter('woocommerce_get_regular_price','donation_price', 10, 2);
add_filter('woocommerce_get_sale_price','donation_price', 10, 2);
function donation_price($price, $productd){
     if($productd->id == '65986'){
        $price = $_SESSION['donation_amount'];
     }
     return $price;
}

This does not work except when wp_redirect is commented out, hence, not redirecting. The above redirects to the cart, but its empty. If I comment out the wp_redirect line and then manually go to the cart, the product is there with my custom price. Actually, I would like to apply a custom price and redirect directly to the checkout page instead of the cart, if possible?

1

1 Answers

3
votes

You can use the woocommerce_before_calculate_totals action hook to modify the contents of the cart, including the product prices.

add_action( 'woocommerce_before_calculate_totals', 'before_calculate_totals' );
function before_calculate_totals( $_cart ){
    // loop through the cart_contents
    foreach ( $_cart->cart_contents as $cart_item_key => &$item ) {
        // you will need to determine the product id you want to modify, only when the "donation_amount" is passed
        if ( $item['id'] == 65986 && isset( $_POST['donation_amount'] ) ){
            // custom price from POST
            $custom_price = $_POST['donation_amount'] > 0 ? $_POST['donation_amount'] : 0;

            // save to the cart data
            $item['data']->price = $custom_price;
            // new versions of WooCommerce may require (instead of line above)...
            // $item['data']->set_price($custom_price);
        }
    }
}