WooCommerce checkout errors: what each message means and how to fix it

Every checkout error was written by someone: WooCommerce, the payment plugin, the payment provider's own script, or the server in between. What the common messages mean, and how to trace one that isn't in WooCommerce at all.

Founder of RoundBorders · WordPress since 2012

Published 11 min read

The short answer

Find out who wrote the message before you change anything. Search your plugins for the exact words, read the failed order's notes and WooCommerce → Status → Logs, and look at the checkout request in the browser's Network tab. If the words are in no file on your site, they came from the payment provider's own script.

Rather hand it over? Get a fixed price for the whole job, from $249.

A WooCommerce checkout error is a sentence someone wrote, in one of four places: WooCommerce itself, the payment plugin, the payment provider’s own script, or the server between the customer and your store. The words tell you which, if you know where to look, and the fix depends entirely on which one it is. The hard ones are rarely hard to fix. They’re hard because the message isn’t where anyone looks. Here’s what the common messages mean, how to trace one that isn’t in WooCommerce at all, and four ways it usually plays out.

Where a checkout error comes from

  • WooCommerce itself. Validation and session messages: a required field, shipping, the terms box, an expired session. Their text is in WooCommerce’s own files.
  • The payment plugin. Stripe, PayPal Payments, Square, GoDaddy Payments and the rest write their own messages, usually after the payment provider said no. They live in the plugin’s folder, sometimes deep inside a library the plugin bundles.
  • The payment provider’s script. The card field on most checkouts is a small window loaded from the provider’s servers, and its messages (“Your card number is incomplete.”) come with it. Those words are in no file on your site.
  • The server in between. A PHP error, a firewall, a cache or a timeout breaks the reply to the checkout request, and the browser falls back to WooCommerce’s catch-all.

Plain English The message is a return address. Find out who sent it before you touch a setting, or you’ll fix something that wasn’t broken.

What each checkout message means

The first eight are WooCommerce’s own, word for word from its current code. The last three come from payment plugins.

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

The classic checkout’s catch-all. The browser sent the order and the reply wasn’t the JSON WooCommerce expected, or it came back with nothing to show. It’s almost never about the card. Something on the server broke the reply: a PHP fatal error, a warning printed in front of the JSON, a security plugin or firewall answering with a block page, or a request that timed out. Check WooCommerce → Orders first, because sometimes the payment went through and only the reply failed, which is exactly why the message tells customers to check for charges. Then read the reply itself (step 4 below).

“The response is not a valid JSON response.”

The same failure on the block checkout, which new stores get by default since WooCommerce 8.3. The order goes to /wp-json/wc/store/v1/checkout and something other than JSON came back. Same checks.

“Sorry, your session has expired. Return to shop”

WooCommerce received an order with an empty cart, which means it didn’t recognise the customer’s session. The usual causes: the cart or checkout page is being served from a page cache or a CDN, the session cookie is being dropped (a security plugin, a proxy, or the visit switching between www and the bare domain), or the tab sat open long enough for the session to be cleaned up. Make sure every cache skips cart, checkout and my-account, and skips visitors carrying WooCommerce’s cart cookies.

“We were unable to process your order, please try again.”

The security token on the checkout form (a nonce) didn’t match, but the cart was still there. Nearly always a cached checkout page serving an old token, or the customer logging in or out in another tab after the checkout loaded. A reload fixes it for that customer. Taking the checkout out of every cache fixes it for everyone.

“Invalid payment method.”

The customer picked a payment method WooCommerce no longer counts as available for this order. It was switched off after the page loaded, or its plugin hides it for this currency, country, total or product. When every customer gets it, look at the plugin’s availability rules, and at any plugin that adds or removes payment methods by condition.

“No shipping method has been selected. Please double check your address, or contact us if you need any help.”

Its sibling on the page reads “There are no shipping options available.” Either no shipping zone covers the address, or a method that should cover it returned nothing. With live carrier rates the second is common: the carrier’s API timed out or refused the request, and the rates plugin’s own log says why. Test with the exact address the customer used.

“[Field] is a required field.”

The field is required but the customer couldn’t fill it in: a checkout field editor or the theme hid it, or it only shows for some countries. Compare what the checkout shows with the field editor’s settings.

“Unfortunately your order cannot be processed as the originating bank/merchant has declined your transaction. Please attempt your purchase again.”

This one appears on the order confirmation page, for an order that ended up Failed, typically after an off-site payment or a card check with the bank came back declined. The failed order’s notes, written by the payment plugin, say why.

