ユーザーポータル

AppCotton の「ユーザーポータル」は、購入者(= ライセンス保有者)が自分のライセンスとドメインの紐づけを自己管理できる画面群です。WooCommerce の重い購入フローに依存せず、軽量な REST + 簡易 UI で以下を実現します。


目的と到達点

  • 自分のライセンス一覧を確認できる
  • ドメインのアクティベーション/解除をセルフで行える
  • **プランのアップグレード(差額課金)**を開始できる
  • メールアドレス通知設定など最小限のプロフィールを更新できる

基本構成

1) ルーティング(例)

  • /my/licenses : ライセンス一覧・詳細
  • /my/domains : ドメイン紐づけ・解除
  • /my/upgrade : アップグレード起点(差額計算→決済へ)
  • /my/settings : 連絡先・通知設定

実体はショートコードや専用テンプレートで構築可能。ログイン必須(未ログイン時はログイン導線へ)。

2) ショートコード(例)

  • [appcotton_portal] … 全体タブ UI を出す統合版
  • [appcotton_portal_licenses]
  • [appcotton_portal_domains]
  • [appcotton_portal_upgrade]
  • [appcotton_portal_settings]

サイト構成に合わせて分割/統合を選択できます。


表示仕様(UX)

ライセンス一覧

  • 表:ライセンスキー(マスク表示)/製品名/プラン名/状態/有効期限/使用数(使用中/上限)
  • 行末アクション:
    • 「詳細」:使用状況とアクティベーション履歴
    • 「キー表示/非表示」:マスク切替
    • 「コピー」:クリップボードへ
    • 「ドメイン管理へ」:該当ライセンスを選択した状態で遷移
    • 「アップグレード」:プラン差額の確認へ

ドメイン管理

  • ライセンス選択ドロップダウン(保持件数が多い場合の検索付き)
  • 現在アクティブなドメイン一覧domain / first_activated_at / last_checked_at / status
  • ボタン:
    • 「このドメインを解除」…確認ダイアログ → 実行
    • 「このサイトを認証」…現在の window.location.origin を提案入力(編集可)→ 実行

アップグレード

  • 現在プランと候補プランを横並び比較
  • 差額の計算結果支払いボタン を提示
  • 決済完了後の状態反映(リダイレクト or ステータス更新待ち表示)

設定

  • 連絡先メール、配信可否(ニュース/重要なお知らせ)、言語
  • 保存時は成功/失敗のトースト通知

バックエンド連携(REST ざっくり仕様)

エンドポイント名は例です。実装の命名に合わせて読み替えてください。

  • GET /appcotton/v1/licenses/mine
    自分のライセンス一覧(キー一部マスク・利用状況サマリ付)
  • GET /appcotton/v1/licenses/{key}/usage
    使用数・上限・アクティベーション配列
  • POST /appcotton/v1/licenses/activate
    ボディ:{ license_key, domain, site_url?, instance_id? }
  • POST /appcotton/v1/licenses/deactivate
    ボディ:{ license_key, domain }
  • GET /appcotton/v1/licenses/{key}/upgrade/options
    アップグレード候補と差額(税込/税抜)見積
  • POST /appcotton/v1/licenses/{key}/upgrade/start
    ボディ:{ target_plan_id, success_url, cancel_url }redirect_url(決済)
  • GET /appcotton/v1/me / POST /appcotton/v1/me
    プロフィールの取得・更新

共通

  • 認証:ログイン済ユーザー(Cookie)+ X-WP-Nonce
  • レート制限:ポータル操作は 1IP/ユーザー ごとにミドルレート(例:1秒1回 / バースト5)
  • 監査:重要操作(解除、アップグレード)は 操作ログ を残す

フロント実装方針(最小 JS)

  • 各ボタンは async fetch → 結果に応じて行を更新(ページ全体リロードなし)
  • キーの表示/非表示は DOM で切替(フルキーは data-full-key に、既定はマスク)
  • ドメイン解除後:使用数と残数を即時再計算して反映
  • トースト通知:成功・警告・エラーの 3 種類(アクセシビリティ対応)

エラーメッセージ規約(抜粋)

  • missing_license_key:ライセンスキー未指定
  • license_not_found:存在しない・権限外
  • activation_limit_reached:上限到達(解除してから再実行してください)
  • domain_already_activated:既に同一ドメインが有効
  • upgrade_not_available:対象プランが現在プラン以下(差額が発生しない)
  • payment_required:決済が未完了

表示はユーザー向け和文、ログは英語コード + 詳細で保存。


差額課金の取り扱い(概要)

  • 同一プロダクト内の上位プランへのアップグレードのみ許可
  • 差額 = target_plan_price - current_plan_price(クーポン等は別規約)
  • 決済完了 → ライセンスの plan_idactivation_limit を更新
  • Webhook(例:stripe.checkout.session.completed)で最終確定(二重更新防止)

セキュリティとプライバシー

  • CSRF:REST は X-WP-Nonce 検証必須
  • 入力値:domain正規化https?:// → ドメイン+サブドメイン単位)
  • 監査:user_id / license_id / domain / ip / ua / ts を操作ログへ
  • 個人情報:メールアドレス等はマスク表示を既定に

カスタマイズポイント(サイト側)

  • テンプレート:ショートコードはラッパー。テーマ側で HTML/クラスを自由に調整可能
  • 翻訳wp_set_script_translations / PO ファイルで UI 文言を差し替え
  • フック(例)
    • appcotton/portal/licenses/columns:一覧カラムの追加/順序変更
    • appcotton/portal/domains/validate_domain:社内ルールの追加検証
    • appcotton/portal/upgrade/can_offer:提供可否の最終判定

QA(よくある質問)

Q. アクティベーション上限に達したらどうなる?
A. 新規アクティベーション API は activation_limit_reached を返し、UI は解除導線を表示します。

Q. ドメインを変えたい場合は?
A. 旧ドメインを解除 → 新ドメインで再認証の順で行います。

Q. 決済に失敗したら?
A. 差額適用は確定 Webhookでのみ反映。失敗時は現プランのまま据え置かれます。


実装チェックリスト

  • ログイン必須導線(未ログイン時の遷移と戻り先)
  • 一覧のマスク表示コピー機能
  • ドメインの正規化解除確認ダイアログ
  • 失敗時の詳細メッセージ再試行ボタン
  • Webhook 冪等性(重複通知でも正しく一度だけ反映)
  • 操作ログの採番・保存・検索

参考コード断片(UI 側呼び出し・擬似)

// 現在ページのオリジンを使って即時アクティベーション
await AppCottonLicense.activate(licenseKey /* required */);

// 指定ドメインで解除
await AppCottonLicense.deactivate(licenseKey, "https://example.com");

// 使用状況の取得(残り数でボタン状態を切替)
const usage = await AppCottonLicense.getUsage(licenseKey);
// usage = { used, limit, remaining, activations: [...] }

上記は UI からの利用例。REST の戻り値に合わせてトースト表示・行更新を実装します。


この仕様に沿えば、購入~利用~拡張の主要導線をユーザー自身で完結でき、運営側のサポートコストも最小化できます。