How to Pass Custom Options like Custom Price to WooCommerce Cart

I am trying to pass a custom price / custom attributes to the woocommerce cart from an ordinary WordPress page using PHP and Ajax, but I can’t get the job done dynamically.

I’m working with an AJAX app embedded on our dev site that essentially calculates a total based on configured product variations. I am trying to grab the total from there and submit a product to the Woocommerce cart (default price 0.00) and override the price there.

I’ve been working from some PHP provided here with a very similar circumstance, but I think I’m missing something: Adding a product to cart with custom info and price

I can set a static price using the ‘woocommerce_before_calculate_totals’ hook but, using the code outlined in the link above, I can’t seem to ‘pass’ a custom price to the cart using an AJAX button. The POST data never reaches the PHP function. The way I’m attempting it right now is by using a button with some AJAX code to make the post, but I keep hitting walls. I think I’ve got the wrong idea about something here. I’m using a static price in the ajax below.

jQuery(function(){
jQuery('#newQuoteBtn').on('click', function(e){
    e.preventDefault();

    jQuery.ajax({
        url: '/wp-content/plugins/override_price.php',
        type: 'post',
        data: { 'custom_options': {'action': 'newquote', 'newprice': '555.55', 'quotenum': '1234567890'}},
        success: function(data, status) {
            /* Product added and redirect to cart */
            console.log('success');
        },
        error: function(xhr, desc, err) {
            console.log(xhr);
            console.log("Details: " + desc + "nError:" + err);
        }
    }); // end ajax call
});
});

I expected the data to pass to the PHP which takes care of overriding the price from there, but I can’t get the variables to the PHP. The authors’ comments stated to put that code in the functions.php file, but how do I post data there? There’s a disconnect somewhere here and I need help illuminating the correct way to approach this problem.

Answer

More or less figured this part out. I had to use a form post to add the product to the cart and this would allow my functions to pick up the variables input in the form (including price) and override them in the cart. More or less, my setup looks like this:

HTML Form

<form method="POST" enctype="multipart/form-data" id="outer-quote-form">
    <label class="quote_number">Quote Number: 
        <input type="text" id="quote_number" name="quote_number" value="">
    </label>
    <label class="custom_price">price:
        <input type="text" id="custom_price" name="custom_price" value="">
    </label>
    <button type="submit" class="btn btn-primary" name="ws-add-to-cart">Add to Cart</button>
</form>

Then I have a few PHP functions. This one listens for the form post and adds a product to the cart.

if (isset($_REQUEST['ws-add-to-cart'])) {
    add_action( 'init', 'add_product_to_cart' );
    function add_product_to_cart() {
        global $woocommerce;
        global $product;
        $product_id = 138;
        $woocommerce->cart->add_to_cart($product_id);
    }
    header("Location:https://www.devsite.com/checkout/");
}

This function hooks to ‘woocommerce_add_cart_item_data’ to get the custom price and add that value to the product data.

add_filter( 'woocommerce_add_cart_item_data', 'add_cart_item_data', 10, 3 );
function add_cart_item_data( $cart_item_data, $product_id ) {
    if( ! empty( $_POST['custom_price'] ) ) {
        $product = wc_get_product( $product_id );
        $price = $product->get_price();
        $newprice = $_POST['custom_price'];
        $cart_item_data['custom_price'] = $newprice;
    }
    return $cart_item_data;
}

Finally, we use ‘woocommerce_before_calculate_totals’ hook to actually override the price of the product in the cart.

add_action( 'woocommerce_before_calculate_totals', 'before_calculate_totals', 10, 1 );
function before_calculate_totals( $cart_object ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }
    foreach( $cart_object->get_cart() as $key=>$value ) {
        if( isset( $value['custom_price'] ) ) {
            $price = $value['custom_price'];
            $value['data']->set_price( ( $price ) );
        }
    }
}

It’s worth noting that this setup only works so far with one product in the cart, and that’s all I need for now.

Leave a Reply

Your email address will not be published. Required fields are marked *