Set Cart Item Price from a Hidden Input Field Custom Price in Woocommerce 3

Set cart item price from a hidden input field custom price in Woocommerce 3

Update 2021 - Handling custom price item in mini cart

First for testing purpose we add a price in the hidden input field as you don't give the code that calculate the price:

// Add a hidden input field (With a value of 20 for testing purpose)
add_action( 'woocommerce_before_add_to_cart_button', 'custom_hidden_product_field', 11 );
function custom_hidden_product_field() {
echo '<input type="hidden" id="hidden_field" name="custom_price" class="custom_price" value="20">'; // Price is 20 for testing
}

Then you will use the following to change the cart item price (WC_Session is not needed):

// Save custom calculated price as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_fields_data_to_cart', 10, 2 );
function save_custom_fields_data_to_cart( $cart_item_data, $product_id ) {

if( isset( $_POST['custom_price'] ) && ! empty( $_POST['custom_price'] ) ) {
// Set the custom data in the cart item
$cart_item_data['custom_price'] = (float) sanitize_text_field( $_POST['custom_price'] );

// Make each item as a unique separated cart item
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}

// For mini cart
add_action( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 2 );
function filter_cart_item_price( $price, $cart_item ) {
if ( isset($cart_item['custom_price']) ) {
$args = array( 'price' => floatval( $cart_item['custom_price'] ) );

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

// Updating cart item price
add_action( 'woocommerce_before_calculate_totals', 'change_cart_item_price', 30, 1 );
function change_cart_item_price( $cart ) {
if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) )
return;

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

// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
// Set the new price
if( isset($cart_item['custom_price']) ){
$cart_item['data']->set_price($cart_item['custom_price']);
}
}
}

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

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.

How to set custom product price after add to cart in WooCommerce?

You used woocommerce_add_cart_item_data to add custom meta is right but you didn't set custom price to product price.

function wdm_add_item_data( $cart_item_data, $product_id ) {

$cart_item_data[ "_custom_options" ] = 678
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'wdm_add_item_data', 10, 2 );

Use the woocommerce_before_calculate_totals action hook to set
custom price to product in the cart.

function woocommerce_custom_price_to_cart_item( $cart_object ) {  
foreach ( $cart_object->cart_contents as $key => $value ) {
if( isset( $value["_custom_options"] ) ) {
$value['data']->set_price($value["_custom_options"]);
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'woocommerce_custom_price_to_cart_item', 10 );

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

Display a custom calculated cart item price in WooCommerce

The $price argument in this hook is the formatted product item price, then you need the raw price instead to make it work on your custom calculation. Try the following instead:

add_filter( 'woocommerce_cart_item_price', 'change_cart_item_price', 10, 3 );
function change_cart_item_price( $price, $cart_item, $cart_item_key ){
if ( WC()->cart->display_prices_including_tax() ) {
$product_price = wc_get_price_including_tax( $cart_item['data'] );
} else {
$product_price = wc_get_price_excluding_tax( $cart_item['data'] );
}

if ( isset($cart_item['length']) ) {
$price = wc_price( $product_price * $cart_item['length'] );
}
return $price;
}

It should work.

Replace the price of the cart item with a custom field value in Woocommerce

It doesn't work if you use get_the_ID() with get_post_meta() in cart. You should use instead:

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

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

foreach ( $cart->get_cart() as $cart_item ) {

// get the product id (or the variation id)
$product_id = $cart_item['data']->get_id();

// GET THE NEW PRICE (code to be replace by yours)
$new_price = get_post_meta( $product_id, '_c_price_field', true );

// Updated cart item price
$cart_item['data']->set_price( floatval( $new_price ) );
}
}

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

Now it should work

Cart item price calculation, based on chosen days custom field in Woocommerce

The code in your question make errors due to code formatting, surely when you copy paste it.

For example - > need to be -> or $product_price. = need to be $product_price .=

To understand, see about PHP operators.

Here below you will find the correct way for your calculations based on rental "Period" (days):

// HERE your rental days settings
function get_rental_days_options() {
return array(
'2' => __("2 Days", "woocommerce"),
'4' => __("4 Days", "woocommerce"),
);
}

// Add a custom field before single add to cart
add_action('woocommerce_before_add_to_cart_button', 'display_single_product_custom_fields', 5);

function display_single_product_custom_fields() {
// Get the rental days data options
$options = array('' => __("Choosen period", "woocommerce")) + get_rental_days_options();

echo '<div class="custom-text text">
<h3>'.__("Rental", "woocommerce").'</h3>
<label>'.__("Start Date", "woocommerce").': </label>
<input type="date" name="rental_date" value="" class="rental_date" />
<label>Period:</label>
<select class="rental-days" id="rental-days" name="rental_days">';

foreach( $options as $key => $option ){
echo '<option value="'.$key.'">'.$option.'</option>';
}

echo '</select>
</div>';
}

// Get custom field value, calculate new item price, save it as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data', 20, 3);

function add_custom_field_data($cart_item_data, $product_id, $variation_id) {
// HERE set the percentage rate to be applied to get the new price
$percentage = 2;

if (isset($_POST['rental_date']) && !empty($_POST['rental_date'])) {
$cart_item_data['custom_data']['start_date'] = $_POST['rental_date'];
}

if (isset($_POST['rental_days']) && !empty($_POST['rental_days'])) {
$cart_item_data['custom_data']['rental_days'] = esc_attr($_POST['rental_days']);

$_product_id = $variation_id > 0 ? $variation_id : $product_id;

$product = wc_get_product($_product_id); // The WC_Product Object
$base_price = (float) $product->get_regular_price(); // Get the product regular price

$price_rate = $cart_item_data['custom_data']['rental_days'] * $percentage / 100;

$cart_item_data['custom_data']['base_price'] = $base_price;
$cart_item_data['custom_data']['new_price'] = $base_price * $price_rate;
}

// Make each cart item unique
if (isset($cart_item_data['custom_data']['rental_days']) || isset($cart_item_data['custom_data']['start_date'])) {
$cart_item_data['custom_data']['unique_key'] = md5(microtime().rand());
}

return $cart_item_data;
}

// Set the new calculated cart item price
add_action('woocommerce_before_calculate_totals', 'extra_price_add_custom_price', 20, 1);
function extra_price_add_custom_price($cart) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

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

foreach($cart->get_cart() as $cart_item) {
if (isset($cart_item['custom_data']['new_price']))
$cart_item['data']->set_price((float) $cart_item['custom_data']['new_price']);
}
}

