Nicola Mustone

Happiness Lead @ Automattic

Delete Expired Coupons Automatically

Update 30 October 2023: Script tested and confirmed working on WooCommerce 8.2.1.

Coupons are amazing, who does not like a discount? A very common way to give coupons to customers is to create one automatically after their first order, or something like that.

The issue with that though is that usually these coupons expire after a specific period, and by default, WooCommerce will not delete them. They have no reason to stay in your database though, so how do we delete expired coupons automatically?

With a snippet of course.

Before implementing any code changes, always ensure your site is backed up. This will help you restore things in case of unforeseen errors. I recommend using Jetpack Backup for real-time backups and one-click restores.

Open your functions.php file in wp-content/themes/your-child-theme-name/ and add this code at the end of the file:

// Delete Expired Coupons that have an expiration date set and are not from AutomateWoo
add_action('delete_expired_coupons_hook', 'delete_expired_coupons_action');
function delete_expired_coupons_action() {
$query_args = [
'fields' => 'ids',
'post_type' => 'shop_coupon',
'post_status' => 'any',
'posts_per_page' => –1,
'orderby' => 'date',
'order' => 'ASC',
'no_found_rows' => true,
'meta_query' => [
'key' => 'date_expires',
'value' => '',
'compare' => '!='
'key' => '_is_aw_coupon',
'value' => false,
'key' => 'date_expires',
'value' => current_time( 'timestamp' ),
'compare' => '<',
$query = new \WP_Query($query_args);
$coupons = $query->posts;
if (!empty($coupons)) {
foreach ($coupons as $coupon_id) {
// Schedule the Deletion (If Not Already Scheduled)
add_action('init', 'schedule_delete_expired_coupons');
function schedule_delete_expired_coupons() {
if (!wp_next_scheduled('delete_expired_coupons_hook')) {
wp_schedule_event(time(), 'daily', 'delete_expired_coupons_hook');
// Manual Deletion Button in Marketing > Coupons
add_action('restrict_manage_posts', 'custom_add_delete_expired_button', 99);
function custom_add_delete_expired_button() {
global $typenow;
if ('shop_coupon' === $typenow) {
<form method="post" style="display:inline;">
<input type="hidden" name="custom_action" value="delete_expired_coupons">
<?php wp_nonce_field('custom_delete_expired_coupons', 'custom_delete_nonce'); ?>
<input type="submit" class="button" value="Delete Expired Coupons" onclick="return confirm('Are you sure you want to delete all expired coupons?');" />
// Display a notice if expired coupons were deleted.
if (isset($_REQUEST['custom_deleted']) && $_REQUEST['custom_deleted'] === 'true') {
echo '<div class="updated"><p>Expired coupons deleted successfully.</p></div>';
// Redirect with a message after deletion.
add_action('admin_init', 'custom_delete_expired_coupons');
function custom_delete_expired_coupons() {
if (isset($_REQUEST['custom_action']) && $_REQUEST['custom_action'] === 'delete_expired_coupons' && check_admin_referer('custom_delete_expired_coupons', 'custom_delete_nonce')) {
wp_redirect(add_query_arg(['custom_deleted' => 'true'], admin_url('edit.php?post_type=shop_coupon')));
view raw functions.php hosted with ❤ by GitHub

This snippet will automatically move to the Trash all the expired coupons in your store so you can go and delete them permanently with one click, regardless if they have been used or not.

If you want to permanently delete the coupons directly instead of trashing them, you can change this code:

wp_trash_post( $coupon->ID );

to this:

wp_delete_post( $coupon->ID, true );

but beware that once you permanently delete a coupon it cannot be recovered.

Note that it works on WordPress cron jobs. If you disabled them or for any reason, they are not working, this snippet will not work as well.

It will also add a Delete Expired Coupons button in Marketing > Coupons. Beware though, this button might run into timeout issues if you have too many coupons to delete!


Subscribe to This Blog

Receive new articles from this blog directly in your inbox! No spam guaranteed!

Join 651 other subscribers

Contribute to Improving This Blog

Did you enjoy this article? Was it helpful? Contribute to help me write more articles! The funds collected from this blog are reinvested directly into improving my skills or the blog so that I can provide more and better content!


Make a one-time donation

Make a monthly donation

Make a yearly donation

Choose an amount


Or enter a custom amount

Your contribution is appreciated.

Your contribution is appreciated.

Your contribution is appreciated.

DonateDonate monthlyDonate yearly

More Posts That You Might Like…

9 responses to “Delete Expired Coupons Automatically”

  1. Will this delete expired coupons that have been used?

  2. Hi there. I have the same issue here, the snippet should not delete expired by date coupons but already used coupons. Any ideas in that?
    Thank you so much in advance!

  3. This snipped haven’t worked for me. I have added it as Snipppet (executed once) but without effect. Still having over 40’000 coupons in the system (the most of them are expired).

  4. Thanks 4 sharing

  5. will this work?

    1. Yes, I tested it now on WooCommerce 4.9.2 and I updated the article with the most updated version of this script.

  6. Hi Nicola,

    your script is not working for us. WordPress 5.7.2 + Woocommerce 5.4.1. I really hope it can be fixed, we desperately need this functionality.

    Kind regards,

  7. This code is outdated. Its not working because WooCoommerce has changed a way how some data is stored in the database.

    I have created GIST with updated solution which is tested and its working ⬇️

    1. Thank you! I also updated the script today and added a new button to manually trigger the deletion. The code in this article is no longer outdated, and tested with WooCommerce 8.2.1.

Leave a Reply




Receive new articles from this blog directly in your inbox!

No spam guaranteed!

Join 651 other subscribers

About The Author

Hi, I’m Nico! Support Lead at Automattic, championing & WooCommerce. Off-duty, I’m at Elemental Beacon, leading epic D&D adventures. Let’s connect, whether it’s about WordPress or a quest!


Don't Miss a Thing!

Receive new articles from this blog directly in your inbox!

No spam guaranteed!

Join 651 other subscribers

Continue Reading

%d bloggers like this: