Skip to content
WooRescueHQ

WooCommerce / Payments

WooCommerce Payment Failed but Customer Was Charged

Short answer

The payment and the order update are two separate steps. When the provider confirms a payment but WooCommerce never receives, accepts or finishes processing that confirmation, the money is taken and the order stays pending, failed or cancelled. Compare the provider's event log, the order notes and the gateway log for one affected order: the first point where they disagree is where the confirmation was lost.

Symptoms

  • The provider's dashboard shows a successful charge; the WooCommerce order is Pending payment, Failed or Cancelled.
  • The customer was charged but received no order confirmation email, or no order exists at all.
  • Orders change to Processing hours later, or only after the customer contacts you.
  • The customer was charged twice and two orders exist, only one of them paid.

Most common causes

  1. The notification never reached the store. The provider's server-to-server callback or webhook was blocked by a firewall, WAF, CDN bot protection, basic authentication, a maintenance-mode plugin or a geo-block.
  2. The notification was redirected. An HTTP→HTTPS or www/non-www redirect on the callback URL. Many providers treat a redirect as a failed delivery.
  3. The notification was rejected. A wrong webhook secret or signing key — for example after re-creating the webhook endpoint, or mixing test and live keys.
  4. The store failed while processing it. A PHP error in code that runs when an order is paid — stock, emails, an ERP sync — interrupted the update.
  5. The order was no longer pending. The hold-stock timeout cancelled it before a delayed confirmation arrived, or the customer paid on an old order tab.
  6. The redirect was the only confirmation. The customer closed the window after paying or after 3D Secure, and the store relied on the browser redirect instead of a server notification.
  7. The order could not be matched. Custom order numbers, multisite or a changed order reference prevent the gateway plugin from finding the order.

Diagnosis

1. Pick one affected order and build its timeline

From three sources, write down every event with its exact time:

Source What to note
Payment provider dashboard Payment created, authorised, captured; notification/webhook attempts and their responses
WooCommerce order notes Status changes and gateway messages, with timestamps
Gateway log (WooCommerce → Status → Logs) Incoming notifications, validation results, errors

The first event that appears in the provider but not in the store is where the confirmation was lost.

2. Check the provider's delivery log

Most providers show each notification or webhook attempt with its response code. Read them:

  • Timeout or connection error — the store did not answer in time, or the request never reached it.
  • 3xx — the callback URL redirects; update it to the final URL.
  • 401 / 403 — authentication, a security plugin or a WAF blocked it.
  • 400 — the gateway plugin rejected it, often a signature or secret mismatch.
  • 500 — PHP failed while processing it. Look for a fatal error at that timestamp.

3. Confirm the request reached the server

Search the web server access log for requests to the callback URL at the times the provider reports. The URL depends on the gateway plugin — often a ?wc-api= URL or a REST endpoint. No entry at all means the request was blocked before PHP: CDN, WAF or firewall.

4. Look for errors during order processing

If the notification reached the store and was accepted, find out what happened next: a fatal-errors entry, a PHP error, or a failed scheduled action at the same minute. Code hooked to woocommerce_payment_complete or to order status changes runs inside the notification request; if it fails, the order may never be saved as paid.

Logs and technical checks

  • Provider: event log and webhook/notification delivery history for the affected payments.
  • WooCommerce → Status → Logs: the gateway's log source and fatal-errors.
  • Web server access and error logs for the callback URL.
  • WooCommerce → Settings → Products → Inventory: the Hold stock time that cancels unpaid orders.
  • Tools → Scheduled Actions: failed or pending actions created around the payment time.
  • Security plugin, CDN and WAF logs for blocked requests to the callback URL.

Solutions

  • Make the callback URL reachable: exclude it from WAF challenges, bot protection, maintenance mode, basic authentication and caching. Use the final URL without redirects.
  • Fix the webhook secret in the gateway settings to match the endpoint configured at the provider, separately for test and live mode.
  • Fix the code that fails during payment processing, and move slow work — ERP syncs, external calls — to background jobs so the notification request finishes quickly.
  • Make sure server notifications are enabled, so the order does not depend on the customer's browser returning to the store.
  • Reconcile affected orders: for each successful payment without a paid order, verify amount, currency and customer, then complete or recreate the order through the gateway's or WooCommerce's normal tools, with an order note describing the verification.

What not to do

  • Do not disable signature verification "to make it work". It lets anyone mark orders as paid.
  • Do not delete failed or cancelled orders: they are the evidence and the link to the payment.
  • Do not refund or charge customers again before reconciling both sides.
  • Do not raise the hold-stock time as the fix. It hides late confirmations instead of fixing them.

When to contact an expert

Contact an engineer when charges without orders keep happening, when you cannot tell which orders are affected, when the gateway plugin's logs show nothing at all, or when the failure is inside custom code that runs after payment.

Frequently asked questions

Why does WooCommerce say payment failed when the customer was charged?

Because the store did not get or could not process the provider's confirmation. Common causes are a blocked or redirected notification URL, a wrong webhook secret, a PHP error while the order was being updated, or the order having been cancelled before the confirmation arrived.

Why was the order cancelled even though the customer paid?

With stock management enabled, WooCommerce cancels unpaid orders after the hold-stock time. If the confirmation arrives after that, it finds a cancelled order. Late confirmations are usually a symptom of webhooks or notifications failing on the first attempts.

Can I just mark the order as processing?

Only after confirming the payment in the provider's dashboard and matching amount, currency and customer. Add an order note explaining what was verified. Fix the cause too, or it will happen again.

How do I find all affected orders?

Export successful payments from the provider for the affected period and match them against WooCommerce orders by order number, transaction id or amount and email. Payments without a matching paid order are the ones to reconcile.

$ describe the problem

Have a WooCommerce problem?Request a diagnosis.

Tell us what is failing, what changed recently and the business impact. We review every request and recommend the appropriate next step.

Request a diagnosis See services and prices

Never send passwords, API keys or card data through the form.

Diagnosis from€299

Request a diagnosis