$replace_order = new WC_Cart();
$replace_order->empty_cart( true );
$replace_order->add_to_cart( "256", "1");
The above code add product 256 to the Cart 1 time. But the issue I'm having is that I want to be able to completely override the product price... as far as I can tell, the only thing I can do it apply a coupon to the Cart.
Is there a way to completely override the price to something totally custom?
Here is the code for overriding price of product in cart
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;
// for WooCommerce version 3+ use:
// $value['data']->set_price($custom_price);
}
}
Hope it will be useful...
You need to introduce an if statement for checking product id, in above 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
$target_product_id = 598;
foreach ( $cart_object->cart_contents as $value ) {
if ( $value['product_id'] == $target_product_id ) {
$value['data']->price = $custom_price;
}
/*
// If your target product is a variation
if ( $value['variation_id'] == $target_product_id ) {
$value['data']->price = $custom_price;
}
*/
}
}
Add this code anywhere and make sure that this code is always executable.
After adding this code, when you'll call:
global $woocommerce;
$woocommerce->cart->add_to_cart(598);
Only this product will be added with overridden price, other products added to cart will be ignored for overriding prices.
Hope this will be helpful.
I have tried all above code samples and latest woocommerce 3.0 is not support any of the above example. Use below code and working perfectly for me.
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
$custom_price = 10; // This will be your custom price
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$cart_item['data']->set_price($custom_price);
}
}
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_object->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
For the Wordpress and Woocommerce latest version,Please use like this
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
foreach ( $cart_object->cart_contents as $key => $value ) {
$custom_price = 5;
$value['data']->set_price($custom_price);
}
}
For eveeryone that got here from Google. The above is now deprecated as i found out updating to WooCommerce 3.0.1.
Instead of the above you now need to use set_price instead of price
Here is an example:
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']->set_price = $custom_price;
}
}
I hope this helps people in the future :)
This is how i did it, first i add my custom price to cart_item_data witch can save custom data to cart items, then i use woocommerce_before_calculate_totals, loop the cart and add the previously added price.
function add_donation_to_cart() {
$cart_item_data = array('price' => $_REQUEST['donate_amount']);
$woocommerce->cart->add_to_cart( 5395, 1, '', array(), $cart_item_data);
}
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart ) {
foreach ( $cart->cart_contents as $key => $value ) {
$value['data']->price = $value['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 checkout via the woocommerce_get_cart_item_from_session filter. This seems to be faster than hooking the calculate totals filters (such as woocommerce_before_calculate_totals) as they are run very frequently in WooCommerce.
More details here:
woocommerce change price while add to cart
To make it dynamic ( override price for each item in cart separately ), you need to save the override product price in session with cart item key as session key using woocommerce_add_to_cart hook.
by using these session values you can calculate correct Cart Total and make the altered price appear in the Order Item as well
You can use the following
add_filter( 'woocommerce_cart_item_price', 'kd_custom_price_message' );
function kd_custom_price_message( $price ) {
$textafter = ' USD';
return $price . $textafter;
}
Related
By default when woocommerce cart quantity is changed it updates the item price by multiplying it by the quantity. I would like to change the default behaviour and ensure that when in the cart when the quantity is changed it doesnt change the default price passed when add to cart is clicked
I have added this action hook but i cannot figure out how to stop price change when quantity is changed in a cart.
add_action( 'woocommerce_after_cart_item_quantity_update', 'on_quantity_changed_in_cart', 20, 4 );
function on_quantity_changed_in_cart( $cart_item_key, $quantity, $old_quantity, $cart){
if( ! is_cart() ) return; // Only on cart page
//here stop price from been changed by default
}
Looking to "Disable Woocommerce cart line item quantity price calculation" answer thread, I found out I need to override an action hook to replace the final cost per line:
add_filter('woocommerce_cart_product_subtotal', [$this, 'filter_woocommerce_cart_product_subtotal'], 10, 4);
public function filter_woocommerce_cart_product_subtotal($product_subtotal, $product, $quantity, $cart){
$sub_value = 0;
foreach ($cart->cart_contents as $hash => $value) {
if ($value["product_id"] === wc_get_product($product)->get_id()) {
$sub_value = $value["wcform-custom_price"];
//wcform-custom_price is passed from when adding to the cart.
}
};
return wc_price($sub_value);
}
Now on the totals as well I overriden the following
add_action( 'woocommerce_calculate_totals', [$this,'custom_item_price'],20,1);
add_filter( 'woocommerce_calculated_total', [$this,"calculateFinalTotal"], 20, 2 );
public function custom_item_price( $wc_cart ) {
$cart_contents_total = 0;
foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item ){
$cart_contents_total += $cart_item["wcform-custom_price"];
}
$wc_cart->subtotal = $cart_contents_total;
}
public function calculateFinalTotal($total,$cart){
$cart_contents_total = 0;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ){
$cart_contents_total += $cart_item["wcform-custom_price"];
}
return $cart_contents_total;;///print_r($cart->get_cart());
}
Writing an addition to the site, want to modify the price in the cart. Have the following code:
function apd_product_custom_price($cart_item_data, $product_id)
{
if (isset($_POST['use_rewards']) && !empty($_POST['use_rewards']))
{
$cart_item_data['use_rewards'] = $_POST['use_rewards'];
}
return $cart_item_data;
}
add_filter('woocommerce_add_cart_item_data', 'apd_product_custom_price', 99, 2);
function apd_apply_custom_price_to_cart_item($cart_object)
{
if( !WC()->session->__isset( 'reload_checkout' )) {
foreach ($cart_object->cart_contents as $value) {
if(isset($value['use_rewards'])) {
$price = $value['data']->get_price() -
$value['use_rewards'];
$value['data']->set_price($price);
}
}
}
}
add_action('woocommerce_before_calculate_totals', 'apd_apply_custom_price_to_cart_item',10);
By some reason the hook woocommerce_before_calculate_totals fires twice. if I replace the code in the function apd_apply_custom_price_to_cart_item($cart_object) with just echo 1; it displays 11 in the cart page. Can some please help?
I forgot the link I should refer to for a solution. You can use this at the top of your function:
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
Most likely some other plugins hooks to 'woocommerce_before_calculate_totals' action.
Try to disable plugins one by one and see witch one is causing this behaviour.
In my case I found that WooCommerce-multilingual plugin hooks to woocommerce_before_calculate_totals action.
So I did this:
add_action( 'woocommerce_before_calculate_totals', '_wm_ponc_upte_prc', 99 );
function _wm_ponc_upte_prc( $cart_object ) {
if ( !WC()->session->__isset( "reload_checkout" ) ) {
foreach ( WC()->cart->get_cart() as $key => $value ) {
// checking if user checked checkbox (optional)
if ( isset( $value['wm_ponc_fee'] ) && ( $value[ 'wm_ponc_fee' ] === 'yes' ) ) {
// your calculations ....
// and Remove your action after you are done.
remove_action( 'woocommerce_before_calculate_totals', '_wm_ponc_upte_prc', 99 );
}
}
}
}
I have removed action after custom calculations. And that's it.
I see exactly the same issue - my hooked function is firing twice, leading to the option price being added at 2x the cost. My solution was to load the product, get the price from that and then add my incremental cost to that.
function tbk_woo_update_option_price( $cart_object ) {
$option_price = 3.50;
foreach ( $cart_object->get_cart() as $cart_item_key => $cart_item ) {
$item_id = $cart_item['data']->id;
//Hook seems to be firing twice for some reason... Get the price from the original product data, not from the cart...
$product = wc_get_product( $item_id );
$original_price = $product->get_price();
$new_price = $original_price + $option_price;
$cart_item['data']->set_price( $new_price );
}
}
add_action( 'woocommerce_before_calculate_totals', 'tbk_woo_update_option_price', 1000, 1 );
I am getting the dynamic custom price in a variable that I want to pass to the hooked function in woocommerce_before_calculate_totals hook in cart. But it isn't working.
This is my code:
$add=200; //I want to pass this variable in add_action hook
add_action( 'woocommerce_before_calculate_totals', 'add_custom_total_price');
function add_custom_total_price($cart_object) {
global $woocommerce;
$custom_price =$add; // This is my custom price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
}
}
How can I achieve this?
Thanks
To make it work you just need to define $custom_price variables as global in your function, this way:
$custom_price = 200;
add_action( 'woocommerce_before_calculate_totals', 'add_custom_item_price', 10, 1 );
function add_custom_item_price( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
global $custom_price;
foreach ( $cart_object->get_cart() as $item_values ) {
$item_values['data']->price = $custom_price;
}
}
This code is tested and working (for woocommerce versions 2.5+ and 2.6+).
Naturally this code goes on function.php file of your active child theme or theme.
To add Price in your woocommerce cart before calculate total -
add_action( 'woocommerce_before_calculate_totals', 'add_custom_total_price');
function add_custom_total_price($cart_object) {
global $woocommerce,$add,$custom_price;
$add=200;//Dynamic Price variable
$custom_price =$add;//Dynamic Price variable pass to custom price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
}
}
I would like to make a script for automatically adding a bonus product to WooCommerce cart.
The bonus product would be added into the cart on adding a specific product(s). But I've never seen any improved and fully working code with features - such as automatically removing the bonus item or removing the primary product(s) from the cart.
In this solution I've come up with the below code which has the following features:
Options
Multiple required products
Automatic adding
Automatic removing (if there's no required product in the cart)
function bonus_product() {
if (is_admin()) return;
//## OPTIONS
$options = (object) array(
'bonus_product_id' => 1891, //bonus product to add
'required_products_id' => array(1873), //at least on of the specific product(s) needs to be represented in the cart
);
//function variables
$cart_items = WC()->cart->get_cart();
$bonus_product_found = false;
$required_product_found = false;
//check if the cart is not empty
if(sizeof($cart_items) > 0) {
//checking for required products. loop through the cart items
foreach ($cart_items as $key => $item) {
//bonus product already in the cart?
if($item['product_id'] == $options->bonus_product_id) {
$bonus_product_found = true;
}
//one of required products in the cart?
if(in_array($item['product_id'], $options->required_products_id)) {
$required_product_found = true;
}
}
//adding/removing bonus product
//add bonus product to the cart
if(!$bonus_product_found && $required_product_found) {
WC()->cart->add_to_cart($options->bonus_product_id);
}
//remove bonus product from the cart if none of required items is in the cart
if($bonus_product_found && !$required_product_found) {
$cart = WC()->instance()->cart;
$cart_id = $cart->generate_cart_id($options->bonus_product_id);
$cart_item_id = $cart->find_product_in_cart($cart_id);
$cart->set_quantity($cart_item_id, 0);
}
}
}
add_action( 'init', 'bonus_product' );
I have written an alternative version, based on Add To Cart and Remove From Cart action, which seems to be more appropriate.
$bonus_options = (object) array(
'bonus_product_id' => 1891,
'required_products_id' => array( 1873 )
);
// this function called whenever there is a product added to cart
function add_bonus_product( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) {
global $bonus_options;
// is the product is eligible for bonus product?
if( in_array( $product_id, $bonus_options->required_products_id) ) {
// add the bonus product to cart
WC()->cart->add_to_cart( $bonus_options->bonus_product_id, 1, 0, array(), array( "parent_product_line_item" => $cart_item_key ) );
// later if user removes the product from cart we can use the "parent_product_line_item" to remove the bonus product as well
}
}
add_action( 'woocommerce_add_to_cart', 'add_bonus_product', 10, 6 );
// this function will be called whenever there is a product removed from cart
function remove_bonus_product( $cart_item_key, $cart ) {
$cart_items = WC()->cart->get_cart();
foreach ( $cart_items as $key => $item ) {
if( $item["parent_product_line_item"] == $cart_item_key ) {
// ok this cart item is a bonus item to the product that being removed from the cart
// So remove this too
WC()->cart->remove_cart_item( $key );
}
}
}
add_action( 'woocommerce_cart_item_removed', 'remove_bonus_product', 10, 2 );
How can I set a custom price based on user input? This custom price is hard coded. Any suggestions? Something like function add_custom_price( $cart_object, $custom_price )
<code>add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object,$custom_price ) {
$custom_price = $variable_from_input; // This will be my custom input variable
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
}
}</code>