WooCommerce field notes

Fix WooCommerce, Subscriptions, and Stripe problems with a script

A working library of the problems that hit real WooCommerce stores, across WooCommerce, WooCommerce Subscriptions, and the Stripe gateway, and how to detect or repair each one with a small Python or Node.js script. Every guide has a diagram of the problem, a diagram of the fix, full code in both languages, tests, and links to the source reports.

Python and Node.js Diagrams and full code Sourced from real issues All code on GitHub

Order status and webhooks

7 guides

Payment lifecycle

7 guides

Charges and money

6 guides

Double charge from a race

The redirect and the webhook both complete the order and charge twice. Find and refund the extra.

Reconciler

Idempotency gap on PaymentIntents

A retry without an idempotency key made a second charge. Detect the duplicates and clean them up.

soon

Zero decimal currency charged 100x

Yen and similar currencies got multiplied by 100. Catch the overcharge and refund the difference.

soon

Amount does not match the order

The captured amount and the order total disagree. Compare them and report the ones that drift.

soon

Partial capture total mismatch

A partial capture but the order still shows the full amount. Line the total up with what was taken.

soon

Partial refund gives back everything

A small refund returned the whole charge. Spot the over refund on externally captured orders.

soon

Refunds and disputes

6 guides

Dashboard refund not synced

A refund made in Stripe never reached WooCommerce, so the order still looks paid. Record it back.

Reconciler

Refund skips non card methods

Refunds on iDEAL or EPS never flip the order to refunded. Fix the ones the webhook missed.

Repair

Fee and net stale after a refund

The saved fee and net still show the pre refund total. Recompute them from the balance transaction.

Repair

Disputes not recorded on the order

A chargeback pulled funds but the order shows nothing. Put the dispute state on the order.

soon

Refund and dispute double reversal

A refunded charge got disputed and Stripe pulled the money twice. Measure the loss you never booked.

soon

Fee and net missing on renewals

Renewal orders stopped saving fee and net after an update. Backfill them for clean books.

soon

Fees, payouts, and accounting

3 guides

Record Stripe fees on orders

Reports show list price, not what you kept. Save the fee and net so profit is real.

soon

Match payouts to orders

A bank deposit never equals the order totals. Build a per payout report that ties out to the cent.

soon

Presentment vs settlement currency

The buyer paid one currency and you settled another. Make the exchange explicit in your report.

soon

Customers, cards, and tokens

7 guides

Duplicate customers for one email

Retries made a new Stripe customer each time. Keep one, move the cards, remove the empties.

soon

Orphaned customers and cards

Stripe holds customers with no WooCommerce user. List the orphans and the renewal risks.

soon

Duplicate saved cards

A half finished upgrade left the same card twice. Group by fingerprint and detach the copies.

soon

Subscription has no saved card

A retry at checkout dropped the token, so renewals fail. Recover the customer and card from Stripe.

Reconciler

New card not linked to the sub

The buyer changed cards but the sub still points at the old one. Repoint it to the current card.

Reconciler

Payment method detached

The token is no longer attached to the customer, so renewals are rejected. Reattach or flag it.

soon

Card not saved for future renewals

After a manual 3D Secure renewal the card is not set for off session use. The next renewal fails too.

soon

Subscription lifecycle

7 guides

On hold after a good renewal

Stripe took the renewal but the subscription stayed on hold under HPOS. Set it back to active.

Reconciler

SEPA renewal stays active on fail

A slow SEPA debit failed but the sub still shows paid. Set the order failed so retries can start.

soon

Staging site pauses live subs

A clone with live keys paused real subscriptions. Find the wrong pauses and resume them.

soon

Renewal charged, no order made

Stripe billed the renewal but WooCommerce has no order for it. Reconcile invoices to orders.

soon

Card change flips sub to pending

Changing to a 3D Secure card left the subscription pending. Reactivate it and save the new card.

soon

Card check read as a failed payment

A failed card check downgraded a live subscription. Restore the subs that were wrongly held.

soon

Cannot change the card twice

A cached SetupIntent blocks the second card change in one session. Detect and clear the block.

soon

Cancellation sync

2 guides

Billing runs after WooPayments off

Turning off the plugin left Stripe subscriptions billing on their own. Find and cancel the orphans.

soon

Stripe bills after cancellation

The sub was cancelled in WooCommerce but Stripe keeps charging. Cancel the Stripe side to match.

soon

Alternative payment methods

4 guides

SEPA subs flip to manual renewal

A gateway ID change quietly turned off auto renewals for SEPA. Repair the payment method meta.

soon

Old SEPA sources rejected

Saved SEPA sources fail on the new API. Move them to a modern payment method or flag them.

soon

Stripe Link becomes manual

A Link purchase never saved its card to the sub. Pull the card across so renewals run again.

soon

iDEAL and Bancontact for renewals

These one time methods need a SEPA mandate to renew. Check for the mandate or flag the sub.

soon

Sources to PaymentMethods and SCA

5 guides

Move sources to payment methods

