When checkout breaks on a WooCommerce store, the store owner leads with the last thing they changed. That is usually noise. The gateway had a bad week, a certificate rotated, a webhook had been failing for days. WooCommerce checkout debugging is mostly refusing to chase the story that arrives first, and I found a clean framing for that in a Towards Data Science piece by Subha Ganapathi that runs the plot of Knives Out through Bayesian inference.
The detective in the article never commits to a story on gut feeling. He keeps every hypothesis alive, assigns weights to each, and moves the weights as contradictions arrive. That is a fair description of debugging a store you did not build, and the article is worth reading for how it stages the whole thing.
Start with hypotheses that can’t overlap
The article leans on the MECE rule: every hypothesis should be mutually exclusive and collectively exhaustive. For missing orders on a store, my starting list looks like this.
- a fatal JavaScript error in the theme or checkout block
- the payment gateway plugin failing on the server side
- the gateway’s webhook never reaching the store
- orders are fine and only the order emails are failing
- something outside WordPress: the host, cron, a firewall rule
The article also pushes back on the idea that you assign equal probability to everything, and that matches what I see. Gateways and webhooks get more weight than the theme, because they involve a second server and a queue that can fail in both directions. Custom code gets a low prior on a store where checkout worked untouched for months, and the prior climbs fast once you know a deploy shipped that week.
WooCommerce checkout debugging, step by step
Each check either moves a weight or retires a hypothesis. None of them requires guessing.
- Look at WooCommerce, Orders in the admin before believing “no orders”. If they exist, the email hypothesis jumps and the rest collapse. Order counts can mislead you in other ways, so read the list rather than the dashboard total.
- Open WooCommerce, Status, Logs and read the gateway’s own log, where the source is usually the plugin slug. The wc_get_logger system writes one file per source, so the log stays readable. An empty log on a day with attempts means the request died before the gateway saw it.
- Compare the timestamps in the gateway’s dashboard delivery log against the store’s log. A gap between the two points at the webhook.
- Open the browser console on the checkout page. One red fatal beats a dozen theories.
# what is actually active right now
wp plugin list --status=active
# are scheduled jobs overdue?
wp cron event list
The article is honest that its weights are informed estimates rather than the Bayesian formula, because you cannot put a likelihood on “behaving evasively”. Mine are too. The numbers are a discipline for keeping several stories alive at once.
If your store is losing orders right now and you want another pair of eyes on it, this is the kind of work I do. Send me the gateway log file and the last failed order reference, and I can tell you which hypothesis is winning.
When the model converges on the wrong answer
By the end of the article the probabilities have still not converged on the actual cause of death, because the truth was layered, a suicide engineered by somebody else. Stores have this exact failure mode. Your hypothesis list is exclusive by construction, but stores often break from two causes at once. An object cache serving a stale checkout script while the webhook fails quietly behind it will show the same symptom from two directions.
You fix one thing, the symptom survives, and the weights barely move. When that happens, suspect the list and not the evidence. Split the broad hypotheses, add compound ones, and run the checks again with WP_DEBUG and WP_DEBUG_LOG on. A strong prior can talk you out of fresh data if you let it, and good debugging habits are mostly guardrails against that.
What I run before touching any code
Most of the work comes down to four checks: the orders list, the gateway log, the browser console, and the cron list. They take ten minutes, and they put real evidence behind the weights before you open a single file.
If the gateway log goes quiet in the middle of a busy day, the failure is outside the store, and theme work will not move it.