Why does WooCommerce checkout hang on "processing" and how to fix it
TL;DR: A stuck "processing" spinner almost always means the browser sent the order and is waiting for a response that either never arrives or arrives too late. The five usual sources are a payment gateway webhook that never fires back, a server timeout on a slow host, a JavaScript conflict between plugins on the checkout page, an AJAX request being blocked by a firewall or caching rule, or a database write that silently fails. Each leaves a different trace, and checking the browser network tab first tells you which one you have in under a minute.
What "processing" actually means technically
When a customer clicks "Place order," WooCommerce sends an AJAX request to the server, WordPress processes it (validating the cart, creating a draft order, and handing off to the selected payment gateway), and the gateway either processes the payment directly or redirects, then the server responds back to the browser to move the customer to the confirmation page.
The spinner stays visible until that response arrives. It does not know why the response is late, only that it has not received one, which is why the same visible symptom, an endless spinner, can trace back to five unrelated causes at completely different points in that chain.
Step 1: check the browser network tab during checkout
Before anything else, open browser devtools, go to the Network tab, and place a test order (using a sandbox/test payment mode if your gateway supports it). Watch specifically for the AJAX request WooCommerce sends on order placement, usually named something with checkout or process_checkout in the payload.
Three outcomes tell you which direction to look. If the request never appears at all, or fails immediately with a blocked/CORS-style error, the problem is client-side, a JavaScript conflict or a request being blocked before it leaves the browser. If the request appears, sends, and then sits pending for a long time before eventually timing out, the problem is server-side, most likely Cause 2. If the request completes quickly but the customer still sees no redirect, the problem is more likely in what the gateway or WordPress does after receiving the response, Cause 1 or Cause 5.
Cause 1: payment gateway webhook never returns
For gateways that process payment off-site or asynchronously (many UPI, netbanking, and wallet-based Indian payment gateways work this way), WooCommerce's order confirmation depends on the gateway calling back to a webhook URL on your site to confirm payment succeeded. If that webhook call fails to reach your server, times out, or is rejected, WooCommerce has no way to know the payment succeeded and the order can sit indefinitely in a pending or processing state from the customer's perspective, even though the payment itself may have gone through on the gateway's side.
Common reasons the webhook fails to arrive: the webhook URL configured in the payment gateway's dashboard is outdated after a domain or host change, a firewall or security plugin blocking incoming requests from the gateway's IP ranges, or SSL/TLS handshake failures specifically on the webhook endpoint if it uses a different subdomain or configuration than the main site.
Check the payment gateway's own dashboard for the transaction; if it shows as successful there while WooCommerce shows the order as still pending, the webhook is the confirmed cause, not a general server problem.
Cause 2: server or PHP timeout
Checkout processing, especially with tax calculation, inventory checks, and gateway communication all happening within a single request, can be slow enough on an underpowered or overloaded server to exceed the PHP execution time limit or the web server's own request timeout. When that happens, the server kills the request mid-processing, sometimes after the order was already partially created in the database, and the customer's browser never receives a response at all, leaving the spinner running until the browser's own timeout eventually gives up.
This is more common on shared hosting during high-traffic periods (festival sales are the classic case) and on any host with an aggressively low default PHP max_execution_time. It is also more likely if multiple resource-heavy plugins (shipping rate calculators, tax plugins making external API calls) are active on the checkout page, since each adds to the total processing time within the same request window.
Our festival sale traffic guide covers preparing for this specific failure mode before a high-traffic event rather than diagnosing it mid-sale.
Cause 3: JavaScript conflict on the checkout page
If the network tab shows the checkout request never firing, the cause is almost always a JavaScript error earlier in the page's execution, commonly from a conflict between the theme, a checkout customization plugin, and a third-party script (chat widgets, review popups, and analytics scripts are frequent culprits) all trying to bind their own event handlers to the same "Place order" button.
The tell-tale sign is a browser console error appearing the moment the button is clicked, before any network request is attempted. Systematically disabling non-essential plugins active on the checkout page, particularly anything that customizes checkout fields or adds a script to that specific page, isolates this quickly.
Cause 4: caching or firewall blocking the AJAX request
Full-page caching plugins occasionally cache the checkout page itself, which should always be excluded from caching since it is inherently dynamic and session-specific. A cached checkout page can serve a stale security nonce that the server then rejects on submission, producing a request that fails silently or returns an error the frontend does not surface clearly to the customer.
Separately, a security plugin or WAF with an aggressive rate-limiting or bot-protection rule can flag rapid AJAX requests, particularly from customers who double-click "Place order" out of impatience, as suspicious activity and block the second (or even first) request outright.
Confirm your caching configuration explicitly excludes the cart and checkout pages, and check the security plugin's firewall log for any blocked request coinciding with the exact time of a failed checkout attempt.
Cause 5: a database write failing silently
Less common, but the hardest to diagnose without server access: if the database has hit its connection limit, a table has become corrupted, or a specific field has a data constraint the order data violates (this happens after certain migrations or plugin updates that change expected data formats), the order creation step itself can fail partway through, leaving no clear customer-facing error and no completed order, just a hung request that eventually times out.
Checking the site's PHP error log for anything logged at the moment of a failed checkout attempt, database errors specifically, is the direct way to confirm this cause versus the others.
A diagnostic table
| Network tab shows | Likely cause | Where to look next |
|---|---|---|
| Request never sent, console error on click | JavaScript conflict | Disable checkout-page plugins one by one |
| Request sent, pending a long time, then times out | Server/PHP timeout | PHP max_execution_time, server load during test |
| Request completes, no redirect, gateway shows payment as successful | Webhook not reaching site | Gateway webhook URL and firewall allowlist |
| Request blocked or returns 403/429 | Caching or firewall rule | Cache exclusions, WAF rate-limit logs |
| Request times out, PHP error log shows a DB error | Database write failure | DB connection limits, recent schema changes |
What this actually costs in lost sales
The reason this deserves urgent attention rather than "we'll look into it eventually" is that almost no customer reports a stuck checkout. They wait a few seconds, assume the site is broken, and leave, often abandoning a cart they had every intention of completing. Unlike an outright error message, a silent hang generates no support ticket and no obvious signal in standard analytics beyond an unexplained gap between cart additions and completed orders.
If cart abandonment rate spikes without a corresponding spike in support contacts, a silent checkout hang affecting a subset of payment methods or devices is worth ruling out directly, since it produces exactly that pattern: lost sales with no complaints.
FAQs
The order eventually appears in WooCommerce as "pending payment" even though checkout hung. What does that mean?
This usually confirms Cause 1: the order was created on your site before the customer submitted payment details to the gateway, but the gateway's confirmation never made it back. Check the gateway's own transaction log for that order's timestamp to see whether payment was actually captured on their end regardless of what WooCommerce shows.
Does this only happen with certain payment gateways?
Webhook-dependent failures (Cause 1) are more common with gateways that redirect off-site or process asynchronously, common with several India-focused UPI and netbanking integrations, than with gateways that process entirely within the page via a direct API call. If the hang correlates specifically with one payment method and not others, that strongly points at Cause 1 for that method specifically.
Can I reproduce this reliably to test a fix?
Use the payment gateway's sandbox/test mode combined with browser devtools open on the Network tab throughout the process. If the hang is load-dependent (Cause 2), reproducing it outside of peak traffic may not trigger it; a load-testing tool simulating concurrent checkout attempts is more reliable for that specific cause.
Is increasing PHP max_execution_time a real fix or a band-aid?
It is a legitimate fix if checkout processing genuinely needs more time than the default allows, particularly with several tax or shipping plugins doing external calls in sequence. It becomes a band-aid if the underlying cause is a server too underpowered to handle checkout load at all, in which case extending the timeout just delays the same failure under slightly higher load rather than preventing it.
How do I know if it's the payment gateway's problem rather than my site's?
If the gateway's own status page or support confirms an outage or elevated latency at the time of the hang, and your server logs show nothing unusual, the cause is likely external. If your server logs show timeouts, errors, or blocked requests at the exact time, the cause is on your side regardless of what the gateway status page says.
Should I disable caching on the entire site to fix this?
No, only cart and checkout pages need to be excluded from full-page caching; the rest of the site can and should remain cached normally. Most caching plugins have a built-in setting for excluding WooCommerce's dynamic pages specifically, rather than requiring you to disable caching site-wide.
Could a recent WooCommerce or gateway plugin update be the cause?
Yes, this is common enough to check first if the hang started immediately after an update. Payment gateway plugins in particular sometimes change webhook URL formats or authentication requirements between versions, which can silently break a previously working integration until the corresponding setting is updated to match.
What is the fastest first thing to check if I only have five minutes?
Open the network tab and place one test order. Whether the checkout request fires at all, and what happens to it if it does, immediately narrows the cause from five possibilities to one or two, which is far faster than guessing based on symptoms alone.
Conclusion
A stuck checkout spinner is a symptom that can originate at any of five different points in the order process, and each leaves a distinct trace in the browser network tab, the payment gateway's dashboard, or the server's own logs. Guessing based on the spinner alone wastes time; checking where in the chain the request actually stops narrows it down in minutes.
Because most customers leave silently rather than report the issue, this is worth testing proactively, especially before high-traffic periods, rather than waiting for a visible drop in completed orders to notice it happened.
HostCloud's WooCommerce-optimized hosting includes checkout-aware caching exclusions and sized PHP execution limits by default, so server timeout and cache-related hangs should not originate from the hosting layer. Plans start at ₹99 a month at https://hostcloud.in, and free migration is included if you are moving an existing store.
