When I click the "Place Order" button on the checkout page, I would like to re-check my cart for any product that is not supposed to be included in the order. If a matching product is found, I would like to remove that product from the cart, tell the user that the item has been removed, and the order should not proceed. This is my code:
function cart_remove_retail_only_products($errors) {
if (WC()->cart->is_empty()) {
return;
}
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
$productRetailOnly = $_product->get_meta('retail_only');
if (!$productRetailOnly) {
continue;
}
WC()->cart->remove_cart_item($cart_item_key);
throw new Exception( __("Your are using a wholesale coupon but your cart contains a retail only product. The item has been removed from your cart.") );
}
}
add_action('woocommerce_checkout_create_order', 'cart_remove_retail_only_products');
The above function successfully removes matching product(s) from the cart but this is what I see after I click the "Place Order" button.
As you can see, the product "Sample Retail Only Product" is still displayed. But the product isn't actually there anymore. If I refresh the page, this is what I see:
I realized my requirements cannot be achieved by using woocommerce_checkout_create_order
so I ended up using these hooks instead:
woocommerce_add_to_cart
- checks a product when adding to cart
woocommerce_applied_coupon
- checks when a coupon is applied to cart