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
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.
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;
}
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
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;
}
?>