This one almost never announces itself. A membership site stops taking recurring payments and everything on the surface looks exactly the same: the products are published, the customers are still listed, the site loads fine. Weeks later somebody notices the monthly figure has been sliding, opens the subscriptions screen, and finds a column of next payment dates sitting in the past. That is what a WooCommerce subscription not renewing actually looks like from the inside. Not an error. Silence.
I build and repair WordPress membership and course sites for a living, and stalled renewals are the most expensive problem I get called in for, because the damage is already done by the time anyone spots it. The other version arrives as a support ticket instead: a member who paid last month gets locked out overnight and writes in angry. Same root cause, opposite symptom. In almost every case the subscription record itself is correct. Something one layer away from it decided the outcome before the charge was ever attempted. Below are the nine real causes, in the order I check them, and the exact screen to open for each.
Quick Answer
A WooCommerce subscription not renewing usually comes down to one of three things. Your store is running in staging mode, which disables automatic payments entirely and happens whenever the site URL changes or the live site gets restored from a copy. Or scheduled actions are not running, because Action Scheduler depends on WP-Cron and WP-Cron depends on site traffic, so the renewal event never fires. Or the charge was attempted and failed, and since the retry system is off by default, nothing tried again. Check the site mode first, the scheduled actions second, and the payment method third.
๐ What’s Covered
02Cause 1: Is Your Store Running in Staging Mode Without Anyone Noticing?
03Cause 2: Are Scheduled Actions Running at All?
04Cause 3: Did the Subscription Quietly Become a Manual Renewal?
05Cause 4: Is the Saved Payment Token Missing or Detached?
06Cause 5: Did the Payment Fail With Nothing Set to Retry It?
07Cause 6: Is PayPal Running the Schedule Instead of Your Store?
08Cause 7: Is Something Blocking the Gateway’s Webhook?
09Cause 8: Did the Scheduled Action Time Out?
10Cause 9: Are Duplicate Renewal Actions Fighting Each Other?
11WooCommerce Subscription Not Renewing: Which Check Comes First?
12What If the Renewal Charged but the Site Never Noticed?
13Why Does a Stalled Renewal Stay Invisible for So Long?
14How Do You Stop Renewal Failures Coming Back?
15Frequently Asked Questions
How Does a WooCommerce Renewal Actually Get Charged?
A subscription is not a recurring instruction sitting at your bank. It is a record in your database with a date attached, and something on your own server has to wake up on that date and go ask the payment gateway for money. Knowing which piece does what is the difference between a five minute check and a fortnight of guessing.
The sequence is the same every billing cycle. Subscriptions registers a scheduled action for the next payment date and hands it to Action Scheduler, the queue system built into WooCommerce. When that date arrives and the queue is processed, the woocommerce_scheduled_subscription_payment event fires, a renewal order is created, and the gateway is asked to charge the payment method saved against the original order. If the charge succeeds, the order completes and the next date is written. If it fails, the default behaviour is to leave the subscription on hold, email the customer, and wait for them to pay it themselves.

