SDK(開発者向け)

この章では、AppCotton を使った「最低限のSDKコア」を、あなたのプラグイン/テーマに組み込むための初期化・設定手順を示します。ブロックエディタにそのまま貼り付けて読めるよう、テキスト+コードのみで構成しています。


目的(ゴール)

  • あなたのプロダクトで is_premium() をワンコールで使えるようにする
  • REST エンドポイント・Nonce・製品識別子(product_slug)などの 初期設定を1カ所に集約
  • フロント(JS)/ サーバー(PHP)の 最小連携 を確立
  • 失敗時のフォールバックキャッシュ(トランジェント)・タイムアウトを規定

用語

  • AppCotton サーバ:あなたが運用するライセンス基盤(例:https://example.com
  • product_slug:AppCottonの「プロダクト」に対して一意な文字列(例:combpass_premium
  • license_key:購入者に発行されるキー

全体像(最小構成)

  1. PHP 初期化
    • REST ベースURL/Nonce/product_slug を 1カ所で定義
    • is_premium() ヘルパーを提供(トランジェントで一時キャッシュ)
  2. JS 初期化(必要な場合のみ)
    • appcotton_paramswp_localize_script で渡し、
      既存の window.AppCottonLicense ユーティリティ(validate/activate/deactivate)が即使える状態に
  3. 設定オーバーライド
    • 定数 or フィルターで、環境ごとの差し替えを可能に

1) PHP:SDKブートストラップ(初期設定)

以下を、あなたのプラグインのメインファイル等に追加してください。

<?php
// === AppCotton SDK Core: Bootstrap ==================================

// (A) 必須: AppCotton ライセンスAPIのベースURL(末尾にスラッシュ必須)
if ( ! defined('APPCOTTON_API_BASE') ) {
    define('APPCOTTON_API_BASE', 'https://example.com/wp-json/appcotton/v1/'); 
    // 例: https://combpass.com/wp-json/appcotton/v1/
}

// (B) 必須: この配布物に対応する product_slug
if ( ! defined('APPCOTTON_PRODUCT_SLUG') ) {
    define('APPCOTTON_PRODUCT_SLUG', 'your_product_slug'); 
    // 例: 'combpass_premium'
}

// (C) 任意: デフォルトのHTTPタイムアウトなど
if ( ! defined('APPCOTTON_REQUEST_TIMEOUT') ) {
    define('APPCOTTON_REQUEST_TIMEOUT', 12);
}

// (D) 任意: キャッシュ時間(秒)
if ( ! defined('APPCOTTON_VALIDATE_TTL') ) {
    define('APPCOTTON_VALIDATE_TTL', 6 * HOUR_IN_SECONDS);
}

// (E) ライセンスキーの取得先(例:WPオプション)。必要に応じて変更可。
function appcotton_get_license_key() {
    // 例: 固定ページの設定画面やオプションに保存している想定
    return trim( (string) get_option('appcotton_license_key') );
}

2) PHP:is_premium() ヘルパー(サーバ側検証+キャッシュ)

  • 成功/失敗を 一時キャッシュ
  • 失敗時にも 安全に false を返す
  • ドメイン/サイトURLも送る(サーバ側でのドメインアクティベーションと整合)
<?php
function appcotton_is_premium( $force_refresh = false ) {
    $cache_key = 'appcotton_valid_' . md5( home_url() . '|' . APPCOTTON_PRODUCT_SLUG );
    if ( ! $force_refresh ) {
        $cached = get_transient( $cache_key );
        if ( $cached !== false ) {
            return (bool) $cached;
        }
    }

    $license_key = appcotton_get_license_key();
    if ( $license_key === '' ) {
        set_transient( $cache_key, 0, MINUTE_IN_SECONDS ); // すぐ再確認できるよう短め
        return false;
    }

    $endpoint = trailingslashit( APPCOTTON_API_BASE ) . 'licenses/validate';

    $response = wp_remote_get( add_query_arg([
        'license_key' => rawurlencode($license_key),
        'product_slug'=> rawurlencode(APPCOTTON_PRODUCT_SLUG),
        'domain'      => rawurlencode( home_url() ),
    ], $endpoint ), [
        'timeout' => APPCOTTON_REQUEST_TIMEOUT,
    ]);

    if ( is_wp_error($response) ) {
        // 通信失敗は短命キャッシュ
        set_transient( $cache_key, 0, 5 * MINUTE_IN_SECONDS );
        return false;
    }

    $code = wp_remote_retrieve_response_code($response);
    $body = json_decode( wp_remote_retrieve_body($response), true );

    // 200 かつ valid:true を「プレミアム」とみなす(サーバ仕様に合わせる)
    $ok = ($code === 200 && ! empty($body['valid']));

    set_transient( $cache_key, $ok ? 1 : 0, $ok ? APPCOTTON_VALIDATE_TTL : 10 * MINUTE_IN_SECONDS );
    return $ok;
}

