PaidRadar › Bulk-repairing orders after a webhook outage

Webhooks were dead for days. Now there are hundreds of stuck orders.

The endpoint was blocked, timing out or pointing at the wrong URL, and nobody noticed until the backlog became obvious. The instinct is to select everything in the order list and bulk-change the status. That instinct is the expensive one. Here is what goes wrong with it, and a procedure that does not require trusting a guess.

Why a bulk status edit is the wrong tool here

A bulk status change is a bulk assertion that all of those payments succeeded. Nothing in it checks whether any of them did. Two separate problems follow from that.

It verifies nothing

A stuck-order backlog is never uniformly “paid”. It contains genuinely paid orders, abandoned checkouts, declined cards, retries that succeeded on a second order, authorisations that were never captured and asynchronous payments that later failed. Completing the whole list ships goods against every one of those categories. The unpaid ones cost you inventory and shipping with no payment behind them, and you find out at reconciliation.

It skips the payment completion path

WooCommerce records a payment through its own completion flow, which sets the paid date, stores the transaction reference and fires the hooks other systems listen to. A status edit changes the status and little else. The orders then look complete in the admin while reports, exports, accounting integrations and anything keyed to actual payment still treat them as never paid — a second cleanup job you inherit later.

A procedure that holds up

  1. Fix delivery before you touch the backlog. If the endpoint is still broken, the backlog keeps growing while you work through it and you will never know where the boundary was. Get one live payment to complete on its own first — see why webhooks fail to arrive.
  2. Pin down the outage window. Use the gateway's delivery log: find the first failed delivery and the last one. Cross-check against your server or WAF logs. You want two timestamps, not “sometime last week” — every later step depends on that boundary being tight, and a window that is too wide drags in unrelated abandoned checkouts.
  3. Build the candidate list. Filter the order list to pending, on-hold and failed within that window and export it. Do not filter by status alone across all time; that mixes the outage in with your ordinary background of abandoned carts.
  4. Get the gateway's version of the same window. Export the successful payments from the gateway for those dates, including the order reference each payment carries. You now have two lists to reconcile instead of an assumption.
  5. Match on the order reference, not the amount. Same-value payments are common. Match on the reference the gateway stored, then confirm amount and currency agree, then confirm the payment was captured rather than merely authorised and has not been refunded, disputed or reversed since.
  6. Replay whatever is still replayable. Anything inside the gateway's event retention window should be resent from the dashboard rather than repaired on the site. Your payment plugin then processes it exactly as designed, which is a better outcome than any external repair.
  7. Repair the rest through the payment completion flow, recording the transaction reference on each order. Never through a plain status change.
  8. Start with five orders, not five hundred. Complete a small batch, then check what actually happened: did stock reduce correctly, did the right emails go out, did the order notes record the transaction, did your accounting or fulfilment integration pick them up. Only scale up once that batch is clean.

Side effects of completing a large batch at once

Even when every order in the batch is genuinely paid, completing hundreds of them in one action has consequences that are easier to prevent than to undo.

The realistic options at this scale

Approach Verifies payment? Uses the payment completion flow? Effort for hundreds of orders Main risk
Bulk status edit No No Minutes Shipping against payments that never cleared, plus orders with no paid date or transaction reference.
Replaying events at the gateway Yes Yes Feasible, but per event and only inside the retention window Events older than the window cannot be replayed at all.
Manual check, order by order Yes Depends how you complete it Hours to days Fatigue errors, and it stops being realistic well before a few hundred orders.
Automated reconciliation against the gateway API Yes Yes One configured run Another moving part, and it needs read access to the gateway API.

Gateway retention and replay behaviour is documented by the respective providers and can change. Check the current rules for your gateway rather than relying on any third-party summary.

Where PaidRadar fits

PaidRadar performs the verification step mechanically. It scans orders in pending, on-hold or failed inside a look-back window you define, queries the gateway API read-only for each one, and completes only the orders the gateway unambiguously confirms as captured with a matching amount and currency — using WooCommerce's own payment_complete() flow, so paid date, transaction reference, stock and emails behave as they would have on the day. Everything ambiguous is skipped and logged with the gateway's answer next to it, so the backlog you are left with is a short list you can look at by hand.

It never captures, refunds or moves money, it is self-hosted with no account, and it does not replace fixing your webhook delivery — it is the cleanup and the safety net underneath it. Full trade-offs against the other three approaches are in the recovery options comparison.

When you do not need any of this

Questions

Can I just bulk-change all pending orders to completed after an outage?

You can, and it is the one action most likely to cost you money. A bulk edit asserts that every one of those payments succeeded without checking any of them, and the backlog always contains abandoned checkouts, declines and uncaptured authorisations alongside the genuinely paid orders. It also skips the payment completion flow, so the repaired orders carry no paid date or transaction reference.

How do I work out exactly which orders were affected?

Use the gateway's webhook delivery log to find the first and last failed delivery, then filter your order list to pending, on-hold and failed within that window. A tight window keeps ordinary abandoned checkouts out of the candidate list. Cross-check against server or firewall logs if the delivery log is incomplete.

Is replaying the webhooks better than repairing the orders on the site?

Yes, whenever it is still possible. A replayed event is processed by your existing payment plugin exactly as it would have been originally, so nothing about the order is reconstructed after the fact. The limitation is the gateway's event retention window — beyond it there is nothing left to replay and you have to verify against the payment record instead.

Will completing hundreds of old orders send hundreds of customer emails?

It can, and days late. Decide in advance whether those notifications should go out, throttle them if they should, and warn support before you start. The same applies to stock movements and to fulfilment or accounting integrations that will suddenly receive several days of orders at once.

What should happen to orders the gateway cannot confirm?

They should be left alone and listed, not guessed at. Partial payments, currency mismatches, authorisations without capture and payments that were later refunded or disputed all need a human decision. Any automation that completes an order on an ambiguous answer removes the only guarantee that makes automation acceptable here.

How do I avoid the same backlog next time?

Monitor delivery rather than orders. Gateways report failing endpoints and will disable one that keeps failing, so route those notifications somewhere a person reads them. A scheduled reconciliation run is the second layer: it surfaces the gap within hours instead of at month-end, but it is a backstop, not a substitute for working webhooks.

See how PaidRadar works Back to the overview