I’m trying to automatically cancel all processing WooCommerce orders that are not finalized within 30 days since order is created. The code below does not break the site but it doesn’t do anything. How can I fix it?
// Scheduled event to run daily
function cwpai_mark_cancelled_orders() {
// Get all processing orders older than 30 days
$args = array(
'numberposts' => -1,
'post_status' => 'wc-processing',
'date_query' => array(
'column' => 'post_modified_gmt',
'before' => '30 days ago',
),
);
$orders = get_posts($args);
// Loop through each order and mark it as cancelled
if ($orders) {
foreach ($orders as $order) {
wp_update_post(array(
'ID' => $order->ID,
'post_status' => 'wc-cancelled',
));
}
}
}
// Schedule the event
function cwpai_schedule_cancelled_orders_event() {
if (!wp_next_scheduled('cwpai_mark_cancelled_orders_event')) {
wp_schedule_event(time(), 'daily', 'cwpai_mark_cancelled_orders_event');
}
}
add_action('wp', 'cwpai_schedule_cancelled_orders_event');
// Hook into the scheduled event to run the function
function cwpai_run_cancelled_orders_event() {
cwpai_mark_cancelled_orders();
}
add_action('cwpai_mark_cancelled_orders_event', 'cwpai_run_cancelled_orders_event');
2
Answers
Firstly, include this
'post_type' => 'shop_order'
, within the arguments of the get_posts function. Additionally, take note that you’re utilizing'column' => 'post_modified_gmt'
within the date_query. If your WC-order has been updated, you might not observe any changes. You can modify this to'column' => 'post_date_gmt'
. However, this could prevent your orders from being saved, even if they are updated. Another approach is to consider the following code snippet to update the modified date in the admin panel:To verify, I recommend using this code:
wp_clear_scheduled_hook( 'cwpai_mark_cancelled_orders_event' );
. This enables you to bypass the one-day wait. However, remember to delete this code after finishing of tests. Furthermore, I advise utilizing the plugin WP Crontrol which grants visibility into all cron tasks.Finally, your primary code should resemble the following:
To auto cancel old processing orders (> 30 days), you don’t need any scheduler, and WordPress scheduled actions (cron jobs) are known to be not reliable.
That’s why WooCommerce, WooCommerce Subscription and all serious plugins uses Action Scheduler library, that is a scalable, traceable job queue for background processing.
Your code is a bit outdated, as WooCommerce is progressively migrating to custom database tables, for better performances. So for orders it’s recommended to use WC_Order_query instead of WP_Query and CRUD available methods instead of WordPress functions.
Try the following instead, that will auto cancel old processing orders (> 30 days) daily, and will send an email notification with the cancelled orders (if there were any to cancel):
Code goes in functions.php file of your child theme (or in a plugin). Tested and works.