Merchlint
Available now
Next, in this order
  • DeutschDE
  • EspañolES
  • FrançaisFR
  • ItalianoIT
  • PortuguêsPT
  • NederlandsNL
  • SvenskaSV
  • TürkçeTR

A language shows up here once its pages are actually written. Nothing on this site is machine-translated.

Install free
← All checks

A coupon that outlived its own limit

The date passed or the usage limit ran out, and the coupon is still published. Customers find the code, try it, and abandon the cart at the last step.

Group
Money
Confidence
F — fact from the database
Version
Pro
Updated
Code
A9

The symptom

A code from last year’s campaign is still listed under Marketing → Coupons, still published, and still findable — in an old newsletter, on a voucher site, in an affiliate’s post that nobody took down. The customer types it at checkout and gets “This coupon has expired.”

The mirror image of this is worse and looks identical in the admin: a coupon that was meant to run for two weeks, has no expiry date at all, and has been discounting every eligible order since.

What it costs

The two halves fail in opposite directions, which is why they are one check.

An expired coupon that is still visible costs conversions at the most expensive possible moment. The customer has chosen, added to cart, entered an address and reached payment. A rejected code there does not send them back to shop — it sends them to a search for a working one, on somebody else’s site.

A coupon with no end date costs margin quietly and indefinitely. Nobody notices, because the orders complete successfully and the discount looks like it was intended. This is the same failure as a sale whose end date passed, in a place where fewer people think to look.

How to check it yourself

Coupons are a post type, and their rules are ordinary post meta:

wp db query "SELECT p.post_title AS kod, \
  MAX(CASE WHEN m.meta_key = 'date_expires' THEN m.meta_value END) AS wygasa, \
  MAX(CASE WHEN m.meta_key = 'usage_count'  THEN m.meta_value END) AS uzyc, \
  MAX(CASE WHEN m.meta_key = 'usage_limit'  THEN m.meta_value END) AS limit_uzyc \
  FROM wp_posts p JOIN wp_postmeta m ON m.post_id = p.ID \
  WHERE p.post_type = 'shop_coupon' AND p.post_status = 'publish' GROUP BY p.ID"

Replace wp_ with your table prefix. Read the result twice: once for rows where wygasa is in the past or uzyc has reached limit_uzyc, and once for rows where wygasa is empty on a coupon that was clearly a campaign.

How to fix it

  1. Move finished coupons to the trash rather than leaving them published. A trashed coupon still appears in order history, so nothing in your reporting breaks.
  2. Give every new coupon an expiry date at the moment you create it, even one far out. A date you can extend is safer than a date you have to remember to add.
  3. For codes that leaked into places you do not control, decide deliberately: either honour them and set a real end date, or remove them and accept the checkout error. Leaving it undecided is what costs money.
  4. Search your newsletters and affiliate material for the code before deleting it, so you know what the customer will have seen.

When it is a false positive

  • Evergreen codes by design — a permanent welcome discount or a standing partner rate has no end date on purpose.
  • Coupons kept published for reporting, where a workflow depends on them staying out of the trash.
  • Per-customer limits. usage_limit_per_user reaching its ceiling for one customer is not the same as the global usage_limit being exhausted, and only the second one is a finding.
  • Codes reused every season, expired now and switched back on in three months.

How Merchlint finds it

Merchlint reads every published shop_coupon and compares date_expires against today, and usage_count against usage_limit. It reports three separate cases: expired but published, exhausted but published, and campaign-shaped coupons with no expiry date at all. Each finding shows the code, the rule that fired and the discount it grants, so you can tell a five-percent standing rate from a fifty-percent clearance code without opening either.

Confidence: F — fact from the database. A date is before today or it is not; a counter has reached its limit or it has not.

This check ships in the Pro add-on.

Run this check on your store

Disagrees with what you see in your store? Write to us — we read every message. contact@merchlint.com