Old src tokens cannot be charged off session. Move them to pm tokens so renewals keep working.

soon

Promote the default source

The customer default is a source, not a payment method. Set the modern default so renewals succeed.

soon

Add off session mandate to old subs

Pre SCA subs renew with no mandate and European cards decline. Set up the mandate in bulk.

soon

Attach the payment method

A token used without a customer cannot be reused. Attach it and set the default for the sub.

soon

Legacy to new checkout cards

The new checkout may not show cards saved the old way. Attach them as reusable payment methods.

soon

Account and store migration

7 guides

Recreate subs after account move

A PAN copy keeps customers but drops subscriptions. Rebuild the billing objects on the new account.

soon

Stale IDs after a gateway switch

A new Stripe account left old customer IDs that fail. Find and clear the stale meta.

soon

Remap customers after a store move

A fresh install has no customer mapping. Match Stripe customers to users by email and write it back.

soon

Import cards from another processor

A card import made new IDs and a mapping file. Wire the new tokens into WooCommerce.

soon

Move WooPayments to Stripe

The meta keys differ and cards may not move. Remap what you can and drive re entry for the rest.

soon

Remove test IDs from live

Test customer and card IDs in a live store break every charge. Find and clear them safely.

soon

Detect test vs live key mixups

The wrong mode routes real checkouts to test. Confirm the key mode against Stripe itself.

soon

Bulk subscription operations

4 guides

Bulk swap a reissued card range

An issuer reissued a whole card range and renewals fail. Swap the payment method across many subs.

soon

Bulk cancel and keep in sync

Cancel many subs at once without leaving one side active. Cancel Stripe and WooCommerce together.

soon

Bulk pause on both systems

Pause at scale so Stripe stops billing and WooCommerce shows on hold. Keep the two lined up.

soon

Push a card change to Stripe

The card changed in WooCommerce but Stripe still charges the old one. Point Stripe at the new card.

soon

Catalog, metadata, and scheduling

4 guides

Sync products to Stripe

Stripe has nothing to bill without matching products and prices. Upsert them and store the IDs.

soon

Backfill order ID metadata

Old Stripe objects have no order ID, so nothing ties out. Match them and patch the metadata.

soon

Currency not enabled on Stripe

A currency shown at checkout is not turned on in Stripe, so payment fails. Report the gaps.

soon

Renewals never run

Cron or Action Scheduler is stuck, so renewals and retries never fire. Find the stalled jobs.

soon

WooCommerce core: stock and inventory

6 planned

Overselling race drives stock negative

Two orders pass the stock check at once and quantity goes below zero.

Repair

Failed order reduces stock, never restored

A failed order cut stock that was never added back when cancelled.

soon

Double stock reduction

One order reduced stock twice, leaving inventory permanently short.

soon

Stale reserved-stock rows oversell

Old reservation rows hold inventory that a second buyer then oversells.

soon

Variations stuck On Backorder at zero

A variation shows On Backorder at zero stock with backorders off.

soon

Order edits do not adjust stock

Adding or removing line items on an order never changes the stock.

soon

WooCommerce core: products and catalog

13 planned

Product lookup table out of sync

The product lookup cache drifts from real stock, price, and sales.

soon

On-sale flag shows products not on sale

The lookup table marks products on sale when they are not.

soon

Popularity sort uses stale total sales

Edited total_sales never reaches the lookup, so popularity sort is wrong.

soon

Deleting a variation does not resync the parent

A removed variation leaves the parent with stale stock and price.

soon

Orphaned product variations

Variations whose parent product is gone bloat the database and collide.

soon

Duplicate or missing SKUs

Imports and concurrent writes create duplicate or empty SKUs.

soon

Products stranded with no category

Products with no category vanish from archives and menus.

soon

Broken featured images

Products point at deleted attachments, so thumbnails break.

soon

Product visibility terms mis-assigned

A migration bug assigned wrong visibility terms, hiding products.

soon

Out of stock but still purchasable

Sold-out products stay buyable and visible in the catalog.

soon

Expired sale prices never revert

A finished sale keeps charging the sale price after it ends.

soon

Attribute and term counts drift

Layered nav shows wrong product counts per term.

soon

Ratings count drifts from real reviews

Displayed star counts diverge from the approved reviews.

soon

WooCommerce core: coupons

4 planned

Coupon usage count undercounts

Concurrent checkouts lose updates, so usage limits are exceeded.

soon

Coupon usage counted twice via REST

A REST order increments usage at pending and again at processing.

soon

Failed orders inflate and lock coupons

Held orders keep a coupon locked so real customers cannot use it.

soon

Coupon expiry uses UTC not site time

Coupons expire early or stay live around the local date boundary.

soon

WooCommerce core: customers and linking

3 planned

Guest orders not linked to accounts

A guest order never links to the account with the same email.

soon

Duplicate customer accounts at checkout

A username race creates duplicate accounts for one email.

soon

Customer lookup out of sync

The customer lookup table drifts from the real users list.

