Where this message comes from
The full string is There was an error processing your order. Please check for any charges in your payment method and review your order history before placing the order again. It is defined in includes/class-wc-frontend-scripts.php (method get_script_data(), parameter i18n_checkout_error) and displayed by client/legacy/js/frontend/checkout.js. It has existed since WooCommerce 8.9, added so that customers check their payment instead of placing the order again.
It only appears on the classic checkout ([woocommerce_checkout] shortcode). The Checkout block, which goes through the Store API, shows a different message.
What it means technically
When the customer clicks “Place order”, the browser sends the form via AJAX to /?wc-ajax=checkout. The message is displayed in three cases:
- the server answers with an HTTP error (500 after a fatal error, 403 from a firewall, 502, 503 or 504 after a timeout);
- the response is not readable JSON (an HTML page, an empty response);
- WooCommerce returns a failure without any message, for example a gateway that declines the payment without saying why.
An expired nonce or a lost session produce their own messages (“We were unable to process your order, please try again.”, “Sorry, your session has expired.”). A cache serving a stale nonce therefore does not explain this particular message.
WooCommerce creates the order before calling the gateway: depending on when the failure happens, you will find a pending order, a paid order, or nothing at all.
Documented causes, from most to least frequent
Ranking based on about fifteen WordPress.org forum threads and WooCommerce GitHub issues: a trend, not a statistic.
- A fatal PHP error in a plugin. Examples found: a
TypeErrorin WooCommerce Square (fixed in 4.9.4), All in One SEO 4.9.6.1 crashing while the order was created, a quote plugin passing an empty status. - The order email crashing. The
mail()function missing on the server, an empty sender address, an SMTP quota reached, or the WooCommerce 10.9.0 regression fixed in July 2026. The trickiest case: the email is sent after the payment, so the customer is charged while seeing an error. - A payment gateway issue. A WooCommerce PayPal Payments 2.9.4 bug on card payments, a failure returned without a message, or a response that is too slow: the server drops the connection although the payment succeeded. This is the scenario that led to the message.
- A request blocked by a firewall. WooCommerce documented 403 errors caused by hosting providers’ ModSecurity rules, triggered by the order attribution cookies (enabled by default since 8.5). On the classic checkout, a 403 displays this message.
No documented case points to HPOS as a direct cause: the only link found is a table desynchronisation that made the 10.9.0 email regression worse.
Diagnose without guessing
- Check the real state. WooCommerce > Orders and your gateway dashboard, at the time of the error. “Processing” with a transaction: the payment went through. “Pending payment” without a transaction: nothing was charged.
- Read WooCommerce > Status > Logs. Three sources matter:
fatal-errors(fatal errors with the call stack),place-order-debug-xxxxxxxx(since 9.9, WooCommerce logs each step of the order and deletes this log when everything went fine; the last logged step shows where the process stopped), and the gateway log if its logging is enabled. - Turn on the WordPress log in
wp-config.php:define( 'WP_DEBUG', true );,define( 'WP_DEBUG_LOG', '/path/outside/web/debug.log' );,define( 'WP_DEBUG_DISPLAY', false );. A path outside the web root avoids awp-content/debug.logreadable by anyone. - Watch the request. Browser Network tab, filter
wc-ajax=checkout, place a test order. JSON with"result":"failure"and"messages":"": a failure without explanation, often the gateway. 500: fatal error, seefatal-errors. 403 with an HTML page: firewall. 502 or 504 after a long wait: timeout. With the Checkout block, the equivalent request is/wp-json/wc/store/v1/checkout. - Isolate the gateway. Test with bank transfer or cheque, then with the gateway in test mode. If the error persists offline, look at emails and plugins, then run a conflict test (Storefront, WooCommerce only) on a staging site.
A snippet to log every checkout attempt
WooCommerce provides no hook to intercept the failure response sent to the browser. This mu-plugin uses woocommerce_before_checkout_process and woocommerce_checkout_order_processed (declared in includes/class-wc-checkout.php), plus WordPress’s shutdown, which also runs after a fatal error. It touches neither the payment nor the message: it writes one line per attempt to the checkout-diagnostic source (duration, HTTP code, last PHP error, order created).
File to create: wp-content/mu-plugins/wc-checkout-diagnostic.php
'checkout-diagnostic',
'duration_s' => round( microtime( true ) - $start, 2 ),
'http' => $http,
'order' => $order ? $order->get_id() : null,
'status' => $order ? $order->get_status() : null,
'gateway' => $order ? $order->get_payment_method() : null,
'php_error' => $error,
);
$level = ( $fatal || ( $http && $http >= 400 ) ) ? 'error' : 'info';
wc_get_logger()->log( $level, 'Checkout attempt (classic checkout)', $context );
},
PHP_INT_MAX
);
} );
How to read it: an error line with "status":"processing" means the customer was charged despite the error. An unusually long duration points to a timeout. No line for an attempt: the request never reached WooCommerce, think of the firewall. php_error may contain an unrelated warning: cross-check with fatal-errors. Delete the file once the cause is found.
What not to do
- Retrying the order blindly. If the failure happens after the payment, every attempt creates one more order and one more charge: a GitHub issue reports five paid orders for a single purchase. This is exactly what the message asks to avoid.
- Hiding or softening the message. It protects the customer against double charges: fix the cause, not the text.
- Leaving error display on in production. Visitors see the errors, and they can break the checkout JSON response.
- Turning off the whole firewall. Ask your host for the ID of the offending rule and a targeted exception.
Worth watching: WooCommerce 11.4, in development, should redirect to the already paid order when a customer resubmits the form after a failure that happened after payment. As of 6 November 2026, the stable version is 11.2.2.
Sources
- Where the message is defined (class-wc-frontend-scripts.php, WooCommerce 11.2.2)
- Message introduced in 8.9 (PR #45961) and original issue (#41527)
- Classic checkout processing (class-wc-checkout.php)
- Order email regression in 10.9.0 (#66143) and duplicate paid orders (#42223)
- 403 errors and ModSecurity firewalls (WooCommerce Developer Blog)
- Redirect to the already paid order, planned for 11.4 (PR #68749)