WooCommerce 11.0.1 fixes Store API payments for existing orders so each coupon usage limit is enforced correctly. This matters when checkout creates an order before payment, a shopper retries payment, or a custom client resumes an existing order. A coupon can have a global limit, a per-user limit, or both, and the test must distinguish a legitimate retry from a second redemption.
Use this for block checkout, headless Store API clients, pay-for-order flows, payment retries, subscriptions, or promotions with strict global and per-customer limits.
Quick answer
Create coupons that isolate global and per-user limits, then exercise new-order payment, failed-payment retry, pay-for-order, and a second customer. Record coupon usage counts before and after every request. A retry for the same valid order must not consume an extra use, while a genuinely exhausted coupon must be rejected before payment with unchanged order totals and a clear Store API error.
What to check first
- Record coupon ID, code, global limit, per-user limit, allowed products, expiry, usage count, customer ID or email, and order ID.
- Use unique orders for first redemption, same-order retry, second-order attempt, and second-customer control.
- Capture Store API request, response status, error code, order notes, payment intent, totals, and coupon usage count around each step.
- Test payment failure before success so retry behavior is separated from a duplicate redemption.
- Check custom checkout, coupon, subscription, and gateway extensions for filters that change validation or order reuse.
Test scenarios to run
Run the same controlled fixture across these branches. Write down the expected result before testing so a surprising response is easy to identify.
| Scenario | Fixture | Expected result |
| First redemption | Coupon global limit 1, unused, new customer | Existing order can pay and usage count becomes exactly 1 |
| Same-order retry | First gateway attempt fails before a successful retry | Retry succeeds or resumes without adding a second coupon use |
| Second order | Another unpaid order uses the exhausted coupon | Store API rejects the coupon before payment and totals remain correct |
| Per-user boundary | Global capacity remains but the same customer reached limit | Same customer is rejected while an eligible second customer can proceed |
Decision rule
Pass only when accepted payments consume one legitimate use, same-order retries do not consume another, and exhausted coupons are rejected before payment without mutating totals or unrelated orders.
Safe fix order
Use a sequence that makes each result easy to prove. Stop when new evidence changes the scope or owner of the problem.
- Build coupons and orders that isolate each usage-limit branch.
- Run the pre-update fixture and save counts, totals, requests, responses, and notes.
- Install 11.0.1 and repeat with fresh IDs in the same order.
- Remove or correct extension filters only when they change the documented validation contract.
- Deploy and monitor coupon errors, payment retries, and usage-count drift during the first campaign window.
Diagnostic table
Use this table to connect the observed behavior to evidence and a verification step.
| Action | Evidence to collect | How to verify |
| Build coupons and orders that isolate each usage-limit branch. | Record coupon ID, code, global limit, per-user limit, allowed products, expiry, usage count, customer ID or email, and order ID. | Coupon usage counts match completed eligible redemptions and never count the same order twice. |
| Run the pre-update fixture and save counts, totals, requests, responses, and notes. | Use unique orders for first redemption, same-order retry, second-order attempt, and second-customer control. | Global and per-user limits produce distinct, correct Store API decisions. |
| Install 11.0.1 and repeat with fresh IDs in the same order. | Capture Store API request, response status, error code, order notes, payment intent, totals, and coupon usage count around each step. | Rejected attempts do not create payment charges, incorrect order totals, or misleading success notes. |
| Remove or correct extension filters only when they change the documented validation contract. | Test payment failure before success so retry behavior is separated from a duplicate redemption. | Block checkout, pay-for-order, and the custom Store API client agree for the same fixture. |
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
coupon,global_limit,per_user_limit,customer,order,attempt,expected
LIMITONE,1,1,guest-a,10421,first,accepted
LIMITONE,1,1,guest-a,10421,retry,no_extra_use
LIMITONE,1,1,guest-b,10422,first,rejected_global
USERONE,10,1,user-17,10423,second,rejected_user
Production verification checklist
- Coupon usage counts match completed eligible redemptions and never count the same order twice.
- Global and per-user limits produce distinct, correct Store API decisions.
- Rejected attempts do not create payment charges, incorrect order totals, or misleading success notes.
- Block checkout, pay-for-order, and the custom Store API client agree for the same fixture.
Why this usually happens
- Existing-order payment follows a different code path from initial cart validation.
- A failed payment can leave an order and coupon relationship that a retry misinterprets as a new use.
- Guest email, customer ID, and session identity can produce different per-user decisions when test fixtures are not explicit.
Field notes
- Use a sandbox gateway and disposable coupons. Never test a one-use production campaign with live shoppers active.
- Snapshot both order totals and coupon usage records before each request so a rejected attempt cannot silently mutate state.
- Retain the Store API error code and order note, not just the visible checkout message.
Mistakes to avoid
- Do not change several production layers at once. Preserve the failing evidence and isolate one variable per test.
- Do not use a successful status or screen message as the only proof. Verify the business outcome and the underlying record.
- Do not leave debug logging, broad credentials, test orders, or temporary exceptions active after the review.
- Do not close the incident without recording the fixture, timestamps, owner, result, and rollback point.
What to tell the client or owner
Give the owner the affected versions, exact fixture, stable IDs, UTC timeline, before and after evidence, decision, rollback point, unresolved risks, and next review date.
Questions teams ask during testing
Can this be tested on staging?
Start on staging with production-like versions, cache, data shape, and integrations. Finish with one controlled production fixture when the result depends on real routing, provider, or edge behavior.
What evidence should be retained?
Keep the smallest useful set: stable IDs, UTC timestamps, sanitized request or log excerpts, expected result, actual result, version inventory, and the final verification.
When should the change be rolled back?
Roll back when a core revenue, privacy, security, or publishing path fails and the cause cannot be isolated inside the approved maintenance window.
When HandL WP should help
Bring in help when this affects leads, checkout, search visibility, security, paid media reporting, or a client production site. HandL WP can trace the issue through WordPress, hosting, cache, tracking, and Search Console, then verify the workflow after the technical fix.
If this is active on a production site, validate Store API coupon rules.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references