17

I did not want to post here but I could not find the answer I was looking for and I do not have enough reputation to comment on other VERY SIMILAR questions to get my exact answer.

I found an almost perfect answer from this post: WooCommerce: Add product to cart with price override?

using the code:

add_action( 'woocommerce_before_calculate_totals', 'add_custom_price');

function add_custom_price( $cart_object ) {
      $custom_price = 10; // This will be your custome price  
      foreach ( $cart_object->cart_contents as $key => $value ) {
          $value['data']->price = $custom_price;
      }
 }

and it works great...if you set a hard coded custom price.

My question is: How can I set a custom price based on user input?

I have tried every way I can think of to pass information (I even tried using cookies, globals, sessions) and none of them worked how I wanted and all of them were, at BEST, hacks.

The specific product in question is a donation and the customer wants the user to be able to set the donation price (rather than just creating a variable product with set price points).

On the donation page when the user submits the donation form I am adding the donation product to the cart like so:

$donation_success = $woocommerce->cart->add_to_cart($donation_id); 

My donation product has a set price of 0.00 so when it is added to the cart it has a price of 0.00 (I don't know if the price is set at this point or later)

I have tried passing in information at this point using the last variable in the add_to_cart method which accepts an array of arguments but I couldn't seem to get that to work either.

I am sure the answer is simple but I have been trying for hours to do this right and I cannot get it to work. I am out of ideas.

The actual code I am using at the moment is slightly different than was suggested by the answerer of the above post but works basically the same:

add_action( 'woocommerce_before_calculate_totals', 'woo_add_donation');

function woo_add_donation() {
    global $woocommerce;

    $donation = 10;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        if($cart_item['data']->id == 358 || $cart_item['data']->id == 360){
            $cart_item['data']->set_price($donation);
        }
    }
}

Thanks in advance for any helpful advice!

Community
  • 1
  • 1
Bullyen
  • 808
  • 1
  • 8
  • 20
  • I'm new to woocommerce but facing the same issue. Which files do I have to modify to make this work? – werwuifi Mar 12 '19 at 16:39
  • @werwuifi this code would go into the functions.php file in the current WordPress theme. Anytime you see an "add_action" or "add_filter" you can assume this will be in the functions.php file. That said, while this code should still work there might be better answers out there now. – Bullyen Mar 12 '19 at 19:49

3 Answers3

12

I found a solution which is not elegant but works for my purposes.

I was trying to use cookies before but I didn't set the cookie path so it was only available to the page it was set on.

I am now setting a cookie with the donation price:

setcookie("donation", $_GET['donation'], 0, "/");

Then I am setting the price like so:

add_action( 'woocommerce_before_calculate_totals', 'woo_add_donation');

function woo_add_donation() {
    global $woocommerce;

    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        if($cart_item['data']->id == 358 && ! empty($_COOKIE['donation'])){
            $cart_item['data']->set_price($_COOKIE['donation']);
        }
    }
}
Bullyen
  • 808
  • 1
  • 8
  • 20
  • 1
    Just the thing I was looking for! I've spent countless hours trying to alter the functions to no avail. This worked perfect and changed the price:) Many thanks again! – shish Jul 11 '14 at 09:07
  • how can i ad this functionality when adding product to order via api request – yahya akhtar Jun 15 '16 at 07:38
3

I have been looking for exactly the same thing. I found this WooCommerce plugin (not free) for this

name your price plugin

Initially I wasn't sure what search terms to use to find plugins like this but it looks like "WooCommerce name your price" brings up links to other sources of similar plugins.

batman42ca
  • 31
  • 2
  • Thanks batman. We actually have this plugin and it does work fine for normal products. However I was not able to find a way to use this outside the normal shop area. If I am unable to figure out another way I may end up using this. – Bullyen Feb 13 '14 at 19:23
  • @James - I'm actually the author of the Name Your Price plugin. I'm curious what you mean by "outside the normal shop area"? Where do you want to use it? WooCommerce 2.1 should have resolved any issues with using Name Your Price in shortcodes, so you can place it almost anywhere you'd like. – helgatheviking Apr 11 '14 at 07:11
  • @helgatheviking - I needed to setup a donation page with a simple text field and an "Amount" label. I was not looking to include a slider or any other feature which I assume comes along with the short code. I was able to use your plugin (and we use it in multiple other sites) outside of the shop but it wasn't really what I was looking for in this instance. Perhaps it was and I just didn't know everything it could do. FYI: This was literally my first WordPress AND WooCommerce site so I was a little overwhelmed with new information and did quite a few things "incorrectly"/non-wordpressy – Bullyen Apr 15 '14 at 21:06
  • @James absolutely no sliders come with Name Your Price. :) Glad you are using it though! I don't think I ever tested the `[add_to_cart id="99"]` shortcode, but in theory that should've done what you needed. At worst, I know that `[product id="99"]` would get you a title, small description and an add to cart button w/ input field. There is definitely a lot of info to take in! – helgatheviking Apr 15 '14 at 22:49
  • This is a very old post now, but it still comes up in searches. the `[add_to_cart]` shortcode is insufficient for a name your price product because it only shows the add to cart button and not the input. So I wrote a plugin that adds an `[add_to_cart_form]` shortcode that works with the same parameters but displays the entire `
    ` element (while not the entire `[product]` shortcode) so you can show the price input and add to cart button anywhere.
    – helgatheviking Nov 09 '19 at 20:32
0

This code will create order with custom price:

$product = wc_get_product($product_id);
$order = wc_create_order();
try {
    $order->add_product($product);
    //$order->set_customer_id($user->ID);
    $order->set_billing_email($customer_email);
} catch (WC_Data_Exception $e) {
    wp_send_json_error("Failed to create order");
}

$order->calculate_totals();    

try {
    $order->set_total($custom_price); // $custom_price should be float value
} catch (WC_Data_Exception $e) {
    wp_send_json_error("Failed to change order details");
}

$order->save();

$order->update_status( 'completed' );
gil123
  • 512
  • 6
  • 12