決済まわり

WooCommerceでStripe決済が通らない:失敗CSVから原因を特定する

WooCommerceとStripeの組み合わせで「決済できない客がいる」という相談を受けたとき、最初にやるのは推測をやめることです。

「たぶん3Dセキュアでしょう」「カード会社側では」という会話が続くと、いつまでも原因が確定しません。Stripeには失敗した決済の全件データがあるので、それを取って数えます。

結論:CSVを取って、エラーコードごとに数える

  1. Stripeダッシュボードから失敗した決済をCSVでエクスポート
  2. 同じく成功した決済もエクスポート
  3. エラーコードごとに件数を数える
  4. 成功と失敗で何が違うかを比較する

これで「単発の事故」か「構造的な問題」かが即座に分かります。


なぜCSVなのか

ダッシュボードの画面で1件ずつ見ると、印象に引きずられます。目立つエラーが1件あると、それが主因だと思い込む。

数えれば事実が出ます。

  • 失敗50件のうち45件が同じエラーコード → 構造的な問題。実装かアカウント設定
  • 失敗50件がバラバラのエラーコード → 客側の事情。実装は正常な可能性が高い

この分岐が最初に決まらないと、調べる場所が決まりません。


STEP 1: CSVを取る

Stripeダッシュボードの「決済」画面で、ステータスで絞り込んでからエクスポートします。

  • 失敗した決済: ステータス = 失敗
  • 成功した決済: ステータス = 成功

期間は、問題が起きている期間より広めに取ってください。「いつから起きているか」を特定するためです。

エクスポートするカラムに、以下を必ず含めます。

  • 作成日時
  • 金額
  • ステータス
  • エラーコードfailure_code
  • エラーメッセージfailure_message
  • 支払い方法
  • カードブランド
  • カード発行国

STEP 2: エラーコードごとに数える

表計算でもコマンドでも構いません。エラーコードの列で集計します。

# 失敗CSVのエラーコード列を数える(列番号は実際のCSVに合わせる)
cut -d, -f8 failed.csv | sort | uniq -c | sort -rn

Pythonなら以下です。

import csv
from collections import Counter

with open('failed.csv', encoding='utf-8') as f:
    rows = list(csv.DictReader(f))

c = Counter(r.get('failure_code', '') for r in rows)
for code, n in c.most_common():
    print(f'{n:>5}  {code}')

STEP 3: エラーコードを読む

Stripeのエラーコードには意味があります。頻出のものを挙げます。

card_declined

カード会社が拒否しました。さらに decline_code で細分されます。

  • insufficient_funds — 残高不足。客側の事情
  • do_not_honor — カード会社の判断。理由は開示されない。客側
  • generic_decline — 理由不明の拒否。客側が多いが、まとまって出るなら要調査
  • fraudulent — 不正の疑い。まとまって出るなら実装かアカウントの問題

authentication_required

3Dセキュア認証が必要なのに、認証が完了していません。これがまとまって出ているなら実装の問題です。 認証画面への遷移や、認証後の戻りが壊れています。

incorrect_cvc / expired_card / incorrect_number

入力ミス。散発的なら正常です。

processing_error

Stripeまたはカード会社側の一時的な障害。件数が少なければ再試行で解決します。

api_key_expired / authentication_error

実装の問題です。 キーが無効か、モードが混在しています。


STEP 4: 成功と失敗を比較する

エラーコードだけでは分からないことがあります。成功CSVと突き合わせます。

カードブランドで偏りがあるか

特定ブランドだけ失敗しているなら、そのブランドが決済手段として有効化されていない可能性があります。ダッシュボードの「設定 > 支払い方法」を確認してください。

カード発行国で偏りがあるか

海外カードだけ失敗しているなら、Radar(不正検知)が国でブロックしている可能性があります。

金額で偏りがあるか

高額だけ失敗するなら、カード会社の与信限度か、Radarの金額ルールです。

時間帯・日付で偏りがあるか

ある日を境に失敗が始まっているなら、その日に何かが変わっています。プラグイン更新、キー変更、Stripeの仕様変更のいずれかです。変更履歴と突き合わせてください。


WooCommerce固有の注意点

プラグインが複数入っていないか

WooCommerce用のStripeプラグインは複数あります。公式のもの、サードパーティのもの、テーマ同梱のもの。2つ同時に有効になっていると、片方の設定でもう片方が動くという状態になり、症状が不可解になります。

Webhookが二重登録されていないか

プラグインを入れ替えたとき、古いWebhookエンドポイントが残っていることがあります。同じイベントを2回処理して、注文が二重になったり、逆にエラーで両方失敗したりします。

注文ステータスの遷移

Stripeでは成功しているのに、WooCommerceの注文が「支払い待ち」のまま止まる場合、Webhookが届いていません。Stripeダッシュボードの「開発者 > Webhook」で、エンドポイントの成功率を確認してください。

テストモードの注文が残っていないか

本番切り替え後、テストモードで作った注文が残っていると、集計がずれます。切り分けの前に除外してください。


やってはいけないこと

1件のエラーを見て全体を判断する

たまたま見た1件が insufficient_funds(残高不足)だったからといって、他の49件も同じとは限りません。

「Stripeの障害では」で止める

Stripeには稼働状況ページがあります。障害なら公開されています。確認せずに障害のせいにすると、原因が残ったままになります。

本番で試行錯誤する

失敗した決済も、客のカードには一時的に与信がかかることがあります。テストモードで再現してから直してください。


まとめ

決済が通らない原因を推測で議論すると時間が溶けます。全件データがあるのだから、取って数えるのが最短です。

エラーコードの分布を見れば、実装の問題か客側の事情かが5分で分かります。その分岐を確定させてから、詳しく調べてください。


決済が通らなくて困っている方へ

Stripe決済トラブルの調査・復旧を承っています。WooCommerce連携、決済失敗の原因特定、Webhookの不具合など。実データから原因を確定させます。

販売実績58件・評価5.0・出品者ランク プラチナ(2026-09時点)