5

i have a one product 1€ and use e GET parameter to change the price at runtime:

http://url/warenkorb/?add-to-cart=1539&price=18.45

This change not the price in the basket (still remain 1€)

How to achieve this.

I use the following hook:

add_filter( 'woocommerce_add_cart_item', 'my_woocommerce_add_cart_item', 5, 1 );
function my_woocommerce_add_cart_item( $cart_item ) {

if(get_post_meta( $cart_item['data']->id, 'isConfigurableProduct', true)=='1')
{   
    if(isset($_GET['price']))
    {
        $price=$_GET['price'];//keep it simpel for testing
        $cart_item['data']->set_price( $price );
        $_SESSION[$cart_item['data']->id]=$price;
    }
    else
    {
        $cart_item['data']->set_price($_SESSION[$cart_item['data']->id]);   
    }
}
return $cart_item;
}

Thanks

bonanza
  • 51
  • 1
  • 1
  • 2

4 Answers4

9

With WooCommerce 2.5 I found this to be a 2-part process. The first step is to change the run-time display of pricing when added to the cart via the woocommerce_add_cart_item filter. The second part is to set the persistent session data which is read during checkoutvia the woocommerce_get_cart_item_from_session filter.

add_filter( 'woocommerce_add_cart_item' , 'set_woo_prices');
add_filter( 'woocommerce_get_cart_item_from_session',  'set_session_prices', 20 , 3 );

function set_woo_prices( $woo_data ) {
  if ( ! isset( $_GET['price'] ) || empty ( $_GET['price'] ) ) { return $woo_data; }
  $woo_data['data']->set_price( $_GET['price'] );
  $woo_data['my_price'] = $_GET['price'];
  return $woo_data;
}

function  set_session_prices ( $woo_data , $values , $key ) {
    if ( ! isset( $woo_data['my_price'] ) || empty ( $woo_data['my_price'] ) ) { return $woo_data; }
    $woo_data['data']->set_price( $woo_data['my_price'] );
    return $woo_data;
}

Setting my_price as part of the woo_data in woocommerce_add_cart_item allows that data to be retrieved later via the session price filter. A more secure method is to not pass price in the URL and set it directly as to avoid URL price manipulation.

In my real-world implementation connecting Store Locator Plus to WooCommerce, I store per-location pricing data for each WooCommerce product in an internal table and only set/retrieve the location ID in place of 'my_price' in this example. Internal methods are used to fetch the set price from the data table in both methods above, using the location ID as a lookup and only leaving the public URL with a location ID which is not going to allow them to modify pricing.

Lance Cleveland
  • 3,098
  • 1
  • 33
  • 36
  • +1. I was setting price just to 'woocommerce_add_cart_item' hook and it was not working. When i set price on 'woocommerce_get_cart_item_from_session' hook as well then it worked and showed updated price on cart page. – Sajal Feb 26 '16 at 21:25
  • Hi , Please update your answer. Your second line is `add_filter( 'woocommerce_get_cart_item_from_session', 'set_session_prices' ) , 20 , 3 );` should be changed to this: `add_filter( 'woocommerce_get_cart_item_from_session', 'set_session_prices' , 20 , 3 );` The if statement is missing the closing parenthesis just before the curly brace. – MD. Atiqur Rahman Apr 11 '16 at 13:04
  • Thank you too mate :) It helped me a lot ! – MD. Atiqur Rahman Apr 11 '16 at 13:29
  • This answer should be accepted, thanks alot @LanceCleveland – Habib Rehman Feb 17 '17 at 07:29
  • many thanks. When I set the price this way the cart-widget in navbar shows double the price (although the price in checkout/cart pages are correct). Could someone suggest what might the problem be? – saiedmomen Mar 13 '17 at 20:19
2

First of all I want to warn you that if you use price in the url of your add_to_cart link that might make your store vulnerable. If you use this in product meta that would be more secured. Anyway I'm showing you the code to achieve how to set price from the url.