One detail from WooCommerce’s own renewal documentation is worth holding onto, because it explains a lot of confused billing dates later: the next renewal date is normally calculated from the last payment date rather than the scheduled date. So a queue that stalls for three days does not simply catch up. It shifts everyone’s billing anniversary forward by three days.
Read that chain from the left rather than the right. Most people open the subscription, confirm the customer and the product and the price are right, and conclude the extension is broken. The subscription record is usually the one link that was never at fault.
Cause 1: Is Your Store Running in Staging Mode Without Anyone Noticing?
This is the first thing I check, and it is the single most common reason a store stops charging everybody at once on a specific day. Subscriptions stores an obscured copy of your site address in an option called wc_subscriptions_siteurl the first time it is activated, and treats that address as the live site. If the address it reads later does not match, it decides it is running on a copy and switches into staging mode.
Staging mode is a safety feature, and it is deliberately blunt. As WooCommerce documents it, automatic payments are disabled and subscription related emails are suppressed, so a duplicated store cannot charge real customers twice. The trap is that the check works on the address, not on your intentions. Move to a new domain, restore the live site from a staging snapshot, switch between www and non-www, or finish an SSL migration, and your production store starts behaving like a test copy while looking completely normal.
The tell is a red badge reading Staging next to the WooCommerce, then Subscriptions menu item. It is easy to miss on a busy admin screen, and it sits alongside an admin notice that people dismiss during a migration when a dozen other notices are competing for attention.
Fix: Look for the Staging badge next to WooCommerce, then Subscriptions. If it is there on your production store, click Enable Automatic Payments in the staging notice. If the notice was already dismissed, bring it back by visiting your admin with ?wcs_display_staging_notice=true appended while logged in as an administrator, or set the wcs_ignore_duplicate_siteurl_notice option back to false in the options table. Going forward, activate Subscriptions on the live site first and build staging copies from that database, which is the order WooCommerce itself recommends.
Cause 2: Are Scheduled Actions Running at All?
Every renewal starts as a scheduled action, and scheduled actions are processed by Action Scheduler, which leans on WP-Cron to get going. WP-Cron is not a real timer. It fires when somebody loads a page. A low traffic membership site at three in the morning has nothing loading pages, so the queue waits, and on a site that is quiet enough it keeps waiting.
Go to WooCommerce, then Status, then Scheduled Actions. That screen lists actions by status: pending, in progress, complete, failed and past due. Past due is the one that matters here, because it means the scheduled date has come and gone with nothing processing it. A handful of past due actions minutes old is normal on a quiet site. Past due actions more than a day old are a genuine cron problem, and they explain missing renewals, missing emails and gaps in reporting all at once.
There is a second version of this that catches people who thought they had already solved it. Plenty of hosts and optimisation guides tell you to add define( 'DISABLE_WP_CRON', true ); to wp-config.php for performance. That line is correct only if a real server cron job was set up at the same time. Half the stores I look at have the constant and no cron job behind it, which stops the queue completely rather than making it faster.
Fix: Open WooCommerce, then Status, then Scheduled Actions and sort by past due. If anything is more than a few hours old, set up a real server cron job that requests wp-cron.php every five minutes through your hosting control panel, and only then add the DISABLE_WP_CRON constant. Check the WooCommerce, then Status, then System Status page to confirm WordPress cron is reported as working, and recheck the past due count an hour later rather than assuming the change took.
Cause 3: Did the Subscription Quietly Become a Manual Renewal?
A manual renewal subscription is working exactly as designed when it does not charge anyone. It is waiting for the customer to log in and pay, and customers overwhelmingly do not. If a batch of your subscriptions went manual without anyone deciding that, the revenue drop looks identical to a technical fault.
Two settings control this, both under WooCommerce, then Settings, then Subscriptions. Accept Manual Renewals offers every active payment gateway at checkout rather than only the ones that support recurring charges, so a customer can complete a subscription purchase through a gateway that was never going to bill them again. Turn off Automatic Payments goes further and stops new customers being charged automatically even when their gateway supports it. Both settings apply to new subscriptions only, which is why the effect shows up gradually as your customer base turns over rather than all at once.
The other route into manual renewal is a gateway change. Swap payment providers, and existing subscriptions still point at tokens held by the old one. Sites that switched processors during a migration often end up with two populations: older subscriptions charging normally and newer ones sitting in manual mode.
Fix: Open WooCommerce, then Subscriptions and read the payment method column across the whole list rather than one record. Manual renewal subscriptions are labelled as such. Then open WooCommerce, then Settings, then Subscriptions and confirm whether Accept Manual Renewals and Turn off Automatic Payments are switched on, and whether that was a deliberate decision. For individual customers already on manual renewal, the change has to come from their side: they add a payment method in their account and select it for the subscription.
Cause 4: Is the Saved Payment Token Missing or Detached?
Your store does not keep the customer’s card. It keeps a token, a reference the gateway issues that stands in for the card, and the renewal charge is the store presenting that token back. If the token is gone, invalid, or no longer attached to the right customer record at the gateway, the renewal order gets created and the charge fails at the last step.
WooCommerce documents this failure directly, with an error that reads in part: “The provided PaymentMethod was previously used with a PaymentIntent without Customer attachment.” Read plainly, that says the card was charged once as a one off rather than being stored against a reusable customer profile, so it cannot be charged again without the customer present. It is a common outcome when a payment method was added through a route that was never meant for recurring billing.
Expiry is the more ordinary version. Cards expire on a schedule nobody tracks, and an annual subscription is almost guaranteed to outlive at least one card. The renewal fails, the subscription goes on hold, and from the customer’s side nothing changed at all.
Fix: Open the failed renewal order and read its order notes, which carry the gateway’s actual decline reason rather than a generic message. If the token is the problem, the repair has to happen on the customer’s side: they add a fresh payment method from the Payment methods tab in My Account, then change the payment method on the subscription itself. Doing it for them by editing the subscription does not work, because the token has to be created against their gateway profile.
Cause 5: Did the Payment Fail With Nothing Set to Retry It?
Here is the setting that surprises most store owners: the failed payment retry system is off by default. Out of the box, a declined renewal is attempted once. The subscription goes on hold, the customer gets an email asking them to pay, and that is the end of the store’s involvement. Given how many declines are temporary, that single attempt loses real money.
Switch it on and you get five attempts spread over seven days, using the documented default rules: twelve hours after the failure, another twelve hours, then twenty four, then forty eight, then seventy two. Through all of it the renewal order stays pending and the subscription stays on hold. The first retry sends the customer nothing at all, because twelve hours is not enough time for them to have acted on a warning; the store owner gets a notification instead. Retries two through five email the customer as well.