“An error occurred, please try again or try an alternate form of payment.”

Not WooCommerce. The same sentence is in GoDaddy Payments, PayPal Enterprise Payments (formerly Braintree) and WooCommerce Square: the first two bundle SkyVerge’s payment gateway framework, and Square’s code grew out of it. It’s their “something failed and we won’t say what” message. The provider declined without a reason the plugin passes on, the card form couldn’t reach the provider, or the account behind the plugin can’t take payments: WooCommerce Square uses it for an invalid account, missing permissions and a wrong location, among others. The plugin’s debug log has the real reason (in the SkyVerge-based plugins: Debug Mode → Save to Log). It’s also the message behind the first example below.

“Something went wrong. Please try again or choose another payment source.”

PayPal Payments’ generic error for its buttons and card fields. Its log is in WooCommerce → Status → Logs under woocommerce-paypal-payments, with the reason PayPal gave.

“Stripe.js provenance check failed.”

New in the Stripe plugin 10.9.0 (August 2026): before it takes a payment, the plugin checks that Stripe.js came from js.stripe.com, and blocks the checkout when it didn’t. The browser console explains it with a warning that starts “WooCommerce Stripe Gateway: blocking checkout” and names the address Stripe.js was actually loaded from. A performance plugin that minifies or combines JavaScript, or serves third-party scripts from your own domain, trips it. Exclude js.stripe.com from that plugin’s JavaScript optimisation.

When the message isn’t in WooCommerce

Six checks, in the order I do them. The first two take a minute and usually name the culprit.

1. Copy the exact words, and note where they appeared

A notice at the top of the checkout, a line inside the card box, a popup from a wallet button, the order confirmation page: each points somewhere different. A line inside the card box is almost always the provider’s own script.

2. Search for the words in your plugins

Terminal
grep -rlF "try an alternate form of payment" wp-content/plugins wp-content/mu-plugins wp-content/themes

Search a distinctive part of the sentence, since links and formatting can split the full text. If the store isn’t in English, the words on screen are a translation: search wp-content/languages too, or switch the site to English for the test. No SSH? Most hosting file managers can search, or download wp-content/plugins and search it on your computer.

Read the path of every match. godaddy-payments/vendor/skyverge/… means the message belongs to GoDaddy Payments, whatever library it sits in. And if nothing matches anywhere, that’s an answer too: the words came from outside your server, from the provider’s script or a reply from the provider’s API.

3. Read the order notes and the logs

If an order was created, open it. Payment plugins write the failure into the order notes (“GoDaddy Payments Payment Failed (…)” in the SkyVerge-based ones). Then WooCommerce → Status → Logs: the plugin’s own source (woocommerce-gateway-stripe, woocommerce-paypal-payments, or the gateway’s ID) and fatal-errors for PHP crashes. Most payment plugins only log with their debug setting on, so switch it on, reproduce the error once, and switch it off again.

No order at all means the failure happened in the browser, before the order was ever sent. Skip to steps 4 and 5.

4. Watch the checkout request

Open the browser’s developer tools (F12), go to Network, and place the order. Find the request to ?wc-ajax=checkout on a classic checkout, or checkout under /wp-json/wc/store/v1/ on the block checkout, and open its Response:

  • HTML where JSON should be is the server: a PHP error, a firewall page, a login page. The first lines usually say which.
  • JSON with "code": "woocommerce_rest_checkout_process_payment_error" means the payment plugin failed the payment, and "message" is its text.
  • No request at all means the browser never sent the order: the payment script stopped it first.

5. Read the console

In the same developer tools, the Console tab. Payment scripts report there before the customer sees anything: a script that was blocked, a failed request to the provider, a security policy refusing js.stripe.com, a provider saying the account is invalid.

6. List every payment method that’s switched on

WooCommerce → Settings → Payments, plus the wallet buttons each plugin adds on its own settings screen (Apple Pay, Google Pay, express checkout buttons on product and cart pages). Anything you don’t recognise, or that belongs to an account you’ve closed, is a suspect.

Found the source?

Fix that one thing, then place a real test order as a guest, with a real card, and refund it.

Still a mystery?

Read the four examples below. Each looks impossible from the checkout page.

Four ways it usually plays out

These are the patterns behind most checkout errors that seem to come from nowhere. Each is quick to fix once you know to look for it.

An old payment method nobody switched off

