
Heads up! The article involves PHP codes and is intended for developers. If you’re looking for a built-in plugin that automatically delete older orders, you can simply download the plugin.
Woocommerce auto delete old orders
Would you like to automatically delete old WooCommerce orders? Old orders might be redundant and consume memory in your database. So, it’s a wise move to remove all redundant orders from the WordPress database. You can manually delete the old orders, but it takes time and is a hassle every day for you.
Let’s create a brand new plugin to delete old orders from WooCommerce automatically. So, it’s once set and forget.
We will start with creating a folder “wc-auto-delete-old-orders” and a plugin main file “wc-auto-delete-old-orders.php”. So, the structure would be wp-content/plugins/wc-auto-delete-old-orders/wc-auto-delete-old-orders.php.
<?php
/**
* Plugin Name: WC Auto Delete Old Orders
* Description: Automatically delete old redundant orders from the database.
* Version: 1.0.0
* Author: Sanjeev Aryal
* Author URI: https://www.sanjeebaryal.com.np
* Text Domain: wc-auto-delete-old-orders
*/
defined( 'ABSPATH' ) || die();
/**
* Plugin constants.
*
* @since 1.0.0
*/
define( 'WC_AUTO_DELETE_OLD_ORDERS_PLUGIN_FILE', __FILE__ );
define( 'WC_AUTO_DELETE_OLD_ORDERS_VERSION', '1.0.0' );
require_once __DIR__ . '/action-scheduler/action-scheduler.php';
require_once __DIR__ . '/src/Plugin.php';
/**
* Return the main instance of Plugin Class.
*
* @since 1.0.0
*
* @return Plugin.
*/
function wc_auto_delete_old_orders() {
$instance = \WcAutoDeleteOldOrders\Plugin::get_instance();
$instance->init();
return $instance;
}
wc_auto_delete_old_orders();
In the above file (wc-auto-delete-old-orders.php), you can see we’re requiring an Action Scheduler. Action Scheduler is a library developed by WooCommerce itself. If you want to know more about it, here’s scheduling the tasks with Action Scheduler. Basically, it processes the tasks in the background. Likewise, we’re going to automatically delete old users in the background, like a cron job in WordPress.
So, to include the Action Scheduler, download the latest zip file from the Action Scheduler Github Releases. Here’s a screenshot to download. We’re downloading the latest version 3.4.2 as of now.

Once, we download the action-scheduler.zip, let’s extract it on our plugin’s folder. So, our plugins structure would be:wp-content
- — wp-content
- — plugins
- — wc-auto-delete-old-orders
- — action-scheduler
- — wc-auto-delete-old-orders.php
- — wc-auto-delete-old-orders
- — plugins
That’s all we do with Action Scheduler. You probably noticed that we require another file src/Plugin.php. So, our full plugin’s files and folder structure would be like this:

Now we write all the functionality of the plugin in src/Plugin.php. Let’s start with the basic.
<?php
namespace WcAutoDeleteOldOrders;
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
/**
* Plugin Class.
*
* @since 1.0.0
*/
final class Plugin {
/**
* Instance of this class.
*
* @var object
*/
protected static $instance = null;
/**
* Return an instance of this class.
*
* @return object A single instance of this class.
*/
public static function get_instance() {
// If the single instance hasn't been set, set it now.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Initialize.
*/
public function init() {
// To be filled. See below.
}
}
We’ll write all the hooks inside the init() method. Let’s add a background action to check for old orders every day. So, in the init() method, let’s add:
add_action( 'init', [ $this, 'schedule_delete' ] );
The callback function:
/**
* Schedule the delete process.
*
* @since 1.0.0
*/
public function schedule_delete() {
if ( false === as_next_scheduled_action( 'wc_delete_old_orders_process' ) ) {
as_schedule_recurring_action( strtotime( '+ 1 day' ), DAY_IN_SECONDS, 'wc_delete_old_orders_process', array(), 'wc_delete_old_orders' );
}
}
This means, there’s an action “wc_delete_old_orders_process” that triggers daily. You can see the task by going to the URL: https://example.com/wp-admin/tools.php?page=action-scheduler&s=wc_delete_old_orders_process
Here’s a screenshot for quick reference:

The final step is to hook into this action and perform the deletion. This means the core functionality of the plugin relies here on. Let’s add this on init()
method of Plugin.php same as above.
add_action( 'wc_delete_old_orders_process'. [ $this, 'process_delete' ] );
and the callback function:
/**
* Process Delete.
*
* @since 1.0.0
*/
public function process_delete() {
if ( ! function_exists( 'wc_get_orders' ) ) {
return;
}
$args = array(
'date_created' => '<' . ( time() - 3 * MONTH_IN_SECONDS ),
);
$orders = \wc_get_orders( $args );
foreach ( $orders as $order ) {
\wp_delete_post( $order->get_id() );
}
}
The above method deletes all the orders created 3 months ago. You can customize the date as per your requirement or preference. To my requirement, I don’t need orders older than 3 months ago. Heads up! the orders aren’t recoverable once deleted. So, proceed with caution and make sure you have your daily site backup.
That’s all. You can also see the full source code in the GitHub Repository.
Have you ever wondered why your WooCommerce orders are stuck at processing? Here’s why.
I’m using the plugin, but it only deletes 3 orders per action.
How should I delete all orders for these 3 months?
Hi Carlos, if you have so many old orders, the PHP script will time out before it could delete all order at once. Maybe you can just run the process in a 5 minutes interval than in a day?
Hope that will help!
hi? how are you?
i need help trying to implement this code to bookings of woocommerce
”
heres is the code:
”
public function process_delete() {
if ( ! function_exists( ‘get_wc_booking’ ) ) {
return;
}
$args = array(
‘date’ => ‘update_status(‘completed’);
\wp_update_post( $booking ->get_id() );
}
}
}
“”
and this is the order code thats work
“”
public function process_delete() {
if ( ! function_exists( ‘wc_get_orders’ ) ) {
return;
}
$args = array(
‘date_created’ => ‘update_status(‘completed’);
\wp_delete_post( $order->get_id() );
}
}
“”
I don’t know what’s wrong, if it’s a misspelled function or what.
Hi Julian, thanks for reaching out. Unfortunately, it’s hard to debug without details on the booking plugin you’re using.