Search code examples
woocommerce

How force to empty cart inside action: woocommerce_order_status_changed


I need to force to empty (clear) the cart from inside the hook woocommerce_order_status_changed

I tried this code but it is not working. No errors but it doesn't work. What am I missing here?

Should I grab and use the current user id?

UPDATE: This only happens in orders where the amount to pay is 0€ due to a discount rule. Maybe this is the reason why woocommerce does not clear the cart.

add_action('woocommerce_order_status_changed', 'so_status_completed', 10, 3);

function so_status_completed($order_id, $old_status, $new_status){ 

    if($new_status == 'processing' || $new_status == 'on-hold'){
     
         global $woocommerce;
        $woocommerce->cart->empty_cart();
           
        WC()->cart->empty_cart(true);
        WC()->session->set('cart', array());

    }
}

@LoicTheAztec: I also tried with this in functions.php but neither is working.

add_action('woocommerce_new_order','clear_the_cart');

function clear_the_cart() 
{
    global $woocommerce;
    $woocommerce->cart->empty_cart();
    WC()->cart->empty_cart();
}

Solution

  • You can't access cart as it is a live object on client side (cookie / session), so $woocommerce->cart or WC()->cart is always null under woocommerce_order_status_changed hook.

    Note that when an order is placed, the cart is automatically emptied, apparently except when the amount to pay is 0€.

    If the amount to pay is 0€ and the cart has not been emptied, you can try the following to empty the cart:

    add_action( 'woocommerce_checkout_order_created', 'empty_cart_for_orders_with_zero_amount' );
    function empty_cart_for_orders_with_zero_amount( $order ) {
        if ( WC()->cart && ! WC()->cart->is_empty() && WC()->cart->get_total('') == 0 ) {
            WC()->cart->empty_cart();
        }
    }
    

    It should work.