add_filter( 'woocommerce_add_cart_item', 'c_other_options_add_cart_item', 20, 1 );
function c_other_options_add_cart_item( $cart_item ) {

    if (isset($cart_item['_other_options'])) :
        if( isset($cart_item['_other_options']['product-price']) )
            $extra_cost = floatval($cart_item['_other_options']['product-price']);

        $cart_item['data']->adjust_price( $extra_cost );
        // here the real adjustment is going on...

    endif;

    return $cart_item;

}

add_filter( 'woocommerce_add_cart_item_data', 'c_other_options_add_cart_item_data', 10, 2 );
function c_other_options_add_cart_item_data($cart_item_meta, $product_id){
    global $woocommerce;

    $product = new WC_Product( $product_id);
    $price = $product->price;

    if(empty($cart_item_meta['_other_options']))
        $cart_item_meta['_other_options'] = array();

    $cart_item_meta['_other_options']['product-price'] = esc_attr($_REQUEST['price']) - $price;

// as woocommerce allows to adjust the price (i don't know if there is any way to reset it, but this procedure works), we need to return the adjustable price 

    return $cart_item_meta;
}
maksbd19
  • 3,785
  • 28
  • 37
  • Hi thanks for comment. That won't work, the cart show the old price 1€ – bonanza Jul 15 '14 at 04:29
  • okay but that one worked for me. you should try debugging if the price is being passed to $cart_item_meta['_other_options']['product-price']. if the price is not passed here or it is not set then the adjustment won't work. This is a very simple and generic solution. – maksbd19 Jul 16 '14 at 18:56
  • Cart is empty: `code` c_other_options_add_cart_item_data: array(1) {["product-price"]=> string(5) "17.45" } c_other_options_add_cart_item: array(1) { ["product-price"]=> string(5) "17.45" } `code` – bonanza Jul 17 '14 at 06:54
  • which version of woocommerce are you using? this code is working fine in 2.1.9 – maksbd19 Jul 17 '14 at 18:29
  • version 2.1.12. With your code, the cart remain empty no matter which product i put it in the cart. – bonanza Jul 18 '14 at 04:41
  • is this possible to view your project in any way? i don't understand, it should be working. – maksbd19 Jul 18 '14 at 18:46
  • adjust_price is deprecated. Use set_price – Eslam Sameh Ahmed Jul 01 '23 at 02:40
1

After release of woocommerce version 3.0.0 product price is update on add to cart using set_price($price) function. The example is given as below :

add_action( 'woocommerce_before_calculate_totals', 'mj_custom_price' );

function mj_custom_price( $cart_object ) {
   $woo_ver = WC()->version; 
   $custom_price = 10;
   foreach ( $cart->cart_contents as $key => $value )
   {
       if($woo_ver < "3.0.0" && $woo_ver < "2.7.0")
       {
           $value['data']->price = $custom_price;
       }
       else
       {
           $value['data']->set_price($custom_price);
       }
   }            
}

Many Thanks

Mohd Jafar
  • 291
  • 3
  • 9
0

Its not working for me, i modified to modify price passed by a parameter

spainbox.com/carro/?add-to-cart=28792&shippingprice=141

Product have a price of 1 euro, and i need to add to cart this product because its a service that will have the price of the shipping cost

<?
add_filter( 'woocommerce_add_cart_item', 'c_other_options_add_cart_item', 20, 1 );
function c_other_options_add_cart_item( $cart_item ) {

    if (isset($cart_item['_other_options'])) :
        if( isset($cart_item['_other_options']['product-price']) )
            $extra_cost = floatval($cart_item['_other_options']['product-price']);

        $cart_item['data']->adjust_price( $extra_cost );
        // here the real adjustment is going on...

    endif;

    return $cart_item;

}

add_filter( 'woocommerce_add_cart_item_data', 'c_other_options_add_cart_item_data', 10, 2 );
function c_other_options_add_cart_item_data($cart_item_meta, $product_id){
    global $woocommerce;

    $product = new WC_Product( $product_id);
    $price = $product->price;

    if(empty($cart_item_meta['_other_options']))
        $cart_item_meta['_other_options'] = array();

    $cart_item_meta['_other_options']['product-price'] = esc_attr($_REQUEST['shippingprice']);

// as woocommerce allows to adjust the price (i don't know if there is any way to reset it, but this procedure works), we need to return the adjustable price

    return $cart_item_meta;
}
?>