While WooCommerce contains tons of helper functions, such as functions that will give you all “on sale” products, there’s no function in WooCommerce that will return all coupons present within a shop. This is because there’s a pretty easy way to query them yourself because coupons are their own custom post type: the shop_coupon post type.

This means that we can simply query all posts for that post type to get a list of WooCommerce coupons present in the shop. You could do this for any post type created by WooCommerce, such as orders or products, as well.

Get All Posts for a WordPress Post Type

The key function we’ll need to use here is get_posts(). This will give you an array of all post objects for the post type specified. You can use several parameters with get_posts() to query the posts desired, which the WordPress Codex covers.

One parameter to which I’d recommend paying attention is post_per_page, as this will determine how many results you get. The default number of posts returned is 5, but since I want to query all coupons (there shouldn’t be so many that this will be a massive request), I’ll change my posts per page to -1 to get all results. To be technically correct, we should use nopaging => true instead, but I’ve never seen this in the wild.

We’ll create an array of all arguments to use for the parameters, then name this array $coupons.

$args = array(
    'posts_per_page'   => -1,
    'orderby'          => 'title',
    'order'            => 'asc',
    'post_type'        => 'shop_coupon',
    'post_status'      => 'publish',
);
    
$coupons = get_posts( $args );

This will return an array of all coupon posts in the shop based on our arguments / parameters. We’re only including “published” coupons (no drafts or pending coupons), and we’re sorting them by name. This will include data such as the coupon code (post title), description (post excerpt), author, and when it was published.

Here’s a sample of what some of that data will look like if we were to dump it:

Array
(
    [0] => WP_Post Object
        (
            [ID] => 175
            [post_author] => 1
            [post_date] => 2015-01-05 19:09:33
            [post_date_gmt] => 2015-01-06 00:09:33
            [post_content] => 
            [post_title] => 10off
            [post_excerpt] => Gives 10 percent discount on all cart contents
            [post_status] => publish
            [comment_status] => closed
            [ping_status] => closed
            [post_password] => 
            [post_name] => 10off
            [to_ping] => 
            [pinged] => 
            [post_modified] => 2015-01-15 11:02:31
            [post_modified_gmt] => 2015-01-15 16:02:31
            [post_content_filtered] => 
            [post_parent] => 0
            [guid] => http://store.com/?post_type=shop_coupon&p=175
            [menu_order] => 0
            [post_type] => shop_coupon
            [post_mime_type] => 
            [comment_count] => 0
            [filter] => raw
        )

    [1] => WP_Post Object
        (
            [ID] => 174
            [post_author] => 1
            [post_date] => 2015-03-05 18:50:47
            [post_date_gmt] => 2015-03-05 23:50:47
            [post_content] => 
            [post_title] => shipidea
            [post_excerpt] => Enables free shipping for the order
            [post_status] => publish
            [comment_status] => closed
            [ping_status] => closed
            [post_password] => 
            [post_name] => shipidea
            [to_ping] => 
            [pinged] => 
            [post_modified] => 2015-03-05 18:53:47
            [post_modified_gmt] => 2015-03-05 23:53:47
            [post_content_filtered] => 
            [post_parent] => 0
            [guid] => http://store.com/?post_type=shop_coupon&p=174
            [menu_order] => 0
            [post_type] => shop_coupon
            [post_mime_type] => 
            [comment_count] => 0
            [filter] => raw
        )
);

Each coupon in the shop is included in the array, and some key data about each post is present in its own array.

Get and Use the Needed Post Meta

Now you didn’t get this data for your health, right? You probably want to use it for something.

In my case, I want to display a list of coupon codes for all published WooCommerce coupons. My finished product will be a plugin that lets us filter the “Orders” screen based on which coupon was used, of which this code is a part.

Since I’ve already got an array of all coupons in the shop, I can loop through the array for each coupon, and get the information I need. As we saw in the raw data above, the coupon code is stored as the post title, so we’ll (1) loop through all coupons, (2) get the title for the coupon post object, and (3) push these post titles into a new array.

I’ll create an array called $coupon_names, and push each title into it:

$coupon_names = array();
foreach ( $coupons as $coupon ) {
    // Get the name for each coupon post
    $coupon_name = $coupon->post_title;
    array_push( $coupon_names, $coupon_name );
}

Now my $coupon_names array only contains a title for each coupon present in the shop. The raw data for that array looks like this:

Array
(
    [0] => 10off
    [1] => shipidea
    [2] => spring2015
    [3] => thankshank
)

We can use this array of coupon titles as we see fit now — to check if a coupon exists, if it’s used in an order, if a particular customer has used it, etc. In my case, I was using it to create a filtering option on the “Orders” screen, and then added a query to see if an order had used that coupon code. Here’s what the finished product looked like:

WooCommerce Filter Orders by Coupon used

Advanced Usage: Access the Coupon Object

If you need to do more with the coupon, such as access more data about it (like expiration date), you can instantiate a new coupon object based on the title:

new WC_Coupon( $coupon->post_title );

This gives you more freedom in how you can use the coupon data, and you could do things like check for the coupon type, check if the coupon enables free shipping (which you could then use to only filter orders by whether they contain a free shipping coupon or not), only include valid (not expired) coupons, or more. I’d recommend checking out the WC_Coupon class for other methods you can use with the coupon object.

Filter Orders by Coupon Plugin

Since I already did the work for this, here’s the finished plugin on GitHub which you can use to look over the code, or install it to filter your WooCommerce orders by coupon used in the order.

Download Filter Orders by Coupon

Published by Beka Rice

Beka leads product direction for SkyVerge and technical documentation. She spends a lot of time on research and interviews, but likes to write so she has an excuse to spend more time jamming out to anything from The Clash to Lady Gaga.

8 Comments

  1. I’ve tried using the “Filter Orders by Coupon Plugin” but only get a white screen when i attempt to filter the orders.

    • Hey Stuart, afraid I can’t replicate this — I’d recommend disabling other plugins (besides WooCommerce) / switching to a default theme, then re-enabling one by one to see which is at fault.

  2. Great tutorial.
    Helped me very much for writing my own customized coupon plugin.

  3. How do I get details on applied coupons on cart/checkout page?

    For example using “WC()->cart->get_applied_coupons()” I need to read “amount” of each coupon.

  4. Awesome post. I’m wondering how hard it would be to use a text box in the filter to search for coupons that start with something, when we generate coupons on the fly we have a random suffix on them and I would love to be able to see how many are actually being used.

    • Hey Blaine, the regular search box on the orders list should already handle this pretty well, moreso if the prefix is fairly unique / not used in a SKU.

  5. I kept finding this thread when looking for SQL queries to locate coupons. To help get other started, you can use the following in phpMyAdmin:

    SELECT * FROM wp_posts WHERE post_type = ‘shop_coupon’;

  6. Hi Miss. Rice. Please help me.
    I want to check customer or user email in Coupon applying process and update customer_email meta field if coupon has not been used before.

    Or, alternatively:
    In my case, i want to set Usage limit per user to 4-user/customer and Usage limit per coupon to 4. I don’t like to use auto generation of code by email address.

    thank,
    mohammadi

Hmm, looks like this article is quite old! Its content may be outdated, so comments are now closed.