WooCommerce stores every order attempt—including incomplete and failed transactions—which can quickly clutter your database and admin dashboard if left unmanaged.
If you’ve noticed a growing number of “Pending payment” or “Failed” orders, you’re not alone. These often come from abandoned checkouts, payment interruptions, or user errors. Without cleanup, they can impact reporting accuracy and backend usability.
This guide walks through how to automatically manage and clean up these order statuses in WooCommerce.
Issue Background
A WooCommerce store was accumulating a large number of:
- Pending payment orders (abandoned or incomplete checkouts)
- Failed payment orders (unsuccessful transactions)
These orders were:
- Not being automatically deleted
- Cluttering the admin interface
- Making order management and reporting more difficult
The desired behavior was:
- Remove pending payment orders after 24 hours
- Retain failed orders for a limited time (e.g., 7 days) for reference
Diagnosis
WooCommerce does not automatically delete orders by default.
Key findings:
- Pending payment orders remain indefinitely unless manually removed or automated
- Failed orders are also retained permanently
- WooCommerce cron jobs handle some cleanup, but not order deletion
- No native setting exists to define retention periods for these statuses
Resolution Steps
1. Identify target order statuses
WooCommerce uses specific order statuses:
pending→ created but not paidfailed→ payment attempt unsuccessful
2. Create a scheduled cleanup function
You can use WordPress cron (wp_cron) to automate deletion.
add_action('init', function() {
if (!wp_next_scheduled('cleanup_old_orders')) {
wp_schedule_event(time(), 'hourly', 'cleanup_old_orders');
}
});
add_action('cleanup_old_orders', function() {
$args = [
'limit' => -1,
'status' => ['pending', 'failed'],
];
$orders = wc_get_orders($args);
foreach ($orders as $order) {
$created = strtotime($order->get_date_created());
$now = time();
// Delete pending orders older than 24 hours
if ($order->get_status() === 'pending' && ($now - $created) > 86400) {
wp_delete_post($order->get_id(), true);
}
// Delete failed orders older than 7 days
if ($order->get_status() === 'failed' && ($now - $created) > 604800) {
wp_delete_post($order->get_id(), true);
}
}
});
3. Adjust retention timing as needed
86400seconds = 24 hours604800seconds = 7 days
Adjust these values depending on your store’s needs.
4. Test in a staging environment
Before deploying:
- Verify orders are deleted correctly
- Confirm no valid orders are affected
- Monitor cron execution using tools like WP Crontrol
5. Consider plugin-based alternatives
If you prefer a no-code solution, some plugins offer similar functionality, but custom code provides more control.
Final Outcome
- Pending payment orders are removed after 24 hours
- Failed orders are retained briefly, then cleaned up
- Admin dashboard is significantly cleaner
- Reporting accuracy improves
- Database size is reduced over time
This approach keeps WooCommerce running efficiently without losing access to short-term transaction data when needed.
Need help optimizing WooCommerce performance?
Managing order data, automating cleanup, and customizing WooCommerce behavior can significantly improve performance and usability.
If your store is dealing with cluttered orders or complex workflows, Freshy can help implement tailored solutions.