After the fifth attempt the renewal order is marked failed and the customer is sent the renewal invoice email, which is exactly where an unretried subscription would have landed on day one. The difference is that a week of automatic attempts sits in between, and a card that was declined for a temporary hold on Monday frequently works by Wednesday. The retry rules are documented in full, including how to change the intervals.
Fix: Go to WooCommerce, then Settings, then Subscriptions and enable the automatic failed payment retry system. Then check that the customer facing retry emails are enabled under WooCommerce, then Settings, then Emails, since a retry the customer never hears about is worth far less than one they can act on. If your decline volume is high, look at the actual decline reasons in the order notes before changing the intervals, because insufficient funds and an expired card want very different timing.
Cause 6: Is PayPal Running the Schedule Instead of Your Store?
Older stores carry a category of subscription that your site does not control at all. Legacy PayPal Standard subscriptions were set up as billing agreements at PayPal, and PayPal owns the schedule from that point on. Your store is a spectator.
WooCommerce is direct about what that costs you. Its documented limitations of PayPal Standard state that store admins cannot modify the recurring totals on such a subscription, cannot modify any of its billing dates, and that PayPal controls the schedule and batch processes payments, so payments are not processed exactly when due. Charges land within about a day of the due date rather than on it. Subscription switching, the upgrade and downgrade flow, does not work with these at all.

