/licenses/validate

概要

指定したライセンスキーが有効かどうか、および**利用上限・アクティベーション状況(このドメインが紐付いているか)**を検証します。
クライアント SDK(JS/PHP)や、配布プラグイン側の is_premium() 判定がこのエンドポイントを叩きます。


エンドポイント

  • GET /wp-json/appcotton/v1/licenses/validate
  • POST /wp-json/appcotton/v1/licenses/validate(GET 同等の挙動)

どちらも同じ構造で応答します。フロントエンド(JS)からは GET を、サーバー側(PHP)からは POST を推奨。


認証

  • 公開 API(基本はトークン不要)
    • WordPress ログイン時は X-WP-Nonce を付けても動作しますが必須ではありません。
  • レート制限は別章「認証方式とレート制限」を参照。

リクエスト・パラメータ

名前必須説明
license_keystring検証対象のライセンスキー
product_idnumberプロダクトID。product_slug を使う場合は不要
item_slug / product_slugstringプロダクトのスラッグ(例:combpass_premium
domainstring (URL/ホスト)検証したいドメイン(既定はリクエスト元)
site_urlstring (URL)任意のサイトURL(環境の自己申告)
instance_idstringクライアント識別子(マルチサイトや端末ごと識別したい場合)

product_idproduct_slug はどちらか一方でOK。プラグイン側では product_slug 推奨


成功レスポンス(200)

{
  "valid": true,
  "message": "License is valid.",
  "expires_at": "2026-12-31 23:59:59",
  "usage": {
    "used": 2,
    "limit": 3,
    "remaining": 1,
    "activations": [
      {
        "domain": "https://example.com",
        "status": "active",
        "first_activated_at": "2025-11-01 12:34:56",
        "last_checked_at": "2025-11-11 10:00:00"
      },
      {
        "domain": "https://sub.example.com",
        "status": "active",
        "first_activated_at": "2025-11-02 09:10:11",
        "last_checked_at": "2025-11-11 10:00:00"
      }
    ]
  },
  "is_activated": true
}

フィールド説明

  • valid: ライセンスが有効か(true/false)
  • message: 人間可読な説明メッセージ
  • expires_at: 失効日時(未設定の場合は null
  • usage.used: 既に使用(アクティベート)しているドメイン数
  • usage.limit: 上限(-1 は無制限)
  • usage.remaining: 残り利用可能数(無制限時は十分な大きい数/または null
  • usage.activations: ひも付いているドメインの一覧
  • is_activated: このリクエストの domain が既に有効化済みかのフラグ

代表的なエラーレスポンス

400 Bad Request

{
  "valid": false,
  "error": "missing_license_key",
  "message": "License key is required."
}

404 Not Found

{
  "valid": false,
  "error": "license_not_found",
  "message": "License not found."
}

409 Conflict(プロダクト不一致・プラン不整合)

{
  "valid": false,
  "error": "product_mismatch",
  "message": "License is not issued for the specified product."
}

429 Too Many Requests(レート超過)

{
  "valid": false,
  "error": "rate_limited",
  "message": "Too many requests. Please slow down."
}

具体的なコード一覧と文言の規約は「§5 エラー規約」を参照。


使用例

1) cURL(GET)

curl -G \
  -H "Accept: application/json" \
  --data-urlencode "license_key=YOUR-LICENSE-KEY" \
  --data-urlencode "product_slug=combpass_premium" \
  --data-urlencode "domain=https://your-site.tld" \
  https://YOUR-DOMAIN.tld/wp-json/appcotton/v1/licenses/validate

2) JavaScript(フロントエンド)

const endpoint = `${window.location.origin}/wp-json/appcotton/v1/licenses/validate` +
  `?license_key=${encodeURIComponent(licenseKey)}` +
  `&product_slug=${encodeURIComponent('combpass_premium')}` +
  `&domain=${encodeURIComponent(window.location.origin)}`;

const res = await fetch(endpoint, { headers: { 'Accept': 'application/json' }});
const data = await res.json();

if (data.valid && data.is_activated) {
  // プレミアム機能を解放
} else {
  // 未認証UIを表示(購入/再認証の導線へ)
}

3) PHP(サーバーサイド)

$response = wp_remote_post(
  home_url('/wp-json/appcotton/v1/licenses/validate'),
  [
    'timeout' => 15,
    'body'    => [
      'license_key'  => $license_key,
      'product_slug' => 'combpass_premium',
      'domain'       => home_url(),
      'site_url'     => home_url(),
    ],
  ]
);

if (!is_wp_error($response)) {
    $body = json_decode(wp_remote_retrieve_body($response), true);
    if (!empty($body['valid']) && !empty($body['is_activated'])) {
        // 有効
    } else {
        // 無効 or 未アクティベート
    }
}

実装上の注意

  • ドメイン正規化https://example.comhttp://example.com/ の揺れを内部で統一)
  • CORS:配布先のプラグインから直接叩く場合に備え、サーバー側の許可設定を確認
  • タイムアウト/再試行:ネットワーク断などを考慮してクライアントでのリトライ戦略を用意
  • UI 挙動valid でも is_activated=false のケースでは「ドメインのアクティベーションを促すUI」を表示

ステータスコード一覧

  • 200: 成功(有効/無効の判定結果を含む)
  • 400: パラメータ不備(例:missing_license_key
  • 404: ライセンス未発見
  • 409: 整合性エラー(プロダクト不一致・プラン不整合など)
  • 429: レート制限
  • 500: サーバーエラー(内部例外)

変更履歴

  • v1: 初版公開(valid 判定、usageis_activated を返却)