PluginCity Product Expiry Dates for WooCommerce
Set a product expiry date in WooCommerce. When it passes the product comes off sale, and a cart still holding it cannot be checked out.

Product Expiry Dates is a WooCommerce plugin that takes a product off sale on its own when its expiry date passes, and stops a basket still holding it from being checked out.
The free version is on WordPress.org.
What it does
Some things should not be sold after a certain date. An event ticket is worthless the morning after, a seasonal line stops making sense in February, a limited-time offer ends, and a course closes for enrolment. WooCommerce has no way to say so.
Product Expiry Dates adds an Expiry tab to every product, with one box on it: the date that product can no longer be sold after. When that moment passes it comes off sale on its own, without anybody having to remember.
The date is enforced in both of the places it has to be. A product past its date cannot be added to a basket, and a basket that already had one in it cannot be checked out — which matters more than it sounds, because a basket can easily outlive the date it was filled before. The customer is told which product to take out, by name.
An expired product is taken off sale, not marked out of stock. It has not run out of units, and saying that it has would tell every report, feed and stock email something untrue about your shop. It stays in your shop, unbuyable, with a line on the page explaining why.
Pro is for shops where one date box per product is not enough. A shelf life dates your whole catalogue at once, and each category can carry a figure of its own — days for a flash sale, a year for a course. Variations can be dated separately, dates can be typed straight into the products list or carried in and out through your product CSV, and staff and trade accounts can be allowed to buy past-date stock so last season's lines still clear. It warns you a few days before a date passes, on your dashboard and by email, and can mark stock down as the date approaches so it clears before it stops selling.
Pro is the complete plugin. It adds all of the above, and it keeps every date and setting you have already made.
Watch: how it works
WooCommerce has no setting for an expiry date, so a product keeps its Add to cart button after it should have stopped being available to buy, until someone remembers to take it down. In this step-by-step tutorial we add expiry dates to a WooCommerce shop with the free PluginCity Product Expiry Dates for WooCommerce plugin: an Expiry tab on every product with a date and an optional time, an Expires column in the Products list, the two messages customers read (in the cart and on the product), where the cart and checkout message shows, and a shortcode that shows the date on a product page. Then we test it as a customer: an expired product on the shop page and on its own page, and a product that expires while it is already in a cart. No code needed.
Also on YouTube (opens in a new tab)
Read the transcript
WooCommerce will keep selling a product, long after it should have stopped being available to buy. In this tutorial, we'll give products an expiry date, so they come off sale on their own. We'll use the free PluginCity Product Expiry Dates plugin, and test everything as a customer.
This is Summer Blend, a seasonal coffee. It was only meant to be sold until October 31. WooCommerce has no setting for that, so the Add to cart button is still here. A customer can add it to the cart, and carry on to checkout. Nothing in a standard shop stops the sale.
Let's fix that. In your dashboard, go to Plugins, then Add Plugin. Search for PluginCity Product Expiry Dates for WooCommerce. Find the plugin by PluginCity, click Install Now, then Activate. It's free, and there's no license key to enter.
The settings live under WooCommerce, then Product Expiry. At the top, a note says expiry dates are switched on, but no product has a date yet, so nothing is being stopped. That's the plugin reminding you that nothing is happening yet. The dates themselves are entered on each product.
Open a product, for example Sunrise Blend. Under Product data, click the new Expiry tab. Type the last day the product can be sold. Let's use December 31. The time is optional. Leave it empty, and the product sells until the end of that day. Fill it in, and it stops at that minute. Dates follow your store's time zone, from Settings, General. Click Update to save it.
Now open the Products list. There's a new column, called Expires. It shows every date in one place. Summer Blend's date has passed, so it's in red, and marked No longer on sale. Harvest Blend has a time as well, six pm today. A date without a time shows eleven fifty nine pm, which is the end of that day.
Back in the settings, the yellow note has gone, because products now have dates. Next, open Messages. This is what your customers read. The first box is labeled In the basket, but it's the sentence shown in the cart and at checkout. Write percent S where the product names should go. Let's use our own words, and say cart. The second box, On the product, replaces the Add to cart button on an expired product. Bold, italics and links are allowed in both. Anything else is stripped out.
Under Display, you can switch the cart message on or off, and the checkout message too. An expired product is refused either way. These switches only decide where the customer reads about it. At the top, Use expiry dates is the master switch. Untick it, and nothing is stopped. Click Save changes. Import and export, below, copies these settings to another shop.
Now let's be the customer. A product that hasn't expired sells as normal. By default, the date isn't shown on the page. To show it, add the shortcode pexp_message, with show equals product, to the product description. Now the page says, Available until December 31, 2026.
Now Summer Blend, whose date has passed. On the shop page, its button says Read more, instead of Add to cart. It stays listed, so a customer who follows an old link lands on a page that explains itself. On its own page, the buy button is gone, and our sentence takes its place. It isn't marked out of stock, so your reports and feeds stay truthful. To hide expired products, or move them to draft, you would need Pro.
Dates can run out while a product is already in a cart. Harvest Blend stops at six pm today. It's half past three on the demo shop clock, so a customer can still add it. Now I'll move the demo shop clock to five past six. The cart explains itself. WooCommerce shows its own error at the top, and our message sits beside the totals. The product isn't removed behind the customer's back. It stays in the cart, so they can see why. If they carry on anyway, the order is refused, and the error names the product. Take it out, and the rest of the cart checks out as normal. Orders already placed are never changed.
There's also a Pro version, and the free plugin lists what it adds. Pro can warn you before a date passes, take expired products out of the shop, let staff and trade accounts buy anyway, and set dates in bulk. Everything else in this video is free.
That's it. Install the free plugin from Plugins, Add Plugin, and give your first product an expiry date. Search for PluginCity Product Expiry Dates for WooCommerce. Thanks for watching.
See it in action
What Free includes
Free forever on WordPress.org.
- One expiry date per product, on an Expiry tab just below Inventory
- An Expires column on the products list, showing what has stopped selling
- The product taken off sale by itself once the date passes, with a sentence saying why
- Baskets that outlived the date refused at the checkout, naming the product to remove
- Notices on the cart, checkout and mini-cart
- Classic checkout and the Cart and Checkout blocks both covered
- PayPal express buttons refused too, so a one-tap order cannot get past the date
- An optional time of day, so a date can end at a minute rather than at midnight
- A shortcode, [pexp_message], to put the message anywhere
- Settings import and export
- High-Performance Order Storage compatible
What Pro adds
Everything in Free, plus all of the features below.
- Roles the dates do not apply to, so staff and trade accounts can clear past-date stock
- A shelf life for the whole shop, dating every product that has none of its own
- A shelf life per category, because a flash sale runs for days and a course for a year
- A date on each variation, for a product whose sizes or flavours do not all last as long
- A choice of what else happens at expiry: hide the product, or move it to draft
- Warnings of what stops selling in the next few days, on your dashboard and by email
- Reduced to clear: a percentage off as the date approaches, and a deeper one at the end
- Dates in Quick Edit and Bulk Edit, to date or shift a whole selection at once
- An expiry column in the WooCommerce product CSV export and import
Free vs Pro
What the free version of PluginCity Product Expiry Dates for WooCommerce does, and what Pro adds. Pro is the complete plugin, so everything in Free is in Pro too.
| Feature | Free | Pro |
|---|---|---|
| One expiry date per product, on an Expiry tab just below Inventory | Included | Included |
| An Expires column on the products list, showing what has stopped selling | Included | Included |
| The product taken off sale by itself once the date passes, with a sentence saying why | Included | Included |
| Baskets that outlived the date refused at the checkout, naming the product to remove | Included | Included |
| Notices on the cart, checkout and mini-cart | Included | Included |
| Classic checkout and the Cart and Checkout blocks both covered | Included | Included |
| PayPal express buttons refused too, so a one-tap order cannot get past the date | Included | Included |
| An optional time of day, so a date can end at a minute rather than at midnight | Included | Included |
| A shortcode, [pexp_message], to put the message anywhere | Included | Included |
| Settings import and export | Included | Included |
| High-Performance Order Storage compatible | Included | Included |
| Roles the dates do not apply to, so staff and trade accounts can clear past-date stock | Not included | Included |
| A shelf life for the whole shop, dating every product that has none of its own | Not included | Included |
| A shelf life per category, because a flash sale runs for days and a course for a year | Not included | Included |
| A date on each variation, for a product whose sizes or flavours do not all last as long | Not included | Included |
| A choice of what else happens at expiry: hide the product, or move it to draft | Not included | Included |
| Warnings of what stops selling in the next few days, on your dashboard and by email | Not included | Included |
| Reduced to clear: a percentage off as the date approaches, and a deeper one at the end | Not included | Included |
| Dates in Quick Edit and Bulk Edit, to date or shift a whole selection at once | Not included | Included |
| An expiry column in the WooCommerce product CSV export and import | Not included | Included |
Who it is for
- Shops selling things that should not be sold after a date, such as an event ticket, seasonal stock, a limited-time offer or a course
- Shops that want a product to come off sale on its own, without anybody having to remember
- Shops that want a shelf life for the whole catalogue or for each category (Pro)
Who it is not for
- Anyone expecting an expired product to show as out of stock: it is taken off sale, not marked out of stock, so reports, feeds and stock emails are not told it has run out
Pricing
Every Pro plan is the same plugin with every feature. The only difference is how many sites you can run it on.
Free
The free plugin, free forever. Distributed through WordPress.org. No licence, no account.
$0
Get Freeon WordPress.org
Single site
One site, with a year of updates and support.
$49/year
Secure checkout. Cancel any time.
5 sites
Most popularUp to 5 sites, with a year of updates and support.
$99/year
Secure checkout. Cancel any time.
25 sites
Up to 25 sites, with a year of updates and support.
$199/year
Secure checkout. Cancel any time.
Need more than 25 sites? Get in touch about a custom licence.
Frequently asked questions
What happens when a date passes?
The product comes off sale. Its buy button goes and the page says it is no longer available, in whatever words you chose. Anybody who already had it in their basket is asked to take it out before ordering.
Is an expired product hidden, or marked out of stock?
Neither. It stays listed, its page still works and explains itself, and its stock is left alone, because how many you have has not changed. Pro can hide it or move it to draft instead.
Can I set a time as well as a date?
Yes. Leave the time empty and the product stays available to the end of the day you typed. Fill it in and it stops at that minute, which suits an event or a deadline.
Can I use it for event tickets, seasonal stock or limited-time offers?
Yes. Type the date on the product's Expiry tab and it stops being available to buy at the end of that day, so seasonal stock, a limited-time offer or a course ends on time. Give an event ticket a date and time and it stops at that minute.
Can different categories have different shelf lives?
Yes, in Pro. Every product category has a days-on-sale box, so a flash-sale category can be dated in days and a course category in a year, or a category can be left out of the shelf life altogether.
Can staff and trade accounts still buy past-date stock?
Yes, in Pro. Tick the roles the dates should not apply to. Everyone else, including anybody who is not logged in, is still held to them.
Can I be warned before a date passes, rather than after?
Yes, in Pro. A dashboard panel lists what stops selling in the next few days, soonest first, and the same list can be emailed each morning. Nothing coming up means nothing sent.
Can stock be marked down as its date approaches?
Yes, in Pro. Set a percentage off in the last week and a deeper one in the last days, and stock clears before it stops selling. Nothing is written onto your products, so extending a date puts the full price back the same moment.
Can I set dates on hundreds of products at once?
Yes, in Pro. Quick Edit types a date straight into the products list, Bulk Edit dates or shifts a whole selection, and the WooCommerce product CSV carries an expiry column both ways.
What happens to my dates if a Pro licence lapses?
They stay, and they carry on taking products off sale — it would serve nobody for expired products to become sellable again because a card was declined. What stops is the deciding: new products stop being given a shelf life, and clearance discounts end so your normal prices come back.
Recent Pro releases
Version 1.1.025 Oct 2026
- New: an Expiry display block for the block editor and the site editor, and an Expiry display widget for Elementor, to put a product's date or the cart message anywhere on a page.
- New: [pexp_message show="product"] prints a product's expiry date on the page. The cart message it printed before is unchanged.
- The listing and settings screen now say that Pro adds a block and an Elementor widget.
Version 1.0.224 Oct 2026
- Fixes a licence status issue on first activation.
- The listing now says cart rather than basket, and answers more of the questions shop owners ask.
- Once a customer's cart has been refused, the settings screen asks once, a week later, for an honest review. Close it and it does not come back.
- Clearer listing text. The plugin works as before.
Version 1.0.030 Sept 2026
- First public release.
More plugins

PluginCity Estimated Delivery Date for WooCommerce
Show an estimated delivery date on product pages, the cart, checkout and emails, and tell your team the dispatch date. Counted in working days.

Stock Alerts for WooCommerce
Lets customers leave their email address on a sold-out product or variation, and emails them when it can be bought again. A change in the stock number on its own sends nothing.

PluginCity Free Shipping Bar for WooCommerce
A free shipping progress bar for WooCommerce. Shows customers how much more to spend, on the cart, at checkout and in the mini-cart.

PluginCity Delivery Instructions for WooCommerce
Add a delivery instructions box to WooCommerce checkout, classic or block. Shown on the order, in your emails and on the thank-you page.

PluginCity Minimum Order for WooCommerce
Set a minimum order amount or quantity for WooCommerce. Checkout waits until the cart reaches it, and customers see exactly what to add.

PluginCity Advanced Pre-Orders for WooCommerce
Sell products before they arrive. Set an expected date, turn Add to basket into Pre-order, and carry that date through to the customer's order.