認証と決済の分離 — PG差し替え自由度のための設計メモ

アプリ認証と決済を混ぜない。キャリアには「ログイン用のIdP」と「決済内の本人確認」という別物が2つあり、混同が事故のもと。SBPS(まとめて支払い/auかんたん決済)を起点に、PG差し替えに備えた分離方針を整理する。

結論サマリ


用語の整理:「キャリア認証」には2種類ある

A. キャリアのIdPB. 決済内のキャリア認証
SoftBank ID / Yahoo! JAPAN ID連携、au IDまとめて支払い・auかんたん決済の購入承認
目的「誰か」を確定する(認証)「この支払いを承認するか」(決済の本人確認)
返すもの安定したユーザー識別子(IDトークン等)決済トランザクションの承認結果
ログイン利用◎ 想定された使い方✗ 副作用の流用(危険)
PG差し替えの影響受けない(認証基盤は決済と独立)認証ごと消える

ポイント:ダメなのはBだけ。 世間でいう「キャリアログイン」は通常Aを指し、これは正当な認証手段。


なぜ「決済内のキャリア認証(B)でログイン判定」はNGか

  1. 1回線=1人とは限らない — 家族端末・法人契約・シェアプラン・子回線。回線で人を引き当てると別人を同一ユーザーとしてログインさせうる。
  2. 機種変・MNP・解約で同一性が壊れる — 番号変更で「別人」になる、番号再割当てで前の持ち主のアカウントに新しい人が入る。
  3. PG差し替えで認証が消滅する(本題)— 決済をやめた瞬間にログインの仕組みごと消える。決済選定が認証の人質になる。
  4. UX・運用が一蓮托生 — 決済しないとログインできない/ログインのたび決済導線、になりがち。

キャリア比較:SoftBank と au

両者とも「IdP層(ログイン)」と「決済層(課金+本人確認)」が分かれている同型の構造。SBPS経由ならどちらもリンク型/API型の非同期決済フローに乗る。

観点SoftBank まとめて支払いau PAY(auかんたん決済)
ログイン用IdPSoftBank ID / Yahoo! JAPAN ID 連携au ID
決済の前提アカウントSoftBank/Y!mobile 回線au ID(au通信・UQ mobile契約等が登録されたもの)
決済内の本人確認キャリア認証(購入承認)au ID 認証による購入承認
エンドユーザー利用条件SoftBank側方針KDDI社の方針に準じる(SBPS仕様では制限せず)
月間利用枠締め日ベースで設定・翌日0時リセット年齢・契約に応じた月間限度額あり
SBPS接続方式リンク型 / API型リンク型 / API型

au で特に効いてくる点

※「決済セッションの具体的な有効期限(秒数)」はSBPSの各IF仕様書(まとめて支払いA/B、auかんたん決済)および加盟店向け非公開マニュアルに依存。 正確な値は SBPSの技術窓口で要確認。設計上は「PGごとに異なる有効期限を持つ」前提でモデル化しておく(後述)。


目標アーキテクチャ

[アプリ認証層]   ← 自前のID基盤(メール/パスワード, OIDC, パスキー, SoftBank ID/au ID連携など)
      │           ここで user_id が確定。決済とは完全独立。
      │ user_id を「入力として」渡す(一方通行)

[決済オーケストレーション層]   ← 抽象IF。PGの違いを吸収する唯一の場所
      │   beginCheckout() / handleCallback() / confirm()
      │   決済セッションの「真実の状態」を持つストアを管理
      ├─→ SBPSアダプタ(まとめて支払い/auかんたん決済:取引登録・結果CGI受信・有効期限管理・電文/チェックサム)
      ├─→ 別PGアダプタ(将来:PayPay / Stripe / その他)
      └─→ ...

依存ルール(最重要)

✓ 決済 → 認証   決済が「ログイン済みの user_id」を受け取る
✗ 認証 → 決済   ログイン判定が決済の認証結果を当てにする(Bの罠)

有効期限の抽象化

PGごとに決済セッションの有効期限はバラバラ(SBPSのキャリア決済、PayPay、カード系などで異なる)。


「重複してよい」の意味

ログイン時のキャリア認証と、決済時のキャリア認証は目的も時間軸も違う別イベントなので、同一ユーザーが同一キャリアに2回認証する形になっても冗長ではない。

[ログイン時] OpenID(SoftBank ID / au ID 等)でID連携 → user_id 確定・セッション開始
      (…ユーザーが買い物…)
[決済時]    SBPSの決済フロー内でキャリア認証 → この支払いの承認(user_idとは独立)

守るのは依存方向(決済→認証の一方通行)だけ。これさえ守れば別アプリ・別チーム・別リリースサイクルでも健全


既存システムの「解体」方針

現状「キャリア認証と決済が紐づいている」場合、癒着パターンを切り分けて解体する。

パターン内容難易度対応
① 認証結果の流用決済内キャリア認証(B)をログイン判定に使用最優先で剥がす。アプリ認証を自前で独立化
② 状態の同居tracking_id等をユーザーセッションに直持ち決済セッションを別ライフサイクルで外出し
③ コード混在ログイン処理と取引登録処理が同一モジュール責務分割のリファクタ

解体ステップ

  1. アプリ認証を、決済内キャリア認証から完全に切り離す 「ログイン済みか」と「決済のキャリア本人確認が通ったか」を別概念にする。以降、決済はログイン済み user_id を受け取るだけ。
  2. 決済セッションを独立した状態として外出し user_id に紐づくが、ユーザーセッションとは別ライフサイクル。provider / tracking_id / expires_at を保持。
  3. SBPS固有処理をアダプタに封じる キャリア認証フローはアダプタの内部実装に降格。上位は beginCheckout → callback → confirm の抽象操作のみ。

①がある場合の移行(既存ユーザーを締め出さない)

  1. 自前のアプリ認証を立てる(次回ログイン時にメール/パスキー等を登録してもらう導線)
  2. 既存の「回線→ユーザー」引き当ては、移行期間だけアカウント連携の確認手段に降格(ログイン本体ではなく補助に)
  3. 全ユーザー移行後、キャリア認証をログイン経路から完全に除去
  4. これで決済(SBPS)は純粋に決済だけになり、PG差し替えが認証に影響しなくなる

次に詰める論点


確認が必要な前提(裏取り未完)

← Back to all posts