New orders show up in WooCommerce > Orders with the grey "Pending payment" status and never move to Processing. The stock is held, no "new order" email goes out, and you are not sure whether the customer paid. There are two different problems behind that one status: either the money arrived and WooCommerce was never told, or the customer never finished paying. One check tells them apart. Below is a rebuilt example (not a real client), that check, and the fix for each cause.
Open one stuck order and note its number, total and the customer's email. Then log in to the payment account (Stripe, PayPal, Square) and search for that email or amount at that time.
On the order screen, read the Order notes box on the right: a working gateway writes a line such as "Stripe charge complete" or "IPN payment completed". Then open WooCommerce > Status > Logs and pick the newest log for your gateway (for example woocommerce-gateway-stripe or paypal). Errors there name the cause directly.
| What you see | Cause | Fix |
|---|---|---|
| Paid in Stripe, order still pending, no "charge complete" note; Stripe's Developers > Webhooks page shows failed deliveries | Stripe tells WooCommerce about the payment by calling a webhook on your site. The webhook is missing, points at an old address (after a move or a switch to https), or uses an old signing secret | In WooCommerce > Settings > Payments > Stripe copy the webhook address it shows and make sure Stripe has exactly that address, with the matching signing secret pasted back into the plugin. Then use "Resend" on the failed events in Stripe, and the orders update on their own |
| Paid in PayPal, order pending, logs mention IPN or "invalid" responses | The old PayPal Standard gateway relies on IPN messages: IPN is off in the PayPal account, points elsewhere, or the receiver email in WooCommerce does not match the PayPal account | Switch to the current WooCommerce PayPal Payments plugin, which uses webhooks and connects by logging in. If you must keep PayPal Standard, turn IPN on in the PayPal account with your site's address and make the receiver email match exactly |
| Webhook deliveries fail with status 403, 404 or 503, or Cloudflare / the host shows a "blocked" page in the delivery details | A firewall, security plugin, "coming soon" mode or a password on the whole site turns the payment provider away | Allow the webhook address (for example /?wc-api=wc_stripe or /wp-json/) through Wordfence, the host's ModSecurity and Cloudflare's WAF, and take the site out of maintenance or coming-soon mode. Do not switch the whole firewall off. See also 403 Forbidden |
| Payment arrived and the gateway note is there, but the status still did not change, or orders update hours late | WooCommerce finishes some steps through scheduled background tasks; on low-traffic sites, or when WP-Cron is switched off, they never run | Open Tools > Scheduled Actions and filter by "Past-due" or "Failed". If many are piling up, ask the host for a real server cron job that calls wp-cron.php every 5 minutes. More in scheduled tasks not running |
| No payment at all; the customer left at the card or PayPal step | The customer abandoned checkout. WooCommerce creates the order before payment, so every abandoned attempt leaves a pending order | Nothing is broken. WooCommerce cancels unpaid orders after the time set in Settings > Products > Inventory > Hold stock (60 minutes by default). If you see many, email those customers a link to pay (the order screen has a "Customer payment page" link) |
| No payment; customers say they pressed Pay and nothing happened, or the checkout shows an error | Checkout itself fails before payment: a script error, a cached checkout page, or a gateway in test mode | Exclude the cart, checkout and my-account pages from every cache, check the gateway is in live mode with live keys, and follow WooCommerce checkout not working |
| Dozens of pending orders from strangers, tiny amounts, often minutes apart | Card testing: bots use your checkout to try stolen card numbers | Turn on the gateway's fraud tools (Stripe Radar rules), add a checkout CAPTCHA or rate limit, and cancel the orders. More in too many requests |
Place a real order yourself for a cheap product, pay with a real card, and refund it afterwards. Within a minute it should move to Processing, carry a "charge complete" note, and send the new-order email. In Stripe, the webhook delivery for it should show status 200.
Most of these take ten minutes once you know which one it is. If you would rather someone else finds and fixes it, that is what the box below is for. Related: WooCommerce checkout not working and emails not sending.