Skip to content
Advertisement

Remove product after an order has been placed in WooCommerce

I’m using the most recent versions of WordPress and WooCommerce.

I’m aware this might seem weird out of context, but I wanna add a hook to my functions.php that removes a certain product by ID from an order after the order has been placed.

Here is what I am working with so far:

add_action('woocommerce_new_order', 'custom_process_order', 10, 1);
function custom_process_order($order_id) {
    $order = new WC_Order( $order_id );
    $items = $order->get_items();
    foreach ($items as $item) {
        if ($item->get_id()==10766) {
          $order->remove_item( $item->get_id() );
        }
    }
    return $order_id;
}

I am trying to remove the product with the ID 10766 from the order if said product is part of the order. I took this from a different, older post here so the code itself might not be perfect. It definitely isn’t working.

Update after some experimentation:
With the help of Cameron Hurd, I tried the following code:

add_action('woocommerce_new_order', 'custom_process_order', 10, 1);

function custom_process_order($order_id) {
    $order = new WC_Order( $order_id );
    $items = $order->get_items();
    foreach ($items as $item) {
        if ($item->get_id() === 10766) {
            $order->remove_item( $item->get_id() );
        }
    }

    $order->save_items();

    return $order_id;
}

This seemed promising, but pressing the checkout button will submit an empty order while also throwing an empty WooCommerce error message leaving the user on the checkout page.

After this I had 2 ideas:
1.) Changing remove_item to wc_delete_order_item. I really don’t know the difference and changing it didn’t seem to make a difference either.
2.) Changing the hook so it happens after the order is in the back end. I tried changing it from woocommerce_new_order to woocommerce_thankyou. This however broke the thank you page in addition to doing nothing to the order.

This is what I’m sitting with now:

add_action('woocommerce_checkout_create_order', 'custom_process_order', 10, 1);

function custom_process_order($order_id) {
    $order = new WC_Order( $order_id );
    $items = $order->get_items();
    foreach ($items as $item) {
        $current_item_id = $item->get_id();
        if ( $current_item_id === 10766) {
            $order->remove_item($current_item_id);
        }
    }

    $order->save_items();

    return $order_id;
}

Still looking for a working answer.

Advertisement

Answer

You could use the woocommerce_checkout_order_processed action hook, where you then specify the product id.

So you get:

function custom_process_order( $order_id ) {
    if( ! $order_id ) return;

    // get order object
    $order = new WC_Order( $order_id );
    
    // get order items = each product in the order
    $items = $order->get_items();

    foreach ( $items as $item ) {
        $product = wc_get_product( $item['product_id'] );
        
        if ( $product->get_id() == 10766 ) {
            $order->remove_item( $item->get_id() );
        }
    }
    
    // Calculate
    $order->calculate_totals();
    
    // Save
    $order->save();
}
add_action( 'woocommerce_checkout_order_processed', 'custom_process_order', 10, 1 );
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement