Appearance
Stripe 決済 技術選定理由
| 項目 | 内容 |
|---|---|
| 親設計 | 決済-アクセス制御-方式選定.md(#2384) |
| 関連 Issue | #2390 決済・購読・アクセス制御 |
| 実装 Issue | #2629 SDK / #2630 Checkout / #2631 Webhook |
| 最終更新 | 2026-07-05 |
1. 目的
有料記事の自サイト決済について、「Stripe の支払いリンクを貼る + 支払い完了テーブル」 という最小イメージと、実際に採用した構成の差分を明文化する。
Payment Link への簡素化、WooCommerce 導入、サブスク追加などの見直し時に、なぜ今の形になっているか を短時間で追えるようにする。
2. 検討した選択肢
親設計(#2384)で比較した主な案と、運用上の「リンクだけ」案を併記する。
| 案 | 概要 | 判断 |
|---|---|---|
| 最小 | Stripe Payment Link を記事に貼る。支払い確認は Dashboard 手動。閲覧権は手動付与 | 不採用(自サイト完結に不向き) |
| C-1 | Stripe Payment Link(静的)+ Webhook + 購入テーブル + アクセス制御 | 設計上は成立。運用の手間が残る |
| C-2(採用) | Stripe Checkout Session API(動的)+ Webhook + 購入テーブル + アクセス制御 + 会員ログイン | 採用(#2629〜#2631) |
| B | WooCommerce 単品 + Stripe 公式プラグイン | 非エンジニアの商品管理向け。プラグイン増を避け今回は見送り |
| A | note 単記事販売 | Phase 1 候補だったが、2026-07 時点で自サイト公開へ移行 |
補足: PCI DSS(カード情報の取り扱い)は、Payment Link でも Checkout Session API でも Stripe Checkout に委譲 する点は同じ。差分は「購入者・記事の紐づけ」と「購入記録の自動化」にある。
3. 採用した構成(サマリ)
| レイヤ | 役割 |
|---|---|
| 会員基盤 | WP 標準ユーザー + member ロール。購入前にログイン必須 |
| 決済 UI | Stripe Checkout(mode: payment、JPY) |
| 購入記録 | db_paid_article_purchase(external_transaction_id で冪等) |
| 閲覧判定 | PaidArticleAccessService(単号購入 or サブスク) |
| 設定 | wp-config.php の Stripe 3 キー(設定手順) |
詳細な API 契約は API-002-1 Stripe Webhook 受信、モジュール構成は commerce-module.md を参照。
4. 「リンク貼り付けだけでは足りない」理由
ここでの「足りない」は、Dashboard で発行した Payment Link を HTML に貼るだけ(Webhook・テーブル・アクセス制御・ログインなし)を指す。
4.1 自サイトで全文を出すには「誰が・何を買ったか」が必要
有料記事は WordPress 上にあり、未購入者にはリードのみ、購入者には全文を出す。Stripe 側で決済が成功しても、WordPress は どの user_id が・どの post_id を購入したか を自動では知らない。
4.2 success ページだけでは購入記録を保証できない
ユーザーが決済後にタブを閉じたり、戻る操作をした場合、success URL だけに頼ると購入記録が欠落する。正本は Webhook(checkout.session.completed)とする。
4.3 ゲスト購入を見送り、WP ログイン必須にした
購入者を wp_users.ID と結びつけないとアクセス制御できない。会員登録・ログイン・member ロールはこの判断の延長(ログイン認証-パスワード設計.md)。
4.4 月次更新(号ごと)の運用を自動化したい
号が増えるたびに Dashboard で Link を手作業発行し、CTA を差し替える運用はミスが蓄積しやすい。価格は db_member_plan_master を正とし、コードから Session を生成する。
5. 静的 Payment Link ではなく Checkout Session API を選んだ理由
#2384 の Phase 2-B(Payment Link + 自前)でも Webhook・テーブル・アクセス制御は必要。C-1 と C-2 の差分は次のとおり。
| 観点 | 静的 Payment Link(C-1) | Checkout Session API(C-2・採用) |
|---|---|---|
| metadata | 購入フローごとに user_id / post_id を載せにくい | Session 作成時に必ず付与(#2630) |
| 価格 | Link ごとに Dashboard 管理。DB と二重管理になりやすい | db_member_plan_master.price を参照して動的生成 |
| 号追加 | 新号のたびに Link 発行・CTA 差し替え | 記事 ID から URL を自動生成 |
| ログイン導線 | 未ログイン購入後の紐づけが複雑化しやすい | 未ログインはログインへ誘導し、購入 URL を redirect_to で保持 |
| 誤設定リスク | 号 A のページに号 B の Link を貼るミス | post_id をサーバー側で固定 |
結論: Payment Link + Webhook でも最小の自サイト決済は成立するが、運用ミスと紐づけ失敗を減らすため Checkout Session API を採用した。
6. 採用構成が回避するリスク
6.1 「リンク + 手動確認」だけだった場合に起きうること
| リスク | 内容 |
|---|---|
| 支払ったのに読めない | Stripe では成功でも WP に購入記録がない |
| 購入者の特定困難 | メール照合など手作業が必要 |
| 号の特定困難 | 記事と Link の対応を人手で管理 |
| 対応遅延・クレーム | 毎回 Dashboard 確認 + 手動付与 |
| 漏洩・不正共有 | パスワード配布型運用に寄りがち(#2384 で note+WP 連携案は却下) |
| 監査・返金対応の弱さ | 購入者・記事・取引 ID の対応表がない |
6.2 採用構成で特に防いでいること
- Webhook 署名検証 +
external_transaction_idによる冪等 INSERT(二重付与・二重課金記録の防止) PaidArticleAccessServiceによる一元的な閲覧判定(テンプレートごとのバラつき防止)- ログイン必須による
user_idの一意な紐づけ
7. トレードオフ(自覚すべきコスト)
採用構成は「リンクだけ」より実装・保守コストが高い。見直しの判断材料として記録する。
| 項目 | 内容 |
|---|---|
| 実装工数 | #2384 見積もり: Payment Link + 自前で 9〜13 日。Checkout API はその上に Session 生成・導線統合を追加 |
| 運用 | STRIPE_* 3 キー・Webhook エンドポイントの本番/テスト管理が必要 |
| 障害時 | 決済成功・DB 未反映時は API-002-1 の手動補正手順 に従う |
| サブスク | 月額サブスク(premium_all_access)は本設計の対象外。必要時は Stripe Subscription Webhook を別設計で定義する |
8. 実装マップ
| Issue | 内容 | 主なパス |
|---|---|---|
| #2629 | Stripe PHP SDK・キー読み取り | core_src/Commerce/Infrastructure/Stripe/ |
| #2630 | Checkout Session 作成 | PaidArticleCheckoutService, PaidArticleCheckoutController |
| #2631 | Webhook 受信・購入記録 INSERT | StripeWebhookService, POST .../commerce/v1/stripe-webhook |
| #2597 | 購入・加入テーブル | db_paid_article_purchase, db_member_subscription 等 |
| #2599 | 閲覧可否判定 | PaidArticleAccessService |
9. 見直しのトリガー
次の条件が揃う場合、Payment Link(C-1)や WooCommerce(B)への縮小・移行を見直してよい。
- 号数が少なく、手動 Link 管理で運用負荷が許容できる
- 非エンジニアが号ごとの価格・商品を頻繁に変えたい(WooCommerce 向き)
- サブスク本格導入で Stripe Billing / Subscription API の設計が別途必要になる
見直し時も Webhook + 購入記録 + アクセス制御 は原則維持する(リンクだけに戻さない)。
10. 関連ドキュメント
- 決済-アクセス制御-方式選定.md — 方式比較・段階導入の親設計
- 会員管理-テーブル設計.md — 購入・加入テーブル定義
- ログイン認証-パスワード設計.md — ログイン必須・閲覧判定フロー
- commerce-module.md — Commerce モジュール構成
- API-002-1 Stripe Webhook 受信.md — Webhook 契約・手動補正
- stripe-api-key-config.md — キー設定手順