今できること
- 招待制sellerのtest-mode販売
- license validate / activate / deactivate の実装検証
- 購入完了ページでのlicense確認
- 承認済みファイルのauthorized download検証
Invite-only closed beta / Stripe test mode
Activatist は、開発者が自分のソフトウェアのライセンスキーを販売し、購入後にアプリ内で検証・有効化できるようにするAPIです。このページはプログラム初学者でも実装できるように、用語、流れ、主要言語のコード例を日本語でまとめています。
POST /v1/licenses/activate
Content-Type: application/json
{
"product_id": "prod_123",
"license_key": "LIC1-XXXX-XXXX-XXXX-XXXX",
"device_fingerprint": "device-abc"
}
Closed Beta Status
Start Here
Concepts
販売するソフトウェア本体です。例: デスクトップアプリ、プラグイン、開発ツール。1つの Product に価格、説明、サポート先、アクティベーション上限が紐づきます。
購入後に発行されるキーです。ユーザーがアプリに入力し、アプリが Activatist API に送って検証します。ログに出してはいけません。
「この端末で使い始める」操作です。同じ端末の再アクティベーションは冪等で、別端末は activation_limit を超えると拒否されます。
端末を見分けるためのアプリ側IDです。メールアドレスや氏名などの個人情報を入れず、安定したランダムIDを使います。
Before You Start
https://license.souko.workQuickstart
Lifecycle
| タイミング | 呼ぶAPI | 理由 |
|---|---|---|
| 初回ライセンス入力 | activate | この端末を利用枠として登録します。 |
| アプリ起動時 | validate | seatを増やさず、revoke/refund/expiredを確認します。 |
| 24時間に1回程度 | validate | 状態変化を反映しつつ、過剰なAPI呼び出しを避けます。 |
| ユーザーが端末解除 | deactivate | ポリシーが許す場合に利用枠を空けます。 |
| ネットワーク不通 | 短いgrace | 最後の成功状態を短時間だけ使い、復旧後にvalidateします。 |
Device Fingerprint
端末IDはアプリ実装者が考えるより、SDK側でOS別の安全な保存先に作るのが扱いやすいです。UUID v4相当のランダムIDなら衝突確率は実用上ほぼ無視できます。メール、氏名、電話番号、IPアドレス、raw hardware serial は使いません。
backendは端末IDのraw値を保存せず、HMAC hashとして扱います。アプリ側でもログには出さないでください。
Application Support 配下、可能なら Keychain。ファイル保存なら権限を絞ります。
AppData 配下、可能なら Credential Manager / DPAPI を検討します。
XDG config 配下に保存し、権限は `0600` 相当にします。
Activation Deep Dive
アクティベーションは「ライセンスキーが正しいか」だけでなく、「この端末を利用枠として登録できるか」も確認します。
Runtime Endpoints
/v1/licenses/validate起動時や定期チェックで使います。activation_count は増えません。
/v1/licenses/activate初回認証や端末登録で使います。activation_limit を超えた別端末は `409 conflict` になります。
/v1/licenses/deactivate端末の解除で使います。ポリシー上許可されている場合、利用枠を空けます。
SDK
通常はこちらを使ってください。SDKは端末IDの生成・保存、runtime API呼び出し、エラー処理をまとめるためのものです。
import { ActivatistClient } from "@activatist/client";
const client = new ActivatistClient({ productId: "prod_123" });
const result = await client.activate(licenseKey);
from activatist import ActivatistClient
client = ActivatistClient(product_id="prod_123")
result = client.activate(license_key)
client, _ := activatist.NewClient("prod_123")
result, err := client.Activate(ctx, licenseKey)
Code Samples
SDKを使えない環境向けです。通常のデスクトップアプリでは上のSDK例を優先してください。
ブラウザやElectronで使いやすい fetch の例です。
Appendix
| HTTP | 意味 | アプリ側の表示例 |
|---|---|---|
| 400 | 入力が不足、形式が不正 | 入力内容を確認してください。 |
| 403 | キーが使えない状態 | このライセンスは利用できません。 |
| 404 | 対象が見つからない | ライセンス情報が見つかりません。 |
| 409 | アクティベーション上限超過 | 利用可能な端末数の上限に達しました。 |
| 429 | 短時間にリクエストが多すぎる | 少し待ってから再試行してください。 |
| 5xx | 一時的なサーバー障害 | 時間をおいて再試行してください。 |
Seller Flow
アプリに認証を組み込むだけならruntime APIの3つで十分です。Activatist上で商品を売る場合は、seller申請、Stripe Connect、Product review、file upload/finalize、admin approval、test checkout、buyer completion/download の順に進みます。
Seller Quickstartを見るGET /v1/public/products/{slug}POST /v1/public/products/{slug}/checkoutPOST /v1/purchases/completePOST /v1/purchases/files/{file_id}/download-intentPOST /v1/licenses/validatePOST /v1/licenses/activatePOST /v1/licenses/deactivatePOST /v1/sellersPOST /v1/sellers/stripe/account-linkPOST /v1/productsPOST /v1/products/{product_id}/submit-reviewPOST /v1/products/{product_id}/files/upload-intentPOST /v1/products/{product_id}/files/{file_id}/finalizeGET /v1/admin/sellersPATCH /v1/admin/products/{product_id}/reviewGET /v1/admin/product-filesPATCH /v1/admin/products/{product_id}/files/{file_id}/reviewPOST /v1/stripe/webhookGET /readyzSafety Rules
ライセンスキー、completion token、buyer email、Firebase token、Bearer token、Stripe/Resend/R2/Cloudflare の秘密情報、presigned URL はログや共有メモに出さないでください。
device_fingerprint にメールアドレス、氏名、電話番号、住所などを入れないでください。ランダムIDを作って端末内に保存する方式が扱いやすいです。
起動時チェックは validate、端末登録は activate、端末解除は deactivate と役割を分けると、ユーザー体験とサーバー負荷が安定します。
Activatist は first-party software license 用です。ギフトカード、ポイント、第三者キー転売、C2C resale には使えません。