A store takes cards through one provider, say GoDaddy Payments, then moves to Stripe. The old account is closed, but the old gateway stays switched on at checkout, with its Apple Pay and Google Pay buttons. With Stripe’s Optimized Checkout, Stripe’s own option carries a generic title (on the block checkout it reads “Payment methods”), so the only option that says Credit/Debit Card is the old one. Customers who want to pay by card pick it. Its card form can’t get through to the closed account, and its script shows “An error occurred, please try again or try an alternate form of payment.”

Nothing reaches Stripe and no order is created, so WooCommerce’s logs and the order list stay empty. The owner usually hears about it from the one customer who writes in, weeks later. And the sentence isn’t in WooCommerce’s code, so searching WooCommerce for it finds nothing: it’s in the old gateway’s folder (step 2 above).

The fix is to switch off the old gateway and its wallet buttons, then give Stripe’s option its card title back with the filter the Stripe plugin provides for this, keeping Optimized Checkout on:

PHP
add_filter( 'wc_stripe_optimized_checkout_title', function () {
	return 'Credit / Debit Card';
} );

It goes in a code snippets plugin or the child theme’s functions.php.

Stripe.js served from your own domain

A performance plugin combines or minifies JavaScript and pulls third-party scripts in with it. WP Rocket, for example, includes external scripts in the combined file when “Combine JavaScript files” is on. Stripe.js then loads from the store’s own domain, and since version 10.9.0 the Stripe plugin refuses it: “Stripe.js provenance check failed.”, with the console warning naming the address it came from. Depending on the page, the card form doesn’t appear or the payment stops. It can look random, working on some pages and failing on others, because only the pages cached with the optimised copy carry it.

Exclude js.stripe.com from the plugin’s JavaScript optimisation (in WP Rocket: File Optimization → Excluded JavaScript Files, where the domain alone is enough), then clear the cache.

A firewall answers the checkout

A security plugin or the host’s firewall decides the checkout request looks suspicious (a card-testing rule, a rate limit, a country block) and answers it with its own block page. The browser expected JSON, so the customer gets “There was an error processing your order…” on the classic checkout, or “The response is not a valid JSON response.” on the block checkout. The Network tab (step 4) shows the block page, often with the firewall’s name on it. Narrow the rule that caught the checkout request (?wc-ajax=checkout, or /wp-json/wc/store/v1/checkout) instead of switching the protection off: card-testing attacks on checkouts are real, and that rule is usually there for a reason.

A new Stripe account, old saved cards

A store changes Stripe accounts: a new company, a new country, or live mode set up after months of testing. Returning customers still have saved cards tied to a Stripe customer in the old account, and paying with one fails, with Stripe answering “No such customer”. The Stripe plugin 11.0.0 (September 2026) removes stale saved cards at checkout when the Stripe customer no longer exists, so update it first. Until then, the customer can always pay with a new card.

Clear out the payment methods you’ve stopped using

Two of those four start with something nobody was looking at any more. Once a year, or whenever you change payment providers:

  • Switch off, then remove, every gateway you no longer use. A method for a closed account still shows at checkout if it’s enabled, and it fails in the customer’s browser, where you’ll never see it.
  • Check the wallet buttons separately. Apple Pay, Google Pay and express buttons are often settings inside a gateway’s own screen, and some show on product and cart pages too.
  • Remove retired plugins. A PayPal plugin from before PayPal Payments, a gateway for a provider you left: if it’s deactivated, delete it; if it’s active and unused, it still loads code on every page.
  • After any change, test as a guest with a real card on the checkout and on a pay-for-order link, and refund the orders.

If the message turns out to be a PHP crash (“There has been a critical error on this website” on the checkout page), that’s a different job with its own guide: how to fix the critical error. For checkouts that fail without any error at all, the spinner that never finishes and the missing shipping methods, see the 8 usual causes.

When you’ve found the source and the fix is a setting, you’re done. When the words are in no file, the logs are empty and orders are still failing, stop guessing: every hour a checkout is down costs real orders. That’s where our store rescue starts: the cause found the same day, and a fixed price before anything changes.

From the RoundBorders team

Still stuck on a checkout error?

Send the store’s address and what customers see. We find the cause the same day and send a fixed price, usually within a few hours.

  • From $249
  • Same-day diagnosis
  • Tested with a real order
No passwords needed to quote

Write as much as you like: what's happening, what you want, links, errors. The more we know, the more exact your fixed price.

How we work on WooCommerce stores

Share this post

Know a store owner with the same problem? Send it their way.

Bishoy Awad

Written by

Founder of RoundBorders. Building and fixing WordPress sites since 2012; our work is listed in the WooCommerce, Pressable and Jetpack partner directories.

Sources

Found a mistake? Write to me.