使い方:有料機能の分岐で if ( appcotton_is_premium() ) { … } とするだけ。


3) JS:AppCotton ユーティリティ利用(任意)

  • 既に AppCotton のフロントJSがある環境では、以下のローカライズを行うだけで window.AppCottonLicense が使えます。
  • 例:アクティベート/解除をユーザーポータルから行うボタンに紐づける等。
<?php
add_action('wp_enqueue_scripts', function() {
    // 既存/同梱の public.js を読み込む想定(ハンドル名は適宜調整)
    wp_enqueue_script('appcotton-public', plugins_url('assets/js/appcotton-public.js', __FILE__), ['wp-i18n','wp-element'], '1.0.0', true);

    // RESTベース・Nonce等をJSへ
    $rest_base = trailingslashit( APPCOTTON_API_BASE ); // 例: https://example.com/wp-json/appcotton/v1/
    wp_localize_script('appcotton-public', 'appcotton_params', [
        'rest_url'        => $rest_base,           // 例: .../v1/
        'appcotton_nonce' => wp_create_nonce('wp_rest'),
        'product_slug'    => APPCOTTON_PRODUCT_SLUG,
    ]);
});

JS側では window.AppCottonLicense.validate(licenseKey, productIdOrSlug, domain) 等が利用可能。
(フロントで「今このドメインは有効か?」を即時に見せたい場合に便利。サーバ側の is_premium() と併用可)


4) 設定オーバーライド(環境切替)

  • 定数で上書き:wp-config.php などで APPCOTTON_API_BASE を本番/検証で出し分け
  • フィルターを公開する場合の雛形:
<?php
function appcotton_get_api_base() {
    $base = defined('APPCOTTON_API_BASE') ? APPCOTTON_API_BASE : '';
    return apply_filters('appcotton/sdk/api_base', $base);
}
function appcotton_get_product_slug() {
    $slug = defined('APPCOTTON_PRODUCT_SLUG') ? APPCOTTON_PRODUCT_SLUG : '';
    return apply_filters('appcotton/sdk/product_slug', $slug);
}

5) 推奨:設定画面の最小項目

  • ライセンスキー(license_key)の入力欄
  • (任意)検証の手動更新ボタン(delete_transient でキャッシュ破棄→ appcotton_is_premium(true) 実行)
  • (任意)現在の検証結果と有効期限表示(AppCotton API の戻り値があれば表示)

6) 失敗時のフォールバック

  • REST 通信エラーや 4xx/5xx は 短命キャッシュで false
  • サーバ障害で解約扱いになる誤検出を避けたい場合は、直近成功結果を最長 X 時間まで維持する設計も可
    (例:最後の成功から 24h は継続許可 → 以降は警告表示)

7) 典型的な導入チェックリスト

  • APPCOTTON_API_BASEAPPCOTTON_PRODUCT_SLUG を定義した
  • ライセンスキーの保存先(get_option('appcotton_license_key') 等)を決めた
  • appcotton_is_premium() を利用する箇所にガードを設置
  • 期限切れ・未購入・通信失敗時の UI/メッセージを用意
  • (任意)JS 連携が必要な画面に appcotton-public.jsappcotton_params を出力

8) よくある質問(抜粋)

Q. サーバ側とフロントのどちらで検証すべき?
A. 制御の要(機能解放の最終判定)はサーバ側is_premium())で行い、フロントは補助表示に留めるのが安全です。

Q. キャッシュが強すぎて即時反映されない
A. APPCOTTON_VALIDATE_TTL を短くするか、設定画面に「検証を再実行」ボタンを用意してください。

Q. 複数製品で使いたい
A. 定数方式ならプラグインごとに定義。共通SDK化するなら、インスタンス化new AppCottonClient($api_base,$product_slug))で分離する設計に拡張します。


9) 最小サンプル(まとめ)

有料機能のガード

<?php
if ( appcotton_is_premium() ) {
    // Pro 機能を提供
    add_action('init', 'my_pro_feature_boot');
} else {
    // 無料版UIや案内を表示
    add_action('admin_notices', function(){
        echo '<div class="notice notice-warning"><p>この機能を利用するにはライセンスが必要です。</p></div>';
    });
}

設定画面保存時にキャッシュ破棄

<?php
// 例: 設定保存時
delete_transient( 'appcotton_valid_' . md5( home_url() . '|' . APPCOTTON_PRODUCT_SLUG ) );
// 直ちに再検証
appcotton_is_premium( true );

以上で「SDKコア:初期化と設定」の最小実装は完了です。
次の章では、UI自動生成(購入ボタン・プラン選択・アップグレード導線)と、エラー規約/Webhook連携に進みます。