WooCommerce Errors
WooCommerce Stripe Payment Failed (WordPress Repair)
Last reviewed
Direct answer
A WooCommerce Stripe payment usually fails because test/live mode or keys are wrong for the current domain, the PaymentIntent is declined or blocked, webhooks never confirm the charge back to WooCommerce, or a script/SSL/plugin conflict stops Stripe.js at checkout. Enable Stripe logging, reproduce once, then read WooCommerce Stripe logs and the Stripe Dashboard before rotating live keys.
This is WordPress Repair for a store that can build a cart but cannot take Stripe money — shoppers see a decline, a spinning Place order button, or a failed order while Stripe may show a different status. This guide separates issuer declines and Radar blocks from WooCommerce connection, webhook, and front-end failures so you fix the layer that actually broke. Work from logs outward; do not keep retrying live cards on a broken webhook path.
Key facts
Verifiable numbers and definitions — each claim links to its source.
- WooCommerce’s Stripe troubleshooting docs recommend enabling Log error messages so failures appear in WooCommerce → Status → Logs while you test checkout. (Troubleshooting the Stripe extension)
- Stripe payment failures fall into issuer declines, blocked payments (including Radar), and invalid API calls — each with different Dashboard/API outcomes. (Stripe declines)
- Typical Stripe log lines for a card attempt include the WooCommerce order number plus Stripe IDs such as charge (`ch_`) and PaymentIntent (`pi_`). (Troubleshooting the Stripe extension)
- WooCommerce payment gateways register through the Payment Gateway API; Stripe is an extension that processes checkout via that interface. (WooCommerce Payment Gateway API)
What the error means
Stripe on WooCommerce is a timeline: the Stripe extension loads payment fields (often via Stripe.js), creates or confirms a PaymentIntent with Stripe’s API, the issuer or Radar accepts or rejects the charge, then webhooks and the extension update the WooCommerce order. Failure can happen at any hop — missing JavaScript, API authentication errors, `card_declined` / Radar blocks, or successful charges that never sync because the webhook URL still points at staging. WooCommerce → Status → Logs (Stripe) and the Stripe Dashboard payment detail both name decline codes and connection errors that the checkout page usually hides behind a generic “payment failed” message.
Common symptoms
- Place order returns “payment failed,” a generic decline, or an endless spinner with Stripe selected
- Stripe card fields never render, stay blank, or show a JavaScript console error on checkout
- Test mode cards succeed while live mode fails (or the reverse) after a recent settings change
- Stripe Dashboard shows a successful PaymentIntent/charge but the WooCommerce order stays Pending payment or Failed
- WooCommerce Stripe logs show API, authentication, or webhook signature errors at the failure time
- Only Stripe fails while other gateways or offline methods still complete
- Webhook or account status in WooCommerce → Settings → Payments → Stripe shows warnings or failed deliveries
Most likely causes
- 01 Stripe extension left in test mode, or live/test keys and webhooks mismatched after a migration or reconnect
- 02 Issuer decline, insufficient funds, incorrect CVC, or Stripe Radar / rule block — not a WooCommerce bug
- 03 Webhook endpoint still aimed at a staging URL, old domain, or disabled after repeated delivery failures
- 04 SSL, mixed content, or a script optimizer blocking Stripe.js so the PaymentIntent never starts
- 05 Plugin or theme JavaScript conflict preventing the Stripe payment method from initializing at checkout
- 06 Security plugin, host WAF, or Cloudflare rule blocking Stripe webhook IPs or checkout REST calls
- 07 Outdated WooCommerce Stripe Gateway relative to WooCommerce core after an update
What changed before the problem started
- WooCommerce Stripe Gateway plugin was updated, reconnected, or switched between test and live
- Domain, SSL, www vs non-www, or staging→live cutover changed webhook URLs
- WooCommerce or WordPress core update changed checkout scripts or REST behavior
- Security, Cloudflare, or optimization plugins were tightened around checkout assets
- Stripe account verification, Radar rules, or payout/capability status changed in the Stripe Dashboard
Troubleshooting steps
- 01
Reproduce once and capture order number, time, and exact message
Use a private window as a guest. Note whether fields render, whether Place order spins, and the on-screen error. Prefer Stripe test mode and documented test cards while diagnosing — do not burn real customer cards to “see if it works.”
- 02
Confirm Stripe is enabled and test vs live mode matches your keys
Open WooCommerce → Settings → Payments → Stripe. Confirm Stripe is enabled, Account details show healthy Payment/Webhook status when available, and you are not accidentally in test mode on a live store (or live mode with test keys).
- 03
Enable logging and read WooCommerce → Status → Logs for Stripe
Turn on Log error messages in the Stripe extension’s advanced settings if needed, reproduce once, then open the `stripe` (or similarly named) log. Match the WooCommerce order number to PaymentIntent (`pi_`), charge (`ch_`), and any decline or API error text.
- 04
Compare the same payment in the Stripe Dashboard
In Stripe → Payments, open the matching PaymentIntent. Issuer declines, Radar blocks, and invalid API calls are labeled differently there than on the WooCommerce thank-you path — that tells you whether to fix cards/Radar, keys, or webhooks.
- 05
Verify webhook delivery to the live HTTPS domain
In Stripe and in the extension connection status, confirm webhooks hit your current live domain and show recent successes. After a migration, recreate webhooks aimed at production so charges stop completing in Stripe while WooCommerce orders stay stuck.
- 06
Inspect the browser console on checkout, then conflict-test if scripts fail
Look for blocked Stripe.js, mixed content, or failed XHR/fetch to Stripe or `/wc-api/` / Store API routes. If scripts fail, conflict-test on staging with a default theme and only WooCommerce + Stripe active before changing live API keys.
When to stop troubleshooting
Stop live experimentation if customers are charged without matching orders, you cannot interpret Stripe decline codes confidently, the Stripe account is under review or restricted, or diagnosis needs live secret keys you do not control. A broken Stripe path during active sales is a strong case for professional WordPress Repair rather than more live card retries.
Information to collect before requesting help
- 01 Exact checkout error text and whether Stripe fields rendered
- 02 WooCommerce order number and matching Stripe PaymentIntent or charge ID
- 03 WooCommerce Stripe Gateway version and WooCommerce core version
- 04 Whether test mode succeeds while live mode fails (or the opposite)
- 05 Stripe log excerpt and Stripe Dashboard outcome/decline reason
- 06 Webhook URL and recent delivery status
- 07 Any charges in Stripe with no matching WooCommerce order
- 08 Recent domain, SSL, plugin, or security rule changes
How a professional repairs the problem
A pro maps the failure across the Stripe request timeline — front-end scripts, API/PaymentIntent, issuer or Radar decision, webhook confirmation — then fixes the broken hop. They rebuild webhooks on the live domain, rotate credentials safely through Stripe’s connect flow, reconcile orphaned charges, conflict-test checkout scripts when needed, and confirm a clean test-mode (then carefully monitored live) transaction before returning the store to full traffic.
Frequently asked questions
Why does Stripe work in test mode but fail in live mode? +
A customer was charged in Stripe but no order appeared — what now? +
Is every “card declined” message a WooCommerce bug? +
Can a caching or optimization plugin break Stripe? +
Should I switch to another gateway to fix this? +
Where do I enable Stripe logging in WooCommerce? +
Repair dispatch
Still Need Help Fixing Your Website?
If you are not comfortable editing website files, changing server settings, repairing a database, or troubleshooting a live website, professional help may prevent additional damage or downtime. We will review the problem before accepting the repair.
- You will receive a clear explanation of the likely cause.
- We will tell you if the issue falls outside our repair scope.
- No additional work will be performed without approval.
- A backup should be created whenever access and website condition allow it.
Do not share passwords through an unencrypted contact form — use Password Pusher (self-destructing link). Prefer a dedicated Rescue 404 admin account, not your personal owner login; if you cannot create one yet, we will add ours after repair.