WooCommerce: Allowing a Customer to Cancel an Order
In this slightly unusual case, we’re looking at allowing a customer to cancel an order for an extended period of time OR based on other specialized criteria. When building this out, the documentation can be a bit confusion on WooCommerce.
Below, we’ll use a filter in WooCommerce to set up specialized criteria for allowing customers to cancel their order.
The Basic Filter
First, let’s cover the basic filter. You’ll add this into your functions.php file on your theme (or child theme).
add_filter( 'woocommerce_valid_order_statuses_for_cancel', 'filter_valid_order_statuses_for_cancel', 20, 2 ); function filter_valid_order_statuses_for_cancel( $statuses, $order ){ $custom_statuses = array( 'pending', 'processing', 'on-hold', 'failed' ); $canChange = 1; //your custom criteria if ( $canChange == 1 ) { return $custom_statuses; } else { return $statuses; } }
A big thank you to LoicTheAztec for the basic setup.
The filter starts with calling the function “filter_valid_order_statuses_for_cancel”, just like other filters. There are two items being passed here: the $order variable which contains the order and the $statuses available.
Originally when I came across this filter, I thought it was talking about which statuses are SHOWN on the checkout page, but that’s not correct. This filter tells WooCommerce which order statuses it is allowed to cancel. Here’s how it thinks:
Person clicks Cancel button > WooCommerce checks order status > declines to cancel if the order status doesn’t match
We’re interrupting that process by changing which order statuses allow cancellation and possibly adding in our own criteria.
Still confused? Keep reading our example cases below.
Example Cases
Allow WooCommerce orders to be cancelled regardless of status:
add_filter( 'woocommerce_valid_order_statuses_for_cancel', 'filter_valid_order_statuses_for_cancel', 20, 2 ); function filter_valid_order_statuses_for_cancel( $statuses, $order ){ $custom_statuses = array( 'pending', 'processing', 'on-hold', 'failed' ); return $custom_statuses; }
Allow WooCommerce orders to be cancelled IF the order is on-hold only:
add_filter( 'woocommerce_valid_order_statuses_for_cancel', 'filter_valid_order_statuses_for_cancel', 20, 2 ); function filter_valid_order_statuses_for_cancel( $statuses, $order ){ $custom_statuses = array('on-hold'); return $custom_statuses; }
Allow WooCommerce orders to be cancelled regardless of status, if it’s within 24 hours:
add_filter( 'woocommerce_valid_order_statuses_for_cancel', 'filter_valid_order_statuses_for_cancel', 20, 2 ); function filter_valid_order_statuses_for_cancel( $statuses, $order ){ $custom_statuses = array( 'pending', 'processing', 'on-hold', 'failed' ); $delay = 24*60*60; // (duration in seconds) $date_created_time = strtotime($order->get_date_created()); // Creation date time stamp $date_modified_time = strtotime($order->get_date_modified()); // Modified date time stamp $now = strtotime("now"); // Now time stamp if ( ( $date_created_time + $delay ) >= $now ){ return $custom_statuses; } else { return $statuses; //returns original statuses if the delay is over 24 hours. } }
A big thank you to LoicTheAztec for this last example.
Summary
You can add in any criteria you’d like for your cancellation system using this filter. The sky’s the limit!