I need to add two different shipping rates, depending on the role of the user making the purchase. I have a role that is 'wholesale_customer' and should not pay shipping costs. However, the purchase must be prevented and a message added at Checkout if the subtotal of the cart is equal to or less than €90. (remember that you must reach the amount of €90)
The other option is all other WordPress roles, who are required to pay €5 shipping if their cart subtotal is €40 or less.
I have configured shipping in WooCommerce, I have created two free shipping methods with a minimum order amount, one of €40 and another of €90.
The problem is that the user with the 'wholesale_customer' role, when he reaches the amount of €40, is also enabled for that free shipping method, which should not happen, since for this user role ('wholesale_customer ' ) shipping is free, if the purchase exceeds the minimum of €90.
I have configured the shipments in WooCommerce in the following way, creating 2 Shipping Methods: - one has "Minimum Quantity Required" at €90
another has "Minimum Quantity Required" at €40
and one of shipping costs at €0.
I have tried to add the following function to add to get what I need, but all the shipping methods are always enabled, so the retail shipping method of "Minimum €40 for free shipping", is also activated for the user with the role wholesale_customer' This should not happen, as users with this role would benefit from benefits that are not theirs.
I'm showing some of the code I've used to try to do what I'm looking for, since I did a lot of testing. Only I have not had the way to add the text that I mention in the presentation for the role 'wholesale_customer' Show images of WooCommerce setup
function custom_shipping_methods_visibility( $available_methods ) {
$subtotal = WC()->cart->subtotal;
$user = wp_get_current_user();
$user_roles = $user->roles;
// Check user role and cart subtotal to show/hide shipping methods
if ( in_array( 'wholesale_customer', $user_roles ) && $subtotal <= 70 ) {
unset( $available_methods['flat_rate:13'] );
} elseif ( $subtotal <= 30 ) {
unset( $available_methods['flat_rate:9'] );
}
return $available_methods;
}
add_filter( 'woocommerce_package_rates', 'custom_shipping_methods_visibility', 10, 1 );
////////////////////
// Adds a custom function to filter shipping methods based on cart role and subtotal
function custom_shipping_methods( $available_methods ) {
// Get cart subtotal
$subtotal = WC()->cart->subtotal;
// Gets the role of the current user
$user = wp_get_current_user();
$user_roles = $user->roles;
//Check user role and cart subtotal to adjust shipping methods
if ( in_array( 'wholesale_customer', $user_roles ) && $subtotal < 70 ) {
foreach ( $available_methods as $method_id => $method ) {
// Hide the shipping methods if the user is a wholesaler and the subtotal is less than €70
unset( $available_methods[ $method_id ] );
}
// Show a warning message
wc_add_notice( 'Debes alcanzar un mínimo de 70€ en tu carrito para realizar el pedido.', 'error' );
}
return $available_methods;
}
add_filter( 'woocommerce_package_rates', 'custom_shipping_methods', 10, 1 );
config-1
Config-2 :
Config-3 :
Updated
First, to prevent "wholesale_customer" user placing an order if cart subtotal is less than €90, the following code will:
// Conditional function: Is user a Wholesale Customer
function is_a_wholesale_customer() {
if ( ! is_user_logged_in() ) return false;
return (bool) in_array( 'wholesale_customer', wp_get_current_user()->roles );
}
// Conditional function: Is user a (normal) Customer
function is_a_normal_customer() {
if ( ! is_user_logged_in() ) return false;
return (bool) in_array( 'customer', wp_get_current_user()->roles );
}
// Conditional function: Is "wholesale_customer" allowed to order
function is_wholesale_customer_allowed_to_order() {
// Check "wholesale_customer" user role and required subtotal
return is_a_wholesale_customer() && WC()->cart->subtotal < 90 ? false : true;
}
// The notice text (for "wholesale_customer")
function wholesale_customer_text_error_notice(){
return __('Please remember that you must reach an amount of €90', 'woocommerce');
}
// Notice reminder based on required subtotal (for "wholesale_customer")
add_action( 'woocommerce_before_cart', 'check_cart_subtotal_wholesale_customer' ); // cart
add_action( 'woocommerce_before_checkout_form', 'check_cart_subtotal_wholesale_customer' ); // checkout
function check_cart_subtotal_wholesale_customer() {
if ( ! is_wholesale_customer_allowed_to_order() ) {
wc_print_notice( wholesale_customer_text_error_notice() );
}
}
// Checkout validation based on required subtotal (for "wholesale_customer")
add_action( 'woocommerce_checkout_process', 'wholesale_customer_checkout_validation' );
function wholesale_customer_checkout_validation() {
if ( ! is_wholesale_customer_allowed_to_order() ) {
wc_add_notice( wholesale_customer_text_error_notice(), 'error' ); // Displays an error notice
}
}
For the shipping methods, your settings are correct.
The following code will show / hide shipping methods based on your user roles ("wholesale_customer" and "customer" (adding unlogged users too) and a minimum cart subtotal amount for free shipping.
Update: The code works now with unlogged user (just as "customer" user role)
For the "wholesale_customer" all shipping methods will be disabled, until cart subtotal reaches €90.
When free shipping will be available, all other shipping methods will be hidden.
For each of your 2 free shipping methods, you will need to get the correct shipping rate ID.
With a cart subtotal higher than €90, on your checkout page shipping section, inspect the displayed radio buttons for each free shipping displayed option (see the screenshot below):
Now you can set in the code below both of your 2 free shipping methods rate IDs:
// showing / Hidding shipping methods
add_filter( 'woocommerce_package_rates', 'filter_shipping_package_rates', 10, 2 );
function filter_shipping_package_rates( $rates, $package ) {
// Settings
$free_rate_ids = array(
'wholesale_customer' => 'free_shipping:2', // Here set the free shipping rate ID for wholesale user
'customer_or_unlogged' => 'free_shipping:3', // Here set the free shipping rate ID for customer or unlogged user
);
$error_data['all_rates'] = array_keys($rates);
// "Wholesale" user role
if ( is_a_wholesale_customer() ) {
$key = 'wholesale_customer';
// show only "Wholesale" free shipping when available
if( isset($rates[$free_rate_ids[$key]]) ) {
return array( $free_rate_ids[$key] => $rates[$free_rate_ids[$key]] );
}
// Hide all shipping methods (no free shipping available)
else {
return array();
}
}
// "Customer" user role or unlogged users
else {
$key = 'customer_or_unlogged';
// show only "Normal" free shipping when available
if( isset($rates[$free_rate_ids[$key]]) ) {
return array( $free_rate_ids[$key] => $rates[$free_rate_ids[$key]] );
}
}
return $rates;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Once the code is saved, to refresh shipping methods cached data, don't forget to empty your cart (or disable, save and enable, save related shipping methods for the current shipping zone, in Woocommerce shipping settings).