Skip to content

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-1Stripe Payment Link(静的)+ Webhook + 購入テーブル + アクセス制御設計上は成立。運用の手間が残る
C-2(採用)Stripe Checkout Session API(動的)+ Webhook + 購入テーブル + アクセス制御 + 会員ログイン採用(#2629〜#2631)
BWooCommerce 単品 + Stripe 公式プラグイン非エンジニアの商品管理向け。プラグイン増を避け今回は見送り
Anote 単記事販売Phase 1 候補だったが、2026-07 時点で自サイト公開へ移行

補足: PCI DSS(カード情報の取り扱い)は、Payment Link でも Checkout Session API でも Stripe Checkout に委譲 する点は同じ。差分は「購入者・記事の紐づけ」と「購入記録の自動化」にある。

3. 採用した構成(サマリ)

レイヤ役割
会員基盤WP 標準ユーザー + member ロール。購入前にログイン必須
決済 UIStripe Checkout(mode: payment、JPY)
購入記録db_paid_article_purchaseexternal_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 だけに頼ると購入記録が欠落する。正本は Webhookcheckout.session.completed)とする。

4.3 ゲスト購入を見送り、WP ログイン必須にした

購入者を wp_users.ID と結びつけないとアクセス制御できない。会員登録・ログイン・member ロールはこの判断の延長(ログイン認証-パスワード設計.md)。

4.4 月次更新(号ごと)の運用を自動化したい

号が増えるたびに Dashboard で Link を手作業発行し、CTA を差し替える運用はミスが蓄積しやすい。価格は db_member_plan_master を正とし、コードから Session を生成する。

#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内容主なパス
#2629Stripe PHP SDK・キー読み取りcore_src/Commerce/Infrastructure/Stripe/
#2630Checkout Session 作成PaidArticleCheckoutService, PaidArticleCheckoutController
#2631Webhook 受信・購入記録 INSERTStripeWebhookService, 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. 関連ドキュメント