I'm facing a challenge with WooCommerce's checkout process.
I use the "B2B for WooCommerce" plugin to differentiate between regular products and B2B product. Here's the scenario:
1 - A unregistered visitor adds products from the "Regular" category (available by default to unregistered visitors) to their cart.
2 - On the checkout page, the visitor decides to register as a B2B client (by form select field on the checkout page).
3 - The registration and checkout processes occur simultaneously on this single page.
I want to prevent the order from being placed if a user is registering as a B2B client and has "Regular" products in their cart. Since both actions (registration and checkout) happen at once, typical WooCommerce hooks aren't working as expected.
How can I validate the user role being registered and the cart contents during checkout process and prevent the order if the conditions are met? Or maybe there's a better, simpler way to do this?
I've tried a function to reset the cart and reload the page.
Edit:
User Role: Wwp_wholesaler
I've created two WooCommerce product categories: Normal and Wholesale. The "Normal" one is visible to all visitors. The "Wholesale" becomes visible to "Wwp_wholesaler" after they register with that role.
The name attribute of the select field is: "afreg_select_user_role". The value attributes for the options are "customer" for regular customers and "wwp_wholesaler" for wholesalers.
The following code will early stop the checkout process when a B to B customer is detected with regular items in cart. In that case, the regular items will be removed from cart throwing an error message, avoiding placing the order.
Note: The provided user role slug is wrong, as user role slugs doesn't have capitals.
The code:
add_action( 'woocommerce_checkout_create_order', 'process_checkout_creating_order', 10, 2 );
function process_checkout_creating_order( $order, $data ) {
global $current_user;
$targeted_field = 'afreg_select_user_role'; // Checkout field key to target
$targeted_role = 'wwp_wholesaler'; // User role slug (for B to B)
$targeted_term = 'Normal'; // Category term for Regular items
// Targeting B to B user role only
if( ( isset($data[$targeted_field]) && $data[$targeted_field] === $targeted_role )
|| in_array( $targeted_role, $current_user->roles ) ) {
$cart = WC()->cart; // Cart live object
$item_keys_found = array(); // Initializing
// Loop through cart items to search for "regular" items
foreach ( $cart->get_cart() as $item_key => $item ) {
if ( has_term( $targeted_term, 'product_cat', $item['product_id']) ) {
$item_keys_found[] = $item_key;
}
}
// If regular items are found
if ( count($item_keys_found) > 0 ) {
// Loop through regular item keys (and remove each)
foreach ( $item_keys_found as $item_key ) {
$cart->remove_cart_item( $item_key );
}
// Throw an error message, avoiding saving and processing the order
throw new Exception(
sprintf( __('You are not allowed to purchase "Regular" items.'.
' %d "Regular" %s been removed from cart. %s', 'woocommerce'),
count($item_keys_found),
_n('item has', 'items have', count($item_keys_found), 'woocommerce'),
sprintf( '<a href="%s" class="button">%s</a>', get_permalink(wc_get_page_id('shop')), __('Continue shopping', 'woocommerce') )
) );
}
}
}
Code goes in functions.php file of your child theme (or in a plugin). Tested and work.