MageSentinel

WooCommerce orders stuck in pending payment: causes and fixes

Pending payment is the status WooCommerce gives an order that exists but has not been paid. A handful a day is normal: shoppers close the card page or the bank’s 3-D Secure screen. A sudden pile is not. It means either nobody can pay, or people are paying and your store is not being told.

All posts5 min read

A round wall clock on a white wall

What Pending payment means, and what it does not

WooCommerce describes the status plainly: the order has been received, but no payment has been made (order statuses). The order is created the moment the shopper presses Place order; the gateway then tries to take the money, either on the page (card fields) or by sending the shopper away to a payment page and back.

Two neighbouring statuses are easy to confuse with it. On hold is used when the payment still needs confirmation, for example bank transfer or cheque, and stock is already reduced. Failed means the payment was rejected. And if you use the block-based Checkout, a checkout-draft record is not an order yet at all: it is a temporary record WooCommerce cleans up daily. Only Pending payment means “created and never paid”.

When WooCommerce cancels them on its own

Under WooCommerce → Settings → Products → Inventory, Hold stock keeps stock reserved for unpaid orders for a number of minutes. When the time runs out, WooCommerce cancels eligible Pending payment orders created through checkout and releases the stock. Leave the field blank and nothing is ever cancelled automatically.

The cancellation runs as a scheduled task (woocommerce_cancel_unpaid_orders) on WP-Cron. If WP-Cron is disabled with DISABLE_WP_CRON and no server cron replaces it, or the site gets so little traffic that WP-Cron rarely fires, old pending orders simply stay. Orders you create in the admin and send with a “pay for order” link are not created through checkout, so they are not cancelled either. If old ones are piling up, check cron before anything else; the Action Scheduler guide covers how to see what is past due.

Abandoned or lost? Ask the payment provider

This is the question that decides everything. Open a few of the stuck orders, note the time, amount and payment method, and find the same attempts in the provider’s dashboard (Stripe, PayPal, your bank’s portal).

If the provider shows no successful payment, the shopper did not finish. A normal share of these is background noise; a jump after a plugin update, a theme change or a new security rule means the payment step is broken for many people, and you should test a purchase yourself straight away. If the provider shows the payment as succeeded but the order is still pending, the store missed the confirmation. Those customers have paid for orders you may not ship, so treat it as an incident.

The order notes help too. Most gateways write a note when the shopper is sent away and another when the result comes back. An order with the first note and never the second points to the return trip or the webhook.

Why the confirmation never arrives

Card gateways confirm payments with a webhook: the provider’s server calls a URL on your store. For the WooCommerce Stripe Gateway that endpoint looks like https://example.com/?wc-api=wc_stripe, and the Stripe dashboard lists every delivery with its response code. PayPal Payments shows the webhook status in its own settings.

Failed deliveries come from a short list of causes. A firewall, a Cloudflare rule or a security plugin blocks the provider’s servers. The webhook still points to an old domain, or to staging. The store answers with a redirect (HTTP to HTTPS, or www to non-www) that the provider does not follow. Maintenance mode or basic auth is switched on. The SSL certificate has expired. Or the signing secret was regenerated on one side only, so every call is rejected as unsigned.

Fix the cause, then resend the failed deliveries from the provider’s dashboard. A resent webhook usually moves the order to Processing exactly as if it had arrived on time. Change the status by hand only after you have confirmed the payment in the provider’s dashboard, never on the customer’s word alone.

Diagnose it in ten minutes

Start with the count: in WooCommerce → Orders filter by Pending payment and look at when they started. With WP-CLI you can list them with wp wc shop_order list --status=pending --user=1 --fields=id,date_created,payment_method,total (use the ID of an administrator). If they all share one payment method, the problem is in that gateway; if they span every method, look at the checkout itself.

Then open WooCommerce → Status → Logs, pick the gateway’s log (for example stripe or ppcp) for the same minutes, and look for errors around the webhook or the return URL. Finally, place a real order yourself with the affected method in a private window and watch whether it reaches Processing. If you need card numbers for a test mode, the provider publishes them; never test with a real card in test mode or a test card in live mode.

Find out your checkout broke before your customers do.

Real checkout checks for Magento and WooCommerce · 14 days free · no card required

Catch the next one the same day

Stuck payments are quiet. The shop loads, products add to the cart, and no error page appears anywhere; the only signal is a rising count in a status most people do not look at. The free MageSentinel plugin counts failed and still-pending payments of the last 24 hours, per payment method, and flags them on its health page.

A scheduled checkout check covers the other half: a real browser goes through the checkout to the payment step and tells you which step broke, with a screenshot. For a one-off check right now, run the free WooCommerce checkout checker. If the payment form itself is failing, continue with WooCommerce payment gateway failing.

Common questions

What does Pending payment mean in WooCommerce?

The order was created at checkout but no payment has been confirmed. It differs from On hold (payment awaiting manual confirmation, stock already reduced) and Failed (payment rejected).

Does WooCommerce cancel pending payment orders automatically?

Only if Hold stock is set under WooCommerce → Settings → Products → Inventory. After that many minutes, eligible pending orders created through checkout are cancelled and their stock released, as long as WP-Cron runs.

The customer paid but the order is still Pending payment. Why?

The gateway’s webhook did not reach the store or was rejected: a firewall or security plugin, an old domain in the webhook settings, a redirect, an expired certificate or a changed signing secret. Fix it and resend the failed webhooks from the provider’s dashboard.

Should I mark pending orders as Processing by hand?

Only after you have confirmed in the provider’s dashboard that the payment succeeded. Resending the webhook is better, because the gateway then records the transaction ID on the order.