// Display cart item custom price details
add_filter('woocommerce_cart_item_price', 'display_cart_items_custom_price_details', 20, 3);

function display_cart_items_custom_price_details($product_price, $cart_item, $cart_item_key) {
if (isset($cart_item['custom_data']['base_price'])) {
$product = $cart_item['data'];
$base_price = $cart_item['custom_data']['base_price'];
$product_price = wc_price(wc_get_price_to_display($product, array('price' => $base_price))). '<br>';

if (isset($cart_item['custom_data']['rental_days'])) {
$rental_days = get_rental_days_options();
$product_price .= $rental_days[$cart_item['custom_data']['rental_days']];
}
}
return $product_price;
}

// Display in cart item the selected date
add_filter('woocommerce_get_item_data', 'display_custom_item_data', 10, 2);

function display_custom_item_data($cart_item_data, $cart_item) {
if (isset($cart_item['custom_data']['start_date'])) {
$cart_item_data[] = array(
'name' => __("Rental start date", "woocommerce"),
'value' => date('d.m.Y', strtotime($cart_item['custom_data']['start_date'])),
);
}

if (isset($cart_item['custom_data']['rental_days'])) {
$rental_days = get_rental_days_options();
$cart_item_data[] = array(
'name' => __("Rental period", "woocommerce"),
'value' => $rental_days[$cart_item['custom_data']['rental_days']],
);
}

return $cart_item_data;
}

// Save and display custom field in orders and email notifications (everywhere)
add_action( 'woocommerce_checkout_create_order_line_item', 'custom_fields_update_order_item_meta', 20, 4 );

function custom_fields_update_order_item_meta( $item, $cart_item_key, $values, $order ) {
if ( isset( $values['custom_data']['date'] ) ){
$date = date( 'd.m.Y', strtotime( $values['custom_data']['date'] ) );
$item->update_meta_data( __( 'Start date', 'woocommerce' ), $date );
}
if ( isset( $values['custom_data']['rental_days'] ) ){
$rental_days = get_rental_days_options();
$item->update_meta_data( __( 'Rental period', 'woocommerce' ), $rental_days[$values['custom_data']['rental_days']] );
}
}

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

Sample Image



Related Topics



Leave a reply



Submit