Appearance
有料記事 Stripe Checkout / Webhook E2E 方針
Issue #2708 で確定した、Stripe Checkout 外部画面と checkout.session.completed Webhook 反映までを含むテストの方針です。
サイト内の未購入・購入済み表示制御や DB fixture による購入済み判定は、本ドキュメントの対象外です。そちらは 有料記事 E2E fixture 実行ガイド と Playwright E2E 実行ガイド を参照してください。
手動の通し確認手順は 有料記事決済 シナリオテスト手順 を正とします。
禁止事項
- Stripe live キー(
rk_live_/sk_live_/pk_live_)や本番カードを使わない - 本番 URL、実ユーザー、実購入履歴に対して E2E / シナリオを実行しない
STRIPE_SECRET_KEY/STRIPE_PUBLISHABLE_KEY/STRIPE_WEBHOOK_SECRETを GitHub Actions secrets や CI 環境変数に載せない(既存どおりwp-config.phpのdefineのみ)
判断基準
| 基準 | 方針 |
|---|---|
| アプリ内ロジック(分岐・DB・表示) | 自動化必須(PHPUnit / 通常 Playwright) |
| 外部 UI だが決定的(Checkout + テストカード + CLI Webhook) | Local 専用 Playwright で自動化する |
| Dashboard 再送 UI・実メール到達・Staging 実機 | 手動(または PHPUnit で論理を担保し手動は任意) |
| CI Quality Gate に載せられるか | Local WP・Stripe CLI・秘密情報・flaky のため 載せない(自動化しない、ではない) |
シナリオ別の線引き
| シナリオ | 層 | 方針 | 理由 |
|---|---|---|---|
| 未ログイン / 未購入 CTA / 購入済み全文 / REST マスク / 二重購入ガード | Playwright 通常 + fixture | 自動化済み(維持) | Stripe 不要でデグレ検知に最適 |
| Checkout 作成分岐・Webhook 署名 / 冪等 / 通知・Access | PHPUnit | 自動化済み(維持) | 外部 UI なしで高速・安定 |
| S5 正常購入(Checkout → テストカード → Webhook → 全文) | Playwright Stripe 専用 | 自動化済み(Local) | 通しの回帰価値が最も高い |
| S9 Checkout キャンセル | Playwright Stripe 専用 | 自動化済み(Local) | 戻り URL・未購入維持は決定的 |
| S10 失敗カード | Playwright Stripe 専用 | 自動化済み(Local) | Stripe 公式 decline テストカードで再現可能 |
| S6 Webhook 再送の二重作成なし | PHPUnit 正 / 手動は任意 | E2E 自動化しない | 冪等は Unit で十分。Dashboard 再送 UI は価値が薄い |
| S14 / S15 管理者メール実到達 | PHPUnit 正 / 手動は任意 | E2E 自動化しない | 文面・発火条件は Unit 済み |
| S3 / S4 未認証・規約未同意 | PHPUnit + 必要なら通常 E2E | 既存 Unit 優先 | Checkout 到達前の自前分岐 |
| Staging 通しスモーク | 手動シナリオ | 手動維持 | 環境差・Dashboard Webhook の最終確認 |
実行環境マトリクス
| 環境 | Stripe 通し | 備考 |
|---|---|---|
| Local | 自動化対象(npm run test:e2e:paid-article-stripe)+ 手動シナリオ | rk_test_ 推奨(sk_test_ も可) / Stripe CLI listen / テストカード |
| Staging | 手動シナリオのみ | Dashboard の Webhook endpoint。live キー禁止 |
| CI Quality Gate | 非対象 | GitHub-hosted から Local WP に届かない。STRIPE_* を CI に載せない |
STRIPE_* の設定手順は Stripe API キー設定 を参照してください。
レイヤ別の責務
- PHPUnit — Checkout Session 作成分岐、Webhook 署名検証・冪等 INSERT・管理者通知、アクセス判定の論理
- 通常 Playwright(
npm run test:e2e) — サイト内表示制御と REST マスク。DB fixture(external_provider = 'manual_test')。Checkout 外部画面は含めない - Stripe 通し Playwright(#2730) — S5 / S9 / S10。通常 E2E から分離した opt-in script
- 手動シナリオ — Staging スモーク、S6 / S14 / S15 の実操作補完、自動化前の通し確認
後続実装の前提と受け入れ条件
Stripe Checkout 通し Playwright を実装する Issue #2730 では、次を満たすこと。
前提
- Local の WordPress が起動している
wp-config.phpにテストモードのSTRIPE_*が設定されている- Stripe CLI で
checkout.session.completedを Local の Webhook へ転送できる
bash
stripe listen --forward-to <local-origin>/wp-json/commerce/v1/stripe-webhookLocal では stripe listen が出力する Signing Secret(whsec_...)を STRIPE_WEBHOOK_SECRET に使う(Dashboard endpoint 用の secret とは別)。
- 専用のテスト会員・テスト有料記事を使う(実ユーザー・実購入済み記事は使わない)
- 単号購入価格(
paid_article_single)が Checkout 可能な金額になっている
実装上の分離
- 別 npm script(例:
test:e2e:paid-article-stripe)または別 Playwright project とする - 通常の
npm run test:e2e/test:e2e:paid-article-accessからは実行されない - CI Quality Gate(
.github/workflows/ci-quality-gate.yml)には載せない
自動化するシナリオ
- S5 — 購入 CTA → Checkout → 成功テストカード → Webhook 反映待ち(DB または全文表示の polling)→ 全文閲覧
- S9 — Checkout キャンセル(または戻る)→ 記事へ戻り未購入のまま
- S10 — decline テストカード → サイト側に購入権限が付与されない
片付け
external_provider = 'stripe'かつ当該テストの Checkout Session ID(cs_test_...)に限定して購入履歴を削除するexternal_provider = 'stripe'だけを条件にした広範な DELETE は行わない
受け入れ条件(後続 Issue)
- live キー・本番カード・本番 URL を使わない
- S5 / S9 / S10 が Local で再現できる
- 通常 E2E と CI から分離されている
- 実行手順と片付けがドキュメント化されている
実行手順(Local・手動)
前提は上記「後続実装の前提と受け入れ条件」と同じです。Stripe CLI の転送例:
bash
stripe listen --forward-to http://slotkouryaku.local/wp-json/commerce/v1/stripe-webhookstripe listen が出力する whsec_... を Local の STRIPE_WEBHOOK_SECRET に設定したうえで、別ターミナルで次を実行します。
bash
npm run test:e2e:install # 初回のみ
npm run test:e2e:paid-article-stripeブラウザを表示する場合:
bash
npm run test:e2e:paid-article-stripe:headedこちらでは Checkout への遷移・カード入力(またはキャンセル)・記事への戻りまで画面操作が流れます。通常の test:e2e:headed(access 系)は記事を開いて表示を断言するだけで、Checkout 操作は含みません。
| シナリオ | 内容 | テストカード |
|---|---|---|
| S5 | 正常購入 → Webhook → 全文 | 日本 Visa 4000 0039 2000 0003(代替: 日本 JCB 3530 1113 3330 0000) |
| S9 | Checkout キャンセル → 未購入維持 | (カード入力なし) |
| S10 | 決済失敗 → 権限なし | 4000 0000 0000 0002(汎用 decline。日本専用 decline は公式に無し) |
通常の npm run test:e2e / test:e2e:paid-article-access では Stripe 通しは実行されません。Playwright project paid-article-stripe は SLOT_KOURYAKU_E2E_STRIPE=1 のときだけ登録され、専用 npm script からのみ起動します(素の npx playwright test でも Stripe suite は出ません)。
トラブルシュート
「購入処理を開始できませんでした」で止まる
Checkout 開始(admin-post.php?action=paid_article_checkout)が Stripe Session を作れず wp_die した状態です。Local ではまず wp-config.php に STRIPE_SECRET_KEY(rk_test_... 推奨。sk_test_... も可)があるか を確認してください。未設定だと購入 CTA は出ても Checkout へリダイレクトできません。設定手順は Stripe API キー設定 を参照。
あわせて確認すること:
STRIPE_PUBLISHABLE_KEY(pk_test_...)も同ファイルに定義するstripe listen --forward-to http://slotkouryaku.local/wp-json/commerce/v1/stripe-webhookを起動し、表示されたwhsec_...をSTRIPE_WEBHOOK_SECRETに設定する(Dashboard の endpoint secret とは別)- WP-CLI 用の
WP_CLI_BIN/WP_ROOTも通常 E2E と同様に設定する
キー追加後は Local の PHP を再読み込み(サイト再起動やリクエスト再試行)してから npm run test:e2e:paid-article-stripe:headed を再実行します。
片付け
テストは成功時・失敗時ともに、次を自動で行います。
external_provider = 'stripe'かつ当該cs_test_...(S5 で捕捉した Session ID)の購入履歴を削除- fixture のユーザー・投稿・
manual_test行・価格復元(既存cleanup)
手動で残った Stripe 行を消す場合も、Session ID を必ず条件に含めます(external_provider = 'stripe' 単独の DELETE は禁止)。
関連
- Parent: #2702
- 方針 Issue: #2708
- 後続実装 Issue: #2730
- 有料記事決済 シナリオテスト手順
- Playwright E2E 実行ガイド
- 有料記事 E2E fixture 実行ガイド
- CI 運用方針
- Stripe Testing