PaidRadar › Order paid but not completed

The money arrived. The order didn't move. Which status you are looking at matters.

“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.

First, the most common false alarm: processing is not broken

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.

What each status actually means

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.

Verify before you change anything

A stuck order is a question, not an answer. Work through this in order, and do not skip to the status dropdown.

  1. Read the order notes. They are the site's own record of what the gateway said and when. A note like “awaiting payment” with nothing after it tells a very different story from a recorded authorisation.
  2. Find a transaction reference. If the order carries a gateway transaction ID, a payment attempt definitely got as far as the gateway. If there is none, be more suspicious.
  3. Look the payment up on the gateway side, searching by order reference, customer email or amount. Confirm three things: it exists, it is captured — not merely authorised — and the amount and currency match the order exactly.
  4. Check it was not reversed. A payment can be captured and then refunded, disputed or charged back. The current state is what counts, not the original success.
  5. Check for a duplicate order. Customers who get no confirmation frequently order again. Completing both means shipping twice for one payment.
  6. Only then act. If the event is still replayable at the gateway, replay it and let your payment plugin do the work. Otherwise complete the order deliberately, and record the transaction ID on it.

Three things that look like a paid order and are not

Not money yet

Authorised but not captured

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.

Not final yet

Asynchronous methods still settling

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.

Wrong record

The payment belongs to another order

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.

Wrong tool

Changing the status by hand is not the same as paying

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().

Once it stops being a handful of orders

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.

Questions

What is the difference between processing and completed in WooCommerce?

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.

My customer paid but the order is stuck on pending payment. Is the money mine?

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.

Should I just set the order to completed?

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.

Why do some orders sit on on-hold instead of pending?

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.

A failed order was actually paid. How does that happen?

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.

How do I tell a webhook problem from a normal abandoned checkout?

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.

See how PaidRadar works Back to the overview