Change Cart Item Prices in Woocommerce 3

Change cart item prices in Woocommerce 3

Update 2021 (Handling mini cart custom item price)

With WooCommerce version 3.0+ you need:

  • To use woocommerce_before_calculate_totals hook instead.
  • To use WC_Cart get_cart() method instead
  • To use WC_product set_price() method instead

Here is the code:

// Set custom cart item price
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 1000, 1);
function add_custom_price( $cart ) {
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

// Avoiding hook repetition (when using price calculations for example | optional)
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;

// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
$cart_item['data']->set_price( 40 );
}
}

And for mini cart (update):

// Mini cart: Display custom price 
add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 3 );
function filter_cart_item_price( $price_html, $cart_item, $cart_item_key ) {

if( isset( $cart_item['custom_price'] ) ) {
$args = array( 'price' => 40 );

if ( WC()->cart->display_prices_including_tax() ) {
$product_price = wc_get_price_including_tax( $cart_item['data'], $args );
} else {
$product_price = wc_get_price_excluding_tax( $cart_item['data'], $args );
}
return wc_price( $product_price );
}
return $price_html;
}

Code goes in functions.php file of your active child theme (or active theme).

This code is tested and works (still works on WooCommerce 5.1.x).

Note: you can increase the hook priority from 20 to 1000 (or even 2000) when using some few specific plugins or others customizations.

Related:

  • Set cart item price from a hidden input field custom price in Woocommerce 3
  • Change cart item prices based on custom cart item data in Woocommerce
  • Set a specific product price conditionally on Woocommerce single product page & cart
  • Add a select field that will change price in Woocommerce simple products

Increase cart item prices based on payment method in WooCommerce

There are some mistakes in your code

  • Use WC()->session->get( 'chosen_payment_method' ); outside the foreach loop
  • get_post_meta() is not needed to get the price, you can use get_price()
  • You will also need jQuery that is triggered when changing the payment method.

So you get:

function action_woocommerce_before_calculate_totals( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;

// Get payment method
$chosen_payment_method = WC()->session->get( 'chosen_payment_method' );

// Compare
if ( $chosen_payment_method == 'cod' ) {
$increaseby = 3;
} elseif ( $chosen_payment_method == 'paypal' ) {
$increaseby = 8;
} else {
$increaseby = 10;
}

// Loop through cart items
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
// Get price
$price = $cart_item['data']->get_price();

// Set price
$cart_item['data']->set_price( $price + ( $price * $increaseby ) / 100 );
}
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );

