How can I set a minimum order amount only for Delivery/Shipments (but not for local pickup) and depending on specific post codes?
Use Case: A Restaurant delivers in the local village without minimum amount. But the neighbor villages should have an order amount. Pickup is always without any minimum amount.
Based on Minimum order amount except for specific shipping method in WooCommerce answer code, this is my attempt:
add_action( 'woocommerce_check_cart_items', 'wc_minimum_required_order_amount' );
function wc_minimum_required_order_amount() {
// HERE Your settings
$minimum_amount = 50; // The minimum cart total amount
$shipping_method_id = 'local_pickup'; // The targeted shipping method Id (exception)
$postcodes = array('82065', '82057', '82067'); // Define your targeted postcodes in the array
$postcode = '82069'; // Initializing
// Get some variables
$cart_total = (float) WC()->cart->total; // Total cart amount
$chosen_methods = (array) WC()->session->get( 'chosen_shipping_methods' ); // Chosen shipping method rate Ids (array)
// Only when a shipping method has been chosen
if ( ! empty($chosen_methods) ) {
$chosen_method = explode(':', reset($chosen_methods)); // Get the chosen shipping method Id (array)
$chosen_method_id = reset($chosen_method); // Get the chosen shipping method Id
}
// If "Local pickup" shipping method is chosen, exit (no minimun is required)
if ( isset($chosen_method_id) && $chosen_method_id === $shipping_method_id ) {
return; // exit
}
if ( isset($_POST['shipping_postcode']) && ! empty($_POST['shipping_postcode']) ) {
$postcode = $_POST['shipping_postcode'];
if ( empty($postcode) && isset($_POST['billing_postcode']) && ! empty($_POST['billing_postcode']) ) {
$postcode = $_POST['billing_postcode'];
}
} elseif ( $postcode = WC()->customer->get_shipping_postcode() ) {
if ( empty($postcode) ) {
$postcode = WC()->customer->get_billing_postcode();
}
}
// Add an error notice is cart total is less than the minimum required
if ( $cart_total < $minimum_amount && ! empty($postcode) && in_array( $postcode, $postcodes ) ) {
wc_add_notice( sprintf(
__("The minimum required order amount is %s (your current order amount is %s).", "woocommerce"), // Text message
wc_price( $minimum_amount ),
wc_price( $cart_total )
), 'error' );
}
}
You are close with your solution, what is missing, however, is the use of in_array(), with which you can check the postcode
So you get:
function action_woocommerce_check_cart_items() {
// HERE Your settings
$minimum_amount = 50; // The minimum cart total amount
$shipping_method_id = 'local_pickup'; // The targeted shipping method Id (exception)
$postcodes = array( 82065, 82057, 82067, 9800 ); // Define your targeted postcodes in the array
// Get some variables
$cart_total = (float) WC()->cart->total; // Total cart amount
$chosen_methods = (array) WC()->session->get( 'chosen_shipping_methods' ); // Chosen shipping method rate Ids (array)
// Initialize
$postcode = '';
// Only when a shipping method has been chosen
if ( ! empty($chosen_methods) ) {
$chosen_method = explode( ':', reset( $chosen_methods ) ); // Get the chosen shipping method Id (array)
$chosen_method_id = reset( $chosen_method ); // Get the chosen shipping method Id
}
// If "Local pickup" shipping method is chosen, exit (no minimun is required)
if ( isset($chosen_method_id) && $chosen_method_id === $shipping_method_id ) {
return; // exit
}
// Get shipping postode
$postcode = WC()->customer->get_shipping_postcode();
// When empty
if ( empty ( $postcode ) ) {
if ( isset( $_POST['shipping_postcode'] ) ) {
$postcode = $_POST['shipping_postcode'];
} else {
if ( isset( $_POST['billing_postcode'] ) ) {
$postcode = $_POST['billing_postcode'];
} else {
$postcode = WC()->customer->get_billing_postcode();
}
}
}
// Still empty, exit
if ( empty ( $postcode ) ) return;
// Add an error notice is cart total is less than the minimum required and postcode occurs in the array
if ( $cart_total < $minimum_amount && in_array( $postcode, $postcodes ) ) {
// Your error message
wc_add_notice( sprintf(
__( 'The minimum required order amount is %s (your current order amount is %s).', 'woocommerce' ), // Text message
wc_price( $minimum_amount ),
wc_price( $cart_total )
), 'error' );
// Optional: remove proceed to checkout button
remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
}
}
add_action( 'woocommerce_check_cart_items' , 'action_woocommerce_check_cart_items', 10, 0 );
Related
I need to force a minimum order amount for just some categories in WooCommerce, and therefore set an alert in the cart and checkout pages.
So far I managed to set an alert if the total amount in the cart is lower than the minimum amount set, but I can't manage to create a category based filter. Actually any other product is added in the cart the alert is overtaken and the user is allowed to buy the product of that category I want to limit.
Here is the code:
/**
* Set a minimum order amount for checkout
*/
add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_cart' , 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_checkout' , 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
// Set this variable to specify a minimum order value
$minimum = 30;
// set array with cat IDs
$category_ids = array( 336, 427, 433 );
// set bool that checks is minimum amount has been reached
$needs_minimum_amount = false; // Initializing
$subTotal_amount = WC()->cart->subtotal; // Items subtotal including taxes
$total_amount = WC()->cart->total; // Items subtotal excluding taxes
if ( $total_amount < $minimum ) {
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
$product_id = $cart_item['product_id'];
$variation_id = $cart_item['variation_id'];
// Check for matching product categories
if( sizeof($category_ids) > 0 ) {
$taxonomy = 'product_cat';
if ( has_term( $category_ids, $taxonomy, $product_id ) ) {
$needs_minimum_amount = true;
break; // Stop the loop
}
}
}
if( $needs_minimum_amount ) {
if( is_cart()) {
wc_print_notice(
sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order ' ,
wc_price( WC()->cart->total ),
wc_price( $minimum )
), 'error'
);
} else {
wc_add_notice(
sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order' ,
wc_price( WC()->cart->total ),
wc_price( $minimum )
), 'error'
);
}
}
}
}
References:
Set minimum Order amount for specific Products or Categories in WooCommerce
https://docs.woocommerce.com/document/minimum-order-amount/
Any help?
There are some mistakes in your code… Use the following instead:
add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_cart', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_checkout_form', 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
$min_amount = 30; // Min subtotal required
$taxonomy = 'product_cat'; // Product category taxonomy | For product tags use 'product_tag'
$terms = array( 336, 427, 433 ); // Category terms (can be Ids, slugs, or names)
$found = false; // Initializing
$subtotal = WC()->cart->subtotal; // Incl. taxes
$total = WC()->cart->total; // Incl. taxes
if ( $total < $min_amount ) {
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( has_term( $terms, $taxonomy, $cart_item['product_id'] ) ) {
$found = true;
break; // Stop the loop
}
if( $found ) {
$message = sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order ' ,
wc_price( $total ),
wc_price( $min_amount )
);
if( is_cart()) {
wc_print_notice( $message, 'error' );
} else {
wc_add_notice( $message, 'error' );
}
}
}
}
}
Code goes in functions.php file of the active child theme (or active theme). It should work.
Addition: Based on specific subtotal incl. taxes
This code version is based on items subtotal belonging to specific defined categories:
add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_cart', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_checkout_form', 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
$min_amount = 30; // Min subtotal required
$taxonomy = 'product_cat'; // Product category taxonomy | For product tags use 'product_tag'
$terms = array( 336, 427, 433 ); // Category terms (can be Ids, slugs, or names)
$subtotal = 0; // Initializing
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( has_term( $terms, $taxonomy, $cart_item['product_id'] ) ) {
$subtotal += $cart_item['line_subtotal'] + $cart_item['line_subtotal_tax'];
}
}
if ( $subtotal < $min_amount ) {
if( $found ) {
$message = sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order ' ,
wc_price( $total ),
wc_price( $min_amount )
);
if( is_cart()) {
wc_print_notice( $message, 'error' );
} else {
wc_add_notice( $message, 'error' );
}
}
}
}
It should works.
Finally I found the solution working a little on the code provided by #LoicTheAztec.
Below the final code. Tested and working.
// Set a minimum order amount for checkout
add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_cart' , 'wc_minimum_order_amount' );
// add_action( 'woocommerce_before_checkout' , 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
$min_amount = 30; // Set this variable to specify a minimum order value
$taxonomies = array('product_cat'); // Product category taxonomy | For product tags use 'product_tag'
$term_ids = array( 336, 427, 433 ); // Category terms (can be Ids, slugs, or names)
$found = false; // Initializing // set bool that checks if minimum amount has been reached
$subtotal = 0; // Initializing // set subtotal formed by specific category total (incl. taxes)
$subTotal_amount = WC()->cart->subtotal; // Items subtotal including taxes
$total_amount = WC()->cart->total; // Items subtotal including taxes
// 1 - Loop through cart items targeting those having that specific category
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( has_term( $term_ids, $taxonomies[0], $cart_item['product_id'] ) ) {
$subtotal += $cart_item['line_subtotal'] + $cart_item['line_subtotal_tax'];
}
}
// 2 - Check if at least one product of that category is in the cart
if($subtotal > 0){
$found = true;
}
// 2 - check if subtotal is below the min amount set
if ( $subtotal < $min_amount ) {
if( $found ) {
$message = sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order ' ,
wc_price( $subtotal ),
wc_price( $min_amount )
);
if( is_cart()) {
wc_print_notice( $message, 'error' );
} else {
wc_add_notice( $message, 'error' );
}
}
}
}
I use a code that adds a 20% discount when choosing "Local Pickup" in the cart and at checkout based on Do not give discounts for on sale products when selecting “local pickup” in WooCommerce
/**
* Discount for Local Pickup
*/
add_action( 'woocommerce_cart_calculate_fees', 'custom_discount_for_pickup_shipping_method', 10, 1 );
function custom_discount_for_pickup_shipping_method( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$percentage = 20; // Discount percentage
$chosen_shipping_method_id = WC()->session->get( 'chosen_shipping_methods' )[0];
$chosen_shipping_method = explode(':', $chosen_shipping_method_id)[0];
// Only for Local pickup chosen shipping method
if ( strpos( $chosen_shipping_method_id, 'local_pickup' ) !== false ) {
// Set variable
$new_subtotal = 0;
// Loop though each cart items and set prices in an array
foreach ( $cart->get_cart() as $cart_item ) {
// Get product
$product = wc_get_product( $cart_item['product_id'] );
// Product has no discount
if ( ! $product->is_on_sale() ) {
// line_subtotal
$line_subtotal = $cart_item['line_subtotal'];
// Add to new subtotal
$new_subtotal += $line_subtotal;
}
}
// Calculate the discount
$discount = $new_subtotal * $percentage / 100;
// Add the discount
$cart->add_fee( __('Discount') . ' (' . $percentage . '%)', -$discount );
}
}
Tell me how to make sure that the local-pickup discount is not taken if the product is from certain categories? I must specify the category name manually, for example, "steak", "sauce" and "bread".
And how to make a notice to customers "Pickup discount does not apply to products from the" Category Name "category"?
I will be glad for your help!
Try below code
/**
* Discount for Local Pickup
*/
add_action( 'woocommerce_cart_calculate_fees', 'custom_discount_for_pickup_shipping_method', 10, 1 );
function custom_discount_for_pickup_shipping_method( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$percentage = 20; // Discount percentage
$chosen_shipping_method_id = WC()->session->get( 'chosen_shipping_methods' )[0];
$chosen_shipping_method = explode(':', $chosen_shipping_method_id)[0];
// Only for Local pickup chosen shipping method
if ( strpos( $chosen_shipping_method_id, 'local_pickup' ) !== false) {
// Set variable
$new_subtotal = 0;
// Set discount excluded categories list
$arr_discount_excluded_category = ['Category 1', 'Test Category'];
// Set variable for matched excluded category from the cart list
$arr_discount_excluded_category_matched = [];
// Loop though each cart items and set prices in an array
foreach ( $cart->get_cart() as $cart_item ) {
// Get product
$product = wc_get_product( $cart_item['product_id'] );
// Get product category
$category_list = wp_get_post_terms($cart_item['product_id'],'product_cat',array('fields'=>'names'));
// Product has no discount
$arr_discount_excluded_category_matched_by_item = array_intersect($category_list, $arr_discount_excluded_category);
if ( ! $product->is_on_sale() && empty($arr_discount_excluded_category_matched_by_item)) {
// line_subtotal
$line_subtotal = $cart_item['line_subtotal'];
// Add to new subtotal
$new_subtotal += $line_subtotal;
}
else{
$arr_discount_excluded_category_matched = array_merge($arr_discount_excluded_category_matched, $arr_discount_excluded_category_matched_by_item);
}
}
// Calculate the discount
$discount = 0;
if($new_subtotal > 0){
$discount = $new_subtotal * $percentage / 100;
}
//Add notification
if(!empty($arr_discount_excluded_category_matched)){
$str_message = 'Pickup discount does not apply to products from the Category "' . implode('", "', array_unique($arr_discount_excluded_category_matched)) . '"';
wc_add_notice($str_message, 'notice');
}
// Add the discount
$cart->add_fee( __('Discount') . ' (' . $percentage . '%)', -$discount );
}
}
Based my update discount will not apply Category 1, Test Category when shipping method is local_pickup and if any of those category products found from the cart list, it will show notification to customer on the success page.
Thank you.
As i can see your code, you have already used below function to get all product added in cart
/* Get product */
$product = wc_get_product( $cart_item['product_id'] );
now you just need to check that your product belongs to any of that category you want to check
i think this way you can figure out
In WooCommerce, I use the following code to set a minimum order amount:
add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_cart' , 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
$minimum = 50; // Hier gibst du den Mindestbestellwert ein
if ( WC()->cart->total < $minimum ) {
if( is_cart() ) {
wc_print_notice( sprintf( 'Der Mindestbestellwert beträgt %s pro Bestellung. Der aktuelle Bestellwert beträgt %s.' , // Text fuer Warenkorb
wc_price( $minimum ),
wc_price( WC()->cart->total )
), 'error' );
} else {
wc_add_notice( sprintf( 'Der Mindestbestellwert beträgt %s pro Bestellung. Der aktuelle Bestellwert beträgt %s.' , // Text fuer Kasse
wc_price( $minimum ),
wc_price( WC()->cart->total )
), 'error' );
}
}
}
Now if the customer chooses "self pickup" ("Local pickup shipping method), I don't want any minimum required order amount.
How can I set Minimum order amount except for "Local pickup" shipping method in WooCommerce?
Based on Getting minimum order amount for 'Free Shipping' method in checkout page answer code and also Set a minimum order amount in WooCommerce answer code, here is the correct way to set a Minimum order amount except for specific shipping method in WooCommerce:
add_action( 'woocommerce_check_cart_items', 'wc_minimum_required_order_amount' );
function wc_minimum_required_order_amount() {
// HERE Your settings
$minimum_amount = 50; // The minimum cart total amount
$shipping_method_id = 'local_pickup'; // The targeted shipping method Id (exception)
// Get some variables
$cart_total = (float) WC()->cart->total; // Total cart amount
$chosen_methods = (array) WC()->session->get( 'chosen_shipping_methods' ); // Chosen shipping method rate Ids (array)
// Only when a shipping method has been chosen
if ( ! empty($chosen_methods) ) {
$chosen_method = explode(':', reset($chosen_methods)); // Get the chosen shipping method Id (array)
$chosen_method_id = reset($chosen_method); // Get the chosen shipping method Id
}
// If "Local pickup" shipping method is chosen, exit (no minimun is required)
if ( isset($chosen_method_id) && $chosen_method_id === $shipping_method_id ) {
return; // exit
}
// Add an error notice is cart total is less than the minimum required
if ( $cart_total < $minimum_amount ) {
wc_add_notice( sprintf(
__("The minimum required order amount is %s (your current order amount is %s).", "woocommerce"), // Text message
wc_price( $minimum_amount ),
wc_price( $cart_total )
), 'error' );
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
or also you can use:
add_action( 'woocommerce_checkout_process', 'wc_minimum_required_order_amount' );
add_action( 'woocommerce_before_cart' , 'wc_minimum_required_order_amount' );
function wc_minimum_required_order_amount() {
// HERE Your settings
$minimum_amount = 100; // The minimum cart total amount
$shipping_method_id = 'local_pickup'; // The targeted shipping method Id (exception)
// Get some variables
$cart_total = (float) WC()->cart->total; // Total cart amount
$chosen_methods = (array) WC()->session->get( 'chosen_shipping_methods' ); // Chosen shipping method rate Ids (array)
// Only when a shipping method has been chosen
if ( ! empty($chosen_methods) ) {
$chosen_method = explode(':', reset($chosen_methods)); // Get the chosen shipping method Id (array)
$chosen_method_id = reset($chosen_method); // Get the chosen shipping method Id
}
// If "Local pickup" shipping method is chosen, exit (no minimun is required)
if ( isset($chosen_method_id) && $chosen_method_id === $shipping_method_id ) {
return; // exit
}
// Add an error notice is cart total is less than the minimum required
if ( $cart_total < $minimum_amount ) {
$text_notice = sprintf(
__("The minimum required order amount is %s (your current order amount is %s).", "woocommerce"), // Text message
wc_price( $minimum_amount ),
wc_price( $cart_total )
);
if ( is_cart() ) {
wc_print_notice( $text_notice, 'error' );
} else {
wc_add_notice( $text_notice, 'error' );
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I try to set a purchase limit before check out, namely:
A minimum weight requirement for the category 'formaggi'
The shop has 8 categories of products, however, the intention is to only check on 1 category.
I'm using this snippet but it doesn't work with the category,
neither for the minimum weight requirement.
/*PESO MINIMO CATEGORIA FORMAGGI 750GR - RAFFO 14mar2020*/
add_action( 'woocommerce_check_cart_items', 'cldws_set_weight_requirements' );
function cldws_set_weight_requirements() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() || is_product () && has_term( ‘formaggi’, ‘product_cart’ )) {
global $woocommerce;
// Set the minimum weight before checking out
$minimum_weight = 0.750;
// Get the Cart's content total weight per categoria
$cart_contents_weight = WC()->cart->cart_contents_weight;
// Compare values and add an error is Cart's total weight
if( $cart_contents_weight < $minimum_weight ) {
// Display our error message
wc_add_notice( sprintf('<strong>Per i Formaggi è richiesto un acquisto minimo di %s gr.</strong>'
. '<br />Peso dei Formaggi nel carrello: %s gr',
$minimum_weight*1000,
$cart_contents_weight*1000,
get_option( 'woocommerce_weight_unit' ),
get_permalink( wc_get_page_id( 'shop' ) )
), 'error' );
}
}
}
Someone who knows what I am doing wrong or where it is going wrong?
There are some mistakes in your code.
The following code checks for A minimum weight requirement for the category 'formaggi', comment with explanation added between the code lines
function cldws_set_weight_requirements() {
// Only on cart and check out pages
if( ! ( is_cart() || is_checkout() ) ) return;
/* SETTINGS */
// The minimum weight
$minimum_weight = 20; // 20 kg
// Set term (category)
$term = 'formaggi';
/* END SETTINGS */
// Set variable
$found = false;
// Total weight
$total_weight = 0;
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// Product id
$product_id = $cart_item['product_id'];
// Quantity
$product_quantity = $cart_item['quantity'];
// Get weight
$product_weight = $cart_item['data']->get_weight();
// NOT empty & has certain category
if ( ! empty( $product_weight ) && has_term( $term, 'product_cat', $product_id ) ) {
// The shopping cart contains a product of the specific category
$found = true;
// Calculate
$total_weight += $product_quantity * $product_weight;
}
}
// If the total weight is less than the minimum and there is a item in the cart from a specific category
if( $total_weight < $minimum_weight && $found ) {
// Displays a dynamic error warning
wc_add_notice( sprintf(
'The minimum weight for the "%s" category is %s, you currently have %s',
$term,
wc_format_weight($minimum_weight),
wc_format_weight($total_weight)
), 'error' );
// Removing the proceed button, until the condition is met
remove_action( 'woocommerce_proceed_to_checkout','woocommerce_button_proceed_to_checkout', 20);
}
}
add_action( 'woocommerce_check_cart_items', 'cldws_set_weight_requirements' );
This seems like it should be simple but I can't quite get there.
Goal: I need to display a notice to users when they change their shipping method if the cart total is less than the required limit.
I wrote a function in functions.php file
function min_delivery(){
//Get Chosen Shipping Method//
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
//end method
//check if they've chosen delivery
if ($chosen_shipping == 'flat_rate:2') {
//set cart minimum
$minimum = 15.00;
//get cart total - 2.00 is the delivery fee
$total = WC()->cart->total-2.00;
// check if the total of the cart is less than the minium
if ( $total < $minimum ) {
//check if it's in the cart
if( is_cart() ) {
wc_print_notice(
sprintf( 'Minimum £15.00 for Delivery' ,
wc_price( $minimum ),
wc_price( $total )
), 'error'
);
//else at checkout
} else {
wc_add_notice(
sprintf( 'Min 15.00 for Delivery' ,
wc_price( $minimum ),
wc_price( $total )
), 'error'
);
}
}//end of total less than min
//else they have pick up
} else {
//set cart minimum
$minimum = 4.50;
//get cart total - 2.00 is the delivery fee
$total = WC()->cart->total-2.00;
if ( $total < $minimum ) {
//check if it's in the cart
if( is_cart() ) {
wc_print_notice(
sprintf( 'Minimum £15.00 for Delivery' ,
wc_price( $minimum ),
wc_price( $total )
), 'error'
);
//else at checkout
} else {
wc_add_notice(
sprintf( 'Min 15.00 for Delivery' ,
wc_price( $minimum ),
wc_price( $total )
), 'error'
);
}
}//end of total less than min
}//end pickup/delivery else
}//end function
Now calling this function with the before checkout form works great
add_action( 'woocommerce_before_checkout_form' , 'min_delivery' );
However my issue is when people update the shipping on the fly, i.e choose between them. I figured there would be a hook I could use such as one of these
//add_action( 'woocommerce_checkout_process', 'min_delivery' );
//add_action( 'update_order_review' , 'min_delivery' );
//add_action( 'woocommerce_review_order_after_shipping' , 'min_delivery' );
add_action( 'woocommerce_before_checkout_form' , 'min_delivery' );
//add_action( 'woocommerce_after_checkout_shipping_form', 'min_delivery' );
//add_action('woocommerce_cart_totals_after_shipping', 'min_delivery');
However none of them do the job. When i look into the console, when updating there is an AJAX Call to ?wc-ajax=update_order_review but I couldn't seem to hook into that
I'm wandering if i'm barking up the wrong tree here and you can even amend the page through hooks and functions as PHP has already rendered?
As per the goal the whole point is to restrict order/payment for delivery where cart total is less than £15 and notify the customer of the reason.
I have revisited and tried to simplify your code. The following will add conditionally a custom information message (refreshed dynamically) in cart and checkout totals table after shipping rows:
add_action( 'woocommerce_cart_totals_after_shipping', 'shipping_notice_displayed', 20 );
add_action( 'woocommerce_review_order_after_shipping', 'shipping_notice_displayed', 20 );
function shipping_notice_displayed() {
if ( did_action( 'woocommerce_cart_totals_after_shipping' ) >= 2 ||
did_action( 'woocommerce_review_order_after_shipping' ) >= 2 ) {
return;
}
// Chosen Shipping Method
$chosen_shipping_method_id = WC()->session->get( 'chosen_shipping_methods' )[0];
$chosen_shipping_method = explode(':', $chosen_shipping_method_id)[0];
$cart_subtotal = WC()->cart->subtotal; // No need to remove the fee
// Settings
$cart_minimum1 = 4.5;
$cart_minimum2 = 15;
// HERE define the cart mininimum (When delivery is chosen)
if ( $cart_subtotal < $cart_minimum2 && $chosen_shipping_method != 'flat_rate' ) {
$cart_minimum = $cart_minimum1;
} elseif ( $cart_subtotal < $cart_minimum2 && $chosen_shipping_method == 'flat_rate' ) {
$cart_minimum = $cart_minimum2;
}
// Display a message
if( isset($cart_minimum) ){
// The message
$message = sprintf( '%s %s for Delivery' ,
is_cart() ? 'Minimum' : 'Min',
strip_tags( wc_price( $cart_minimum, array('decimals' => 2 ) ) )
);
// Display
echo '</tr><tr class="shipping info"><th> </th><td data-title="Delivery info">'.$message.'</td>';
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.