Manage coupons
A coupon is a promise to give money away. A wrong one is discovered by customers before it is discovered by you, so this is the workflow with the least tolerance for a plausible-looking mistake.
Requirements
- WooCommerce active.
- Allow WooCommerce catalog writes open — coupons share the catalogue gate.
woocommerce:catalog:readandwoocommerce:catalog:write.- Shop management capability.
- A backup, and staging for anything bulk.
The tools
| Tool | Does |
|---|---|
wc_get_coupons |
List coupons |
wc_get_coupon |
Read one |
wc_get_coupon_count |
Count without listing |
wc_create_coupon |
Create one |
wc_update_coupon |
Update one |
wc_delete_coupon |
Delete one |
wc_empty_coupon_trash |
Empty the coupon trash |
Read before writing, and read the whole coupon
Read coupon "SPRING25" and show me the discount type, amount, expiry, usage limits and restrictions.
A coupon is a set of interacting rules, and the interesting ones are the restrictions rather than the amount. Before changing anything, know:
- The discount type. Percentage or fixed amount — 25 as a percentage and 25 as a fixed sum are very different promises.
- The expiry date. An expired coupon behaves differently from an absent one.
- The usage limits. Per coupon and per user.
- Minimum and maximum spend.
- Product and category restrictions.
- Whether it allows free shipping.
The dry run is not optional here
wc_create_coupon and wc_update_coupon both support it:
Use a dry run and show me every field of the resulting coupon before creating it.
Read the whole result, not just the field you asked to change. The failure mode is not usually a wrong amount — it is a correct amount with a missing restriction, which turns a targeted promotion into a site-wide discount.
Creating a coupon
State every constraint explicitly. Anything unstated defaults, and the defaults are permissive:
Create a coupon "SPRING25": 25% off, expires 30 April, limited to one use per customer, 200 uses total, minimum spend 50, applies only to the "Outdoor" category, cannot be combined with other coupons.
Then check the dry run against that list item by item before creating it.
Missing constraints to watch for:
- no expiry date, so it works forever;
- no usage limit, so it can be shared publicly and used without bound;
- no minimum spend, so it applies to a one-item order;
- no product restriction, so it applies to the whole catalogue;
- individual use not set, so it stacks with other coupons.
Updating a coupon
Coupons in circulation have been given to customers. Changing one changes what those customers can redeem.
Extend the expiry to 31 May. Change nothing else.
Consider whether a change should instead be a new coupon: reducing an active coupon's value or tightening its restrictions is, in practice, withdrawing something already offered.
Deleting and the trash
wc_delete_coupon removes a coupon. wc_empty_coupon_trash permanently removes everything in the coupon trash.
Be clear about the difference: the first is usually recoverable from the trash, the second is not recoverable at all. wc_empty_coupon_trash is a maintenance operation, not a way to remove one coupon.
Before emptying the trash, look at what is in it. Coupons are sometimes trashed to pause them.
Verify against the storefront
Stored data being right is not proof the coupon behaves correctly. After creating or changing one:
- Read it back.
- Put a qualifying item in a cart on the storefront and apply the code. Confirm the discount is what you intended.
- Try a non-qualifying case — below the minimum spend, or a product outside the restriction — and confirm it is refused.
- Purge the cache.
Step 3 is the one that catches a missing restriction, and it is the one people skip.
Bulk work
Count first with wc_get_coupon_count, then pilot on one:
List the coupons expiring this month with their codes and amounts, then stop.
Never apply a bulk change to coupons without checking one result on the storefront first. A rule applied to forty coupons is forty live offers.
Common problems
| Symptom | Cause |
|---|---|
pom_ai_mcp_wc_coupon_not_found |
Wrong code or ID |
| The write is refused | Catalog write gate closed, or insufficient capability |
| The discount is larger than intended | Percentage versus fixed amount |
| It applies to everything | No product or category restriction was set |
| It never expires | No expiry date was set |
| Customers share it widely | No usage limit was set |
| It stacks with other offers | Individual use was not set |
| The storefront does not recognise it | Cache not purged, or the coupon is not published |