function action_wp_footer() {
if ( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script type="text/javascript">
jQuery(function($){
$( 'form.checkout' ).on( 'change', 'input[name="payment_method"]', function() {
$(document.body).trigger( 'update_checkout' );
});
});
</script>
<?php
endif;
}
add_action( 'wp_footer', 'action_wp_footer' );

Change cart item prices based on custom cart item data in Woocommerce

You need to use 2 different hooks:

  • The first one just as yours without trying to change the price in it.
  • The second one where you will change your cart item price

The code:

add_filter( 'woocommerce_add_cart_item', 'add_custom_cart_item_data', 10, 2 );
function add_custom_cart_item_data( $cart_item_data, $cart_item ) {

if( isset( $_POST['new-width'] ) )
$cart_item_data['new-width'] = $_POST['new-width'];
if(isset( $_POST['new-height'] ) )
$cart_item_data['new-height'] = $_POST['new-height'];

return $cart_item_data;
}


add_action( 'woocommerce_before_calculate_totals', 'set_custom_cart_item_price', 20, 1 );
function set_custom_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;

// First loop to check if product 11 is in cart
foreach ( $cart->get_cart() as $cart_item ){
if( isset($cart_item['new-width']) && isset($cart_item['new-height'])
&& ! empty($cart_item['new-width']) && ! empty($cart_item['new-height']) )
$cart_item['data']->set_price( '30' );
}
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works

How to use cart total to change cart items prices in WooCommerce

You can simply not use cart total in woocommerce_before_calculate_totals when you want to alter cart item price for many reasons…

Instead you will get cart item subtotal inside woocommerce_before_calculate_totals hook. On the code below I use the discounted cart item subtotal including taxes:

add_action('woocommerce_before_calculate_totals', 'customize_cart_item_prices');
function customize_cart_item_prices( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

// Avoiding the hook repetition for price calculations
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;

$threshold_amount = 1000; // Min subtotal
$discount_rate = 0.2; // price discount rate (20%)

$cart_items = $cart->get_cart();

// Getting non discounted cart items subtotal
$subtotal_excl_tax = array_sum( wp_list_pluck( $cart_items, 'line_subtotal' ) );
$subtotal_tax = array_sum( wp_list_pluck( $cart_items, 'line_subtotal_tax' ) );

// Getting discounted cart items subtotal
$total_excl_tax = array_sum( wp_list_pluck( $cart_items, 'line_total' ) );
$total_tax = array_sum( wp_list_pluck( $cart_items, 'line_tax' ) );

if( ( $total_excl_tax + $total_tax ) >= $threshold_amount ) {
// Loop through cart items
foreach ( $cart_items as $item ) {
$price = $item['data']->get_price(); // Get price

$item['data']->set_price( $price * ( 1 - $discount_rate ) ); // Set new price
}
}
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

See on Change cart item prices in Woocommerce 3 answer code, to see how to handle minicart displayed custom cart item price.

Issue with changing WooCommerce cart item prices based on product meta

The woocommerce_cart_item_name hook is being misused in your code attempt. A filter hook should always return something compared to the use of echo.

You should use the woocommerce_before_calculate_totals hook instead

So you get:

function action_woocommerce_before_calculate_totals( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;

// Change price if > 3000
$threshold = 3000;

// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
// Get regular price
$price = $cart_item['data']->get_regular_price();

// Subtotal = Get quantity * price
$subtotal = $cart_item['quantity'] * $price;

// Greater than
if ( $subtotal > $threshold ) {
// Get meta
$meta = $cart_item['data']->get_meta( '_opt_price_var', true );

// NOT empty
if ( ! empty ( $meta ) ) {
// Set new price
$cart_item['data']->set_price( $meta );
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );

Change WooCommerce cart item price based on a custom field and quantity threshold

In your code $variation_data['variation_id'] is not defined as $variation_data doesn't exist for woocommerce_before_calculate_totals hook… Try the following instead:

add_action( 'woocommerce_before_calculate_totals', 'quantity_based_bulk_pricing', 9999, 1 );
function quantity_based_bulk_pricing( $cart ) {

if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;

// Define the quantity threshold
$qty_threshold = 6;

// Loop through cart items
foreach( $cart->get_cart() as $cart_item_key => $cart_item ) {
// Get the bulk price from product (variation) custom field
$bulk_price = (float) $cart_item['data']->get_meta('bulk_price');

// Check if item quantity has reached the defined threshold
if( $cart_item['quantity'] >= $qty_threshold && $bulk_price > 0 ) {
// Set the bulk price
$cart_item['data']->set_price( $bulk_price );
}
}
}

Code goes in functions.php file of your active child theme (or active theme). It should works.

Change cart item price if a specific item is in the cart on Woocommerce

Updated (on October 2018)

You have complicated everything here as you just want to add to a specific product (ID 17) on sale an additional cost when customer is not yet member.

You don't need 2 separated functions for this and your 2nd function is doing it in the wrong way. It don't need to be hooked if you are calling it in your first hooked function.

I have revisited your code completely, using WC_Product methods instead of get_post_meta()

Also the WC_Product method is_on_sale() manage everything like from/to dates for on sale product prices. So you don't need to get that in your function.

In your code there is no differences when product 11 is in cart or is NOT in cart within your 2 Cart loops… So you should may be need to make some changes there.

So your code is now very compact:

add_action( 'woocommerce_before_calculate_totals', 'mps_registration_price', 20, 1 );
function mps_registration_price( $cart ) {

if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;

// Bail if memberships is not active
if ( ! function_exists( 'wc_memberships' ) ) return; // Exit

// Only for non members
$user_id = get_current_user_id();
if ( wc_memberships_get_user_memberships( $user_id ) ) return; // Exit

// First loop to check if product 11 is in cart
foreach ( $cart->get_cart() as $cart_item ){
$is_in_cart = $cart_item['product_id'] == 11 ? true : false;
}

// Second loop change prices
foreach ( $cart->get_cart() as $cart_item ) {

// Get an instance of the WC_Product object (or the variation product object)
$product = $cart_item['data'];

// Method is_on_sale() manage everything (dates…)
// Here we target product ID 17
if( $product->is_on_sale() && $product->get_id() == 17 ) {

// When product 11 is not cart
if( ! $is_in_cart ){
$product->set_price( $product->get_sale_price() + 50);
}
}
}
}

Code goes in function.php file of your active child theme (or active theme) or in any plugin file.

Tested and works.



Related Topics



Leave a reply



Submit