PaidRadar › Order paid but not completed
“Paid but not completed” covers four different WooCommerce states with four different meanings, and only some of them suggest a missed payment confirmation. Getting the distinction right decides whether you are repairing a broken order or shipping goods against money that never cleared.
In WooCommerce, processing is the normal state of a successfully paid order for physical goods. Payment arrived, stock was reduced, and the order is waiting for you to fulfil it. Completed means shipped or delivered — it is a fulfilment state, not a payment state. Orders only jump straight to completed automatically when everything in the cart is virtual and downloadable. If your complaint is “paid orders stay on processing”, nothing is wrong with payment; you are looking at your own fulfilment step.
| Status | What WooCommerce means by it | Stock reduced? | Legitimate reasons to see it | When it suggests a missed webhook |
|---|---|---|---|---|
| Pending payment | The order object exists, no payment has been confirmed. | No | Customer abandoned the payment step, closed the tab, or never returned from the gateway. | The gateway shows a captured payment for that order reference and amount, but the order never left pending. |
| Failed | A payment attempt was made and did not succeed, or could not be verified. | No | Card declined, 3-D Secure abandoned, insufficient funds, fraud rule triggered. | The customer retried successfully and only the failed attempt was ever recorded on the site, or the confirmation for the successful retry was lost. |
| On hold | Awaiting payment confirmation; stock is reserved in the meantime. | Yes | Bank transfer, cheque, or a payment method that settles asynchronously and has not settled yet. | The gateway has since reported the payment as settled and the order never moved on. |
| Processing | Payment received. Awaiting fulfilment. | Yes | The normal state of a paid physical-goods order. | Effectively never — this state means payment was recorded. Sitting here is a fulfilment matter. |
| Cancelled | Cancelled by an admin, the customer, or by the hold-stock timeout. | No (released) | Unpaid order expired after the configured hold time. | Payment landed after the hold-stock window auto-cancelled the order. Rare, but it happens on slow payment methods. |
Behaviour described here is WooCommerce's default; plugins and custom code can and do change when statuses are set and when stock is adjusted. Check your own installation rather than assuming.
A stuck order is a question, not an answer. Work through this in order, and do not skip to the status dropdown.
With manual capture, the gateway holds the funds without taking them. The dashboard shows a successful-looking payment, but nothing has moved and the authorisation expires. Completing the order on that basis ships goods against an amount you may never collect.
Direct debit and several bank-based methods report a payment that is in progress and can still fail days later. On-hold is the correct state for those, and the gateway will report the outcome when there is one. Treating “in progress” as “paid” is exactly how a shop ends up shipping against a payment that later bounces.
Matching by amount alone is unreliable in a shop with repeat prices. Match on the gateway's order reference or payment ID, then confirm amount and currency. A same-value payment from a different order is a silent way to lose money twice.
Setting an order to processing in the admin fires status hooks, but not WooCommerce's payment
completion path. The order gets no paid date and no transaction ID, so reports, exports and anything
keyed to actual payment still treat it as unpaid. Use a route that runs
payment_complete().
The procedure above is the right one, and it does not scale. When the same pattern shows up every week, or when a webhook outage leaves you with hundreds of candidates, the answer is the same check performed mechanically rather than a bulk status edit that verifies nothing.
PaidRadar automates exactly this loop: it scans orders in pending, on-hold and
failed within a look-back window you set, queries the gateway API read-only for each one, and completes
only those the gateway unambiguously confirms as captured with a matching amount and currency — through
WooCommerce's own payment_complete() flow, so stock, emails and paid date behave as they
would have. Anything ambiguous is skipped and logged rather than guessed at. It is free, self-hosted,
and never moves money.
If you want the honest trade-offs against doing it by hand, replaying webhooks or bulk editing, read the comparison of every recovery option. If the underlying cause is still unknown, start with why Stripe webhooks fail to arrive, and if you are cleaning up after an outage, see repairing many orders safely.
Processing means payment was received and the order is waiting to be fulfilled. Completed means the order has been fulfilled. Completed is not a payment state, so a paid order sitting on processing is normal for physical goods — it moves to completed when you ship it, or automatically for orders that are entirely virtual and downloadable.
Only the gateway can answer that. Pending means the site never recorded a confirmed payment; it does not mean the payment failed, and it does not mean it succeeded. Look the transaction up on the gateway side, confirm it is captured rather than only authorised, and confirm the amount and currency match before changing the order.
Not without verifying, and usually not directly. Editing the status skips WooCommerce's payment completion path, so the order ends up with no paid date and no transaction ID while reports and integrations still treat it as unpaid. If the gateway can still replay the event, that is the cleanest fix; otherwise use a route that runs the payment completion flow and records the transaction reference.
On-hold means the shop is waiting for a payment it expects to arrive, and it reserves stock in the meantime. Bank transfer and asynchronous payment methods use it legitimately. It becomes a problem only when the gateway has since reported settlement and the order never moved on.
Usually the customer's first attempt failed, the second succeeded, and only the failure was recorded on the site — or the confirmation for the successful retry was lost in transit. Check the gateway for a later successful payment carrying the same order reference before you assume the failure was final.
By the gateway record, not by the order. Abandoned checkouts leave a pending order with no captured payment behind it. A missed confirmation leaves a pending order with a captured payment that matches it exactly. If there is no matching capture, the order was never paid and should not be completed.