2026年11月13日
2026年11月13日
Fix WooCommerce Stripe Errors: Connection, Webhooks, 3DS and Refunds
This article is a localized edition of the Japanese original. Read the Japanese original
Most problems with the official "WooCommerce Stripe Payment Gateway" extension come down to one of three things: the connection to your Stripe account, webhooks (notifications from Stripe to your site), or mixing up test mode and live mode. This article narrows down the cause from the symptom and shows how to confirm it in the extension's settings and logs.
Screen names and steps follow the official WooCommerce.com documentation for the Stripe extension as of October 2026.
Symptoms and where to look
| Symptom | Main cause | Section |
|---|---|---|
| Cards are declined at checkout | The card issuer's decision, or wrong card details | 2, 3 |
| The payment is recorded in Stripe but the order stays "Pending payment" | Webhooks aren't arriving, or they fail validation | 4 |
| Orders don't complete after 3D Secure authentication | Authentication abandoned, or webhooks not arriving | 4, 5 |
| You refunded in the admin but Stripe shows no refund | You used the manual refund | 6 |
| Payments work in testing but fail in production (or the other way round) | Test mode setting | 1 |
| Stripe payment methods don't appear at checkout | Extension disabled, incomplete connection, or JavaScript errors | 1, 2 |
1. Check the connection and test mode
The settings are under "WooCommerce → Settings → Payments → Stripe". In the official documentation, the settings are grouped as follows.
| Section | What to check |
|---|---|
| General | Is "Enable Stripe" on? Has "Enable test mode" been left on? |
| Account details | Are Payment and Payout (account status) and Webhook and Sync (connection status) all enabled? |
| Advanced settings | Turn on "Log error messages" only while troubleshooting |
While test mode is on, payments go through the test account, so real cards can't be charged and nothing is recorded on the live side of Stripe. Turn it off for production. Conversely, test card numbers don't work in live mode.
Clicking "Configure connection" under "Account details" shows the connection status for both Live and Test. If the status is "Incomplete", you may need to re-authenticate your Stripe account. Connecting requires the site to use HTTPS and be reachable from the internet.
2. Turn on logging and read the logs
Before investigating, turn on "Log error messages" under "Advanced settings" and try the payment again. Entries are written to the WooCommerce log.
- In the admin, open "WooCommerce → Status → Logs" and select the log whose source is
woocommerce-gateway-stripe. - Searching the page for the order number makes it easy to find that order's entries. A payment entry includes the order number, the Payment Intent ID (starting with
pi_), the Charge ID (ch_), the customer ID (cus_), and, if declined, the reason.
If the card fields don't appear on the checkout page or it never finishes loading, also check the browser's developer tools console for JavaScript errors. Script errors in other plugins or the theme can stop the Stripe fields from working.
When you're done, turn "Log error messages" off again.
3. When cards are declined
The reason for a decline is recorded in the log and in the payment details in the Stripe Dashboard as a Stripe error code. The common ones are:
| Code | Meaning | What the site can do |
|---|---|---|
card_declined (generic_decline) |
The card issuer declined without giving a reason | Ask the customer to use another card or contact their card issuer |
card_declined (insufficient_funds) |
Insufficient balance or credit limit | Same as above |
expired_card |
The card has expired | Ask the customer to enter a valid card |
incorrect_cvc |
Wrong security code | Ask the customer to enter the correct value |
These come from the card issuer or the details entered, and changing site settings won't fix them. If the same errors appear in test mode, check that you are using test card numbers. Commonly used test cards published by Stripe are listed below (use any future expiry date and any 3-digit CVC).
| Card number | Result |
|---|---|
4242 4242 4242 4242 |
Succeeds without authentication |
4000 0027 6000 3184 |
Always requires 3D Secure authentication |
4000 0000 0000 0002 |
Declined (generic_decline) |
4000 0000 0000 9995 |
Declined (insufficient_funds) |
4. Check that webhooks arrive
Stripe uses webhooks to tell your site about results such as successful or failed payments and refunds. The extension updates orders when it receives them, so if webhooks don't arrive, the payment succeeds in Stripe but the order stays "Pending payment".
Check the webhook status
According to the official documentation, since version 8.6.1 of the extension, webhooks are set up automatically when you connect to Stripe. Check their status as follows:
- Open "WooCommerce → Settings → Payments → Stripe"
- Click "Configure connection" under "Account details"
- On both the Live and Test tabs, check that the webhook status shows "Configured"
If you upgraded from an older version or deleted the webhooks in the Stripe Dashboard, click "Reconfigure webhooks" on both the Live and Test tabs of the same screen. This recreates the correct webhooks and removes old ones pointing to your site.
The only webhook endpoint this extension uses is a URL of the form https://example.com/?wc-api=wc_stripe. Any other endpoints in the Stripe Dashboard probably belong to other payment plugins or external services.
Is your site accepting the notifications?
In the Stripe Dashboard you can see the delivery history for each webhook and the status your site returned. If deliveries keep failing, check whether something on your site is blocking them:
- Is Basic authentication or an IP address restriction applied to the whole site or to
/?wc-api=wc_stripe? - Is a security plugin, WAF or CDN firewall blocking POST requests from Stripe?
- Is a maintenance mode plugin blocking all visitors who aren't logged in?
If notifications arrive but fail validation, the log shows Webhook validation failed (reason). Use the reason to tell causes apart.
| Reason in the log | Meaning | Fix |
|---|---|---|
signature_mismatch |
The signature doesn't match (wrong webhook secret, or duplicate webhooks pointing to the same site) | Recreate them with "Reconfigure webhooks" |
empty_secret |
No webhook secret is saved | Recreate them with "Reconfigure webhooks" |
timestamp_out_of_range |
The notification time and the server time differ by more than 5 minutes | Check the server's time synchronization (NTP) |
signature_invalid / empty_headers |
The signature header isn't reaching the site | Check whether a proxy or WAF is stripping headers |
5. Orders don’t complete after 3D Secure
For cards that require 3D Secure (cardholder authentication), the payment is finalized after the customer completes the card issuer's authentication screen. If the customer closes that screen or goes back partway through, the payment isn't finalized and the order stays "Pending payment". That is expected behavior.
If the customer completed authentication and the order still isn't updated, check the webhooks in section 4. In test mode, you can check the whole flow by using 4000 0027 6000 3184, approving on the authentication screen, and confirming that the order moves to a paid status such as "Processing".
The site must run on HTTPS. An expired certificate or a mixed HTTP/HTTPS setup (for example, a site address still set to http://) can break the return from the authentication screen or the notifications.
6. Refunds don’t reach Stripe
When you click "Refund" on the WooCommerce order edit screen and enter an amount, two kinds of buttons appear.
- The button that refunds via the payment method ("Refund ¥… via (payment method name)"): asks Stripe to issue the refund and records the result on the order.
- The manual refund button ("Refund ¥… manually"): only records a refund on the WooCommerce order and sends nothing to Stripe.
If you refunded in the admin but the customer's card wasn't refunded, check whether you used the manual button. If you recorded it manually, issue the refund from the payment details in the Stripe Dashboard. If a refund via Stripe fails, the reason is recorded in the log from section 2.
If you refund directly in the Stripe Dashboard, the refund is reflected on the WooCommerce order as long as webhooks arrive.
7. If it still isn’t fixed
- When the site can't reach the Stripe API, a notice appears at the top of the WordPress admin. According to the official documentation, it usually clears within minutes. If it persists, check Stripe's status page or your hosting company's network status.
- Update the extension, WooCommerce, WordPress and PHP to recent versions and check whether the problem still occurs.
- If you can't interpret the log, contact WooCommerce support with the order number and the relevant part of the log.
Related articles
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)