soon

WooCommerce core: tax, totals, and analytics

5 planned

Order tax off by a cent (frontend vs API)

The REST API returns a tax total one cent off from the frontend.

soon

Rounding drifts the order total by a cent

Intermediate rounding leaves historical order totals off by a cent.

soon

Order stats wrong after HPOS migration

Analytics show a false revenue spike after enabling HPOS.

soon

Trashed orders still counted in stats

A trashed order keeps inflating Analytics revenue and counts.

soon

Customer lifetime value drifts

Per-customer spend and order counts diverge from real orders.

soon

WooCommerce core: HPOS and housekeeping

3 planned

Legacy order rows survive after HPOS cleanup

Old shop_order posts linger after cleanup marks itself done.

soon

Checkout-draft orders pile up

Draft orders from the block checkout leak into order queries.

soon

Invisible auto-draft orders

Add Order drafts accumulate but never show in the orders list.

soon

WooCommerce core: database bloat and maintenance

6 planned

Expired transients bloat wp_options

Expired transients are never deleted and slow every query.

soon

Clear-transients tool leaves residue

The built-in clear tool misses thousands of WooCommerce transients.

soon

Autoloaded options bloat

Oversized autoloaded options slow every single request.

soon

Session table balloons

Broken session cleanup lets the sessions table grow without bound.

soon

Orphaned postmeta rows

Meta rows for deleted posts pile up in the most-queried table.

soon

Persistent cart data never cleared

Abandoned persistent-cart usermeta and sessions linger forever.

soon

WooCommerce core: scheduling, cron, and email

5 planned

WP-Cron disabled, emails never send

With no real cron, queued emails and actions never fire.

soon

Action Scheduler tables balloon

Action Scheduler tables grow to many gigabytes and slow the queue.

soon

Completed actions never purged

Thousands of succeeded actions pile up and are never pruned.

soon

Action Scheduler stuck in-progress

A crashed job stays in-progress and blocks the whole queue.

soon

REST pagination breaks on large sets

Paging over many orders silently misses or duplicates rows.

soon

WooCommerce Subscriptions: schedules and dates

6 planned

Next payment date drifts after a late renewal

Each late renewal pushes the billing day further out.

soon

Early renewal shifts the billing cadence

An early renewal permanently moves the customer's billing day.

soon

Timezone-corrupted next payment dates

Off-by-offset dates fire renewals early or twice.

soon

Active sub with a past next payment date

A stalled scheduler leaves a due renewal that never runs.

soon

Subscription will not end

A missing expiration action bills past the scheduled end date.

soon

HPOS schedule divergence

Schedule dates diverge between the post meta and the order tables.

soon

WooCommerce Subscriptions: status and renewals

5 planned

Stuck in pending-cancel

The end-of-term action never fires, so it never cancels.

soon

Cannot reactivate a pending-cancel sub

A leftover end date blocks the return to active.

soon

Zero-cost renewal orphaned by block checkout

A free renewal spawns a draft order linked to no subscription.

soon

Duplicate renewal orders in one cycle

Overlapping actions create two renewal orders for one period.

soon

Renewal marked paid with no payment

A cache bug completes a renewal that was never actually paid.

soon

WooCommerce Subscriptions: manual renewal and dunning

5 planned

Subscriptions revert to manual renewal

A bug flips auto-renew off, so renewals silently stop.

soon

Free trials forced to manual renewal

Block-checkout trials save no payment method and cannot auto-charge.

soon

Dunning stops before its attempts

Failed-payment retries stop scheduling before the configured count.

soon

Renewal actions stall, no renewals made

Stuck scheduled actions leave due renewals uncharged.

soon

Trial-end action false-positive failure

A benign trial-end action is flagged failed and adds noise.

soon

WooCommerce Subscriptions: switches, coupons, and data

8 planned

Proration miscalculated on a second switch

Two switches in one cycle compute an impossible proration.

soon

Recurring coupon dropped on switch

A switch loses the recurring discount, so it renews at full price.

soon

Wrong coupon type on renewals

A sign-up-only coupon is used where a recurring one was meant.

soon

Limited-payment coupon miscounts

The coupon applies to the wrong number of payments.

soon

Subscription price drifts from the product

A later price or name change never reaches existing subscriptions.

soon

Orphaned subscriptions with no customer

Live, billing subscriptions point at no valid user.

soon

Active-subscriber counts wrong in reports

Report caches miscount active subscriptions, especially on HPOS.

soon

Bulk subscription export runs out of memory

The built-in exporter fatals on large subscription sets.

soon

Fighting a WooCommerce or Stripe bug right now?

If you have a bug in WooCommerce, WooCommerce Subscriptions, or the WooCommerce Stripe gateway that you would rather hand off, this is the kind of work I do. Message me and we can work through it together.

Contact me on LinkedIn

Found this useful?

These guides are free and always will be. If one saved you a support ticket or a refund, you can throw a coffee my way. It keeps the notes coming.

Buy me a coffee on Ko-fi