There is a quick way to tell which kind you are looking at. Open the subscription and read the payment method token. Tokens beginning with I are legacy PayPal Standard billing agreements. Tokens beginning with B are reference transactions, the newer arrangement where the charge is initiated from your store rather than by PayPal. Only the second kind behaves like the chain described earlier in this article.
Fix: Before spending an afternoon on cron and tokens, check whether the affected subscriptions are legacy PayPal ones at all, since none of those repairs apply to them. If they are, treat a payment a day late as normal rather than as a fault, and check the PayPal dashboard rather than your store for the true status. For new business, move to a gateway arrangement where your store initiates the charge, and accept that existing billing agreements keep running at PayPal until each one is cancelled.
Cause 7: Is Something Blocking the Gateway’s Webhook?
Gateways report back through webhooks, and a webhook is just an inbound HTTP request to your site. Anything that filters inbound requests can eat it: a security plugin’s firewall, a rate limiter, a host level block on unfamiliar addresses, a maintenance mode plugin left switched on, or a page cache serving a stale response to the endpoint.
The symptom is specific and worth recognising, because it inverts everything else in this article. The customer is charged. The store never hears about it, so the subscription stays on hold and the member stays locked out while their card is being debited every month. That combination generates furious support tickets and refund requests, and no amount of looking at the subscription record explains it, since the record is accurately reporting what the store knows.
Caching deserves a specific mention here, because it causes trouble on membership sites in more ways than one. The same full page caching that intercepts a webhook endpoint is also what makes logged in performance behave nothing like a speed test, something I went through in detail in the guide to why WooCommerce membership sites feel slow.
Fix: Open your gateway’s dashboard and find its webhook delivery log, which records every attempt and the response your server gave. Repeated non success responses point at a block rather than a subscription problem. Confirm the endpoint address matches your canonical site address exactly, including www and HTTPS, because a webhook pointing at the pre migration address fails silently forever. Then exclude the endpoint from caching and allowlist your gateway in whatever firewall sits in front of the site.
Cause 8: Did the Scheduled Action Time Out?
An action that starts and never finishes is a different problem from one that never starts, and it hides in a different place. Subscriptions treats an action that has been running for more than five minutes as failed. On a shared host with a low PHP time limit and a queue holding a few hundred renewals for the first of the month, that threshold gets crossed regularly.
Failed actions do not always announce themselves on the subscriptions screen, so go to WooCommerce, then Status, then Logs and look for the failed scheduled actions log alongside your gateway’s own log. A fatal error triggered by an unrelated plugin during the renewal run shows up here too, and it takes down whatever renewals were in that batch while leaving the rest of the site working perfectly.
Fix: Read the failed scheduled actions log under WooCommerce, then Status, then Logs, and ask your host to raise the PHP maximum execution time well above the common thirty second default. Increase the PHP memory limit at the same time if renewals are batching on a specific day of the month. Once the limits are lifted, the stalled renewals still need triggering, which is done from each subscription’s own edit screen rather than by waiting for the next cycle.
Cause 9: Are Duplicate Renewal Actions Fighting Each Other?
The opposite fault is rarer and much worse for your reputation: the same billing period gets charged twice. WooCommerce documents duplicate renewal orders as happening when more than one renewal action is triggered for the same billing period, and lists three real triggers: overlapping scheduled actions, manual intervention while a renewal is already pending, and conflicting plugins.
The middle one catches conscientious store owners. A renewal looks stuck, so somebody presses Create Pending Renewal Order or processes it by hand, and the original action then completes on its own an hour later. Two orders, two charges, one very reasonable complaint. The rule I work by is simple: never intervene manually until you have confirmed the queue is genuinely stalled rather than merely slow.
Fix: Refund or void the duplicate order first, before anything else, because the customer relationship is the expensive part. Then open WooCommerce, then Status, then Scheduled Actions, filter to that subscription and cancel any leftover pending action for the same period. If duplicates keep appearing, run a conflict test on a staging copy: disable everything except WooCommerce and Subscriptions, confirm a clean renewal, then reactivate in batches until it recurs.
WooCommerce Subscription Not Renewing: Which Check Comes First?
Run these in order. Each one either finds the cause or removes a whole category of cause from the search, which beats opening settings screens at random. The first two take about ninety seconds together and account for most of what I find.
- Check the site mode. Look for the Staging badge next to WooCommerce, then Subscriptions. If it is there, nothing else on this list matters until it is cleared.
- Check past due scheduled actions. WooCommerce, then Status, then Scheduled Actions. Anything past due by more than a few hours is a cron problem, not a subscription problem.
- Establish the scope. One subscription, one gateway, or everybody. All of them points at cron or staging mode; a single customer points at their payment method.
- Read the payment method column. Manual renewal, an automatic gateway, or a legacy PayPal billing agreement. Each has a different mechanism and only one is yours to fix.
- Open the failed renewal order’s notes. The gateway’s real decline reason lives there, not in the customer facing email.
- Check the gateway’s webhook log. Repeated failed deliveries mean the charge and your store’s record of it have come apart.
- Read the logs. WooCommerce, then Status, then Logs, for failed scheduled actions, fatal errors and your gateway’s own log for that date.
- Only then intervene by hand. Process the stuck renewal from the subscription edit screen once you are sure no scheduled action is still pending for that period.
Launch day is when this list earns its keep. On Certified Boater, a NASBLA approved boater safety course I built on LearnDash with WooCommerce handling checkout, which took fourteen thousand pounds in its first launch (it is on my portfolio), the payment plumbing was where every real risk concentrated. The course content behaves the same whether ten people or a thousand arrive. The billing chain is the part that has to be watched.
What If the Renewal Charged but the Site Never Noticed?
This deserves its own section because the response has to be sequenced carefully, and getting it wrong makes things worse. The customer has been charged, your store thinks they have not, and their access has been removed. Two systems disagree, and the customer is caught between them.
Restore access first, before diagnosing anything. Reactivate the subscription manually so the person who paid can get back to what they paid for, then work out why the store never learned about the payment. Doing it the other way round means the investigation happens while a paying customer is locked out, and by the time you have found the webhook problem they have asked their bank for the money back.
Content lockouts have plenty of causes that have nothing to do with billing, which is worth ruling out before you go hunting through gateway logs. If the member’s payments are demonstrably fine and access is still wrong, the protection layer is the more likely suspect, and I worked through that side of it separately in the guide to MemberPress rules not working.
Why Does a Stalled Renewal Stay Invisible for So Long?
Because nothing about it looks wrong. A failed renewal produces a support ticket. A renewal that never ran produces nothing whatsoever: no order, no email, no log entry, no error. Your store is not aware that something did not happen, and neither are you, because absence is genuinely hard to notice on a dashboard built to display what did occur.
Reporting works against you here too. Revenue graphs slope rather than break. A store that stopped charging thirty subscriptions in the first week of a month shows a slightly weak month, which every store has occasionally. It takes two or three of those before anyone treats the shape as a fault rather than a soft patch, and by then the gap is a quarter wide and some of those customers have moved on.
The structural reason is that billing is decided by a chain of systems and administered through a single screen. The subscription record shows a customer, a product, a price and a date, all correct. The link that failed is somewhere you were not looking: a queue that never ran, a site address that no longer matches, a token that stopped being reusable, a webhook that was quietly dropped at the door. That distance between where the fault happens and where you go looking is the entire problem, and it is why a fixed order of checks beats intuition.
How Do You Stop Renewal Failures Coming Back?
Give the store a real server cron job rather than relying on visitor traffic, and treat that as a requirement of selling subscriptions rather than an optimisation. Five minute intervals are plenty. This one change removes the largest single category of stalled renewal, and it takes a few minutes in a hosting control panel.
Turn the failed payment retry system on before you need it. Five attempts across a week costs nothing to enable and recovers a meaningful share of temporary declines that would otherwise become cancellations you never see.
Build a short post migration checklist and actually run it, because migrations cause more renewal outages than anything else on this list. After any move, restore, domain change or SSL switch, check the staging badge, check past due actions, confirm the gateway webhook endpoints point at the new address, and verify a real renewal processes rather than assuming it will.
Keep an eye on the past due count as a routine number, the way you watch stock levels, since it goes wrong long before revenue visibly does. Then run a small monthly reconciliation: compare the count of renewal orders against the number of active subscriptions due in that period, and look at any gap. Fifteen minutes a month catches a stalled queue in week one instead of month three, which is the difference between a fixable dip and a hole in the year.
Frequently Asked Questions
Why did all my WooCommerce subscriptions stop renewing on the same day?
A failure that hits everybody at once is almost always store wide rather than customer specific, and there are two usual answers. Staging mode, triggered when the site address stopped matching the one Subscriptions recorded as live, which disables automatic payments across the whole store. Or scheduled actions stopping, because WP-Cron was disabled without a server cron job replacing it. Check the Staging badge next to WooCommerce, then Subscriptions first, then the past due list under WooCommerce, then Status, then Scheduled Actions.
Does WooCommerce Subscriptions retry a failed payment automatically?
Not until you enable it. The retry system is off by default, so a declined renewal is attempted once, the subscription goes on hold and the customer is emailed to pay manually. Once enabled, the defaults give five attempts across seven days: twelve hours, twelve hours, twenty four, forty eight and seventy two. The order stays pending and the subscription on hold throughout, and only after the fifth attempt is the order marked failed.
Why does my live site say it is a staging site?
Because Subscriptions compares your current site address against the one it stored when it was first activated, and treats any mismatch as a duplicate site. A domain change, a restore from a staging snapshot, an SSL migration or a www change all trigger it. Click Enable Automatic Payments in the notice to switch back to live mode. If the notice was dismissed, recall it by adding the staging notice parameter to your admin URL, or reset the ignore option in the database.
My customer was charged but their subscription is still on hold. What happened?
The gateway took the payment and the notification back to your site never arrived, so your store still believes the renewal is outstanding. Firewalls, security plugins, page caching on the webhook endpoint and an endpoint address left pointing at a pre migration domain are the common culprits. Reactivate the subscription manually first so the customer regains access, then check the gateway’s webhook delivery log to find the failed deliveries and fix the block.
Do I need a real cron job for WooCommerce subscriptions?
On any store you care about, yes. Renewals run through Action Scheduler, which leans on WP-Cron, and WP-Cron only fires when someone loads a page. A low traffic membership site has nothing loading pages overnight, so the queue waits. A server cron job requesting wp-cron.php every five minutes makes processing independent of traffic. If you add the DISABLE_WP_CRON constant to wp-config.php without setting that job up, renewals stop entirely.
Can I just process a stuck renewal manually?
You can, from the subscription’s own edit screen, but check first that no scheduled action is still pending for the same billing period. Manual intervention while a renewal is already queued is one of the documented causes of duplicate renewal orders, and charging a customer twice costs more goodwill than a late renewal does. Confirm the queue is genuinely stalled rather than slow, process the renewal, then cancel any leftover action for that period.
If you have worked through all nine and renewals are still unreliable, the cause has usually moved outside Subscriptions itself. A host level request filter nobody mentioned. A gateway account restriction that shows up only in the provider’s own dashboard. Strong customer authentication rules requiring the cardholder to confirm a charge that was designed to run without them. A migration that carried subscriptions across but not the payment tokens they depend on. Those are worth investigating once the nine above are genuinely ruled out, and not before.
The pattern behind nearly all of it is the same. Recurring revenue on WooCommerce is not one system charging a card, it is four or five systems agreeing to, and the subscription record is only the one you can see. Read it as a chain rather than a switch, and the answer is usually sitting one link above where everybody was looking. Finding it costs far less than the revenue that quietly leaks while nobody does.
Renewals stalled, or members locked out after paying?
Tell me whether it hit one customer or everyone, what changed on the site recently, and which gateway you use. I will tell you honestly which link in the chain is at fault and what it takes to fix it, whether or not you need anyone to do the work.