Search code examples
woocommercehook-woocommerce

WooCommerce WC()->cart->remove_cart_item works but page needs to be refreshed to see that the item has been removed


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.

enter image description here

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:

enter image description here


Solution

  • 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