授權碼開放接口文檔
v1.0
授權碼開放接口文檔
本文面向需要把「支付 → 發碼 → 激活 → 校驗」做進自己軟件的開發者(客戶端軟件 / 僅推廣產品)。文檔按接口逐個說明調用時機、請求參數、返回字段、錯誤碼。
一、核心概念
| 概念 | 字段 / 術語 | 說明 |
|---|---|---|
| 軟件發碼密鑰 | licenseApiSecret |
產品開啟「授權激活」時系統自動生成,在開發者中心產品編輯表單可查看。軟件服務端用它計算 HMAC 簽名,平台用它驗簽;只能保存在你的軟件服務端,嚴禁寫入客戶端。 |
| 授權碼 | licenseCode |
平台生成的唯一授權碼,用戶憑它激活軟件。 |
| 機器碼 | machineCode |
客戶端軟件生成的設備標識(每台電腦唯一,建議對機器指紋做哈希,至少 8 位)。 |
| 激活憑證 | activationToken |
平台在激活 / 發碼時簽發的憑證,軟件保存後每次啟動校驗時回傳。 |
| 訂單號 | clientOrderId |
軟件內支付訂單號(客戶端或服務端生成)。平台按「產品 + 訂單號」冪等,防止重複扣費重複發碼。 |
二、接入準備
- 發佈產品時開啟「授權激活」,保存系統生成的軟件發碼密鑰(licenseApiSecret);
- 在發佈表單配置版本列表(如 BASIC/PRO/ULTIMATE)與升級策略(SAME_CODE 原碼升級 / NEW_CODE 換新碼);
- 將密鑰保存在軟件服務端,客戶端只保留授權碼與激活憑證。
三、接口總覽
接口前綴:https://www.powersoftware.app/frontApi(本地 / 測試環境按你的部署域名替換)。
| 接口 | 調用時機 | 鑒權 | 簽名 |
|---|---|---|---|
POST /license/software/generate |
軟件內支付成功後 | 無(驗簽) | 需要 |
POST /license/software/upgrade |
續費 / 升級版本支付成功後 | 無(驗簽) | 需要 |
POST /license/activate |
用戶首次激活 / 換新設備 | 無 | 不需要 |
POST /license/verify |
軟件每次啟動 | 無 | 不需要 |
POST /license/deactivate |
用戶解綁舊設備(個人中心) | 登入 | 不需要 |
四、簽名規則(發碼 / 升級接口必須)
簽名串:按以下固定順序、以換行符 \n 拼接(缺省字段填空值:edition 空串、expiryDays 填 0):
productId \n machineCode \n edition \n expiryDays \n clientOrderId \n licenseCode \n timestamp
簽名:HMAC-SHA256(軟件發碼密鑰 licenseApiSecret, 簽名串),結果用 Base64URL 編碼後放入 signature 字段。
防重放:timestamp 為毫秒時間戳,平台要求與服務器時間差不超過 5 分鐘,超時直接返回 signatureInvalid。
Node.js 示例:
const crypto = require("crypto");
const payload = [productId, machineCode, edition, expiryDays, clientOrderId, licenseCode, timestamp].join("\n");
const signature = crypto.createHmac("sha256", API_SECRET).update(payload).digest("base64url");
Python 示例:
import hashlib, hmac, base64
payload = "\n".join([str(productId), machineCode, edition, str(expiryDays), clientOrderId, licenseCode, str(timestamp)])
signature = base64.urlsafe_b64encode(hmac.new(API_SECRET.encode(), payload.encode(), hashlib.sha256).digest()).decode().rstrip("=")
(Base64URL 即標準 Base64 將 + 換 -、/ 換 _,並去掉末尾 = 填充。)
五、接口詳情
5.1 生成授權碼(軟件內支付後調用)
調用時機:用戶在軟件內完成支付後,由軟件服務端立即調用一次並保存返回的授權碼與激活憑證。同一訂單只應調用一次;重複調用因冪等不會重複發碼。
POST /license/software/generate
請求參數(JSON body):
| 參數 | 類型 | 必填 | 來源 | 說明 |
|---|---|---|---|---|
| productId | number | 是 | 軟件內置 / 服務端配置 | 產品 ID,與平台發佈的產品一致 |
| machineCode | string | 是 | 客戶端生成 | 當前設備機器碼,≥8 位 |
| edition | string | 否 | 客戶端支付時選擇 | 版本標識,須在產品版本列表內;缺省取產品默認第一個版本 |
| expiryDays | number | 否 | 客戶端支付時選擇 | 有效期天數,0=永久;範圍 0-3650 |
| clientOrderId | string | 是 | 客戶端 / 服務端生成 | 軟件內支付訂單號,1-64 字符;冪等鍵 |
| timestamp | number | 是 | 軟件服務端生成 | 毫秒時間戳 |
| signature | string | 是 | 軟件服務端計算 | HMAC 簽名,≥10 字符 |
成功響應 content 字段:
| 字段 | 類型 | 說明 |
|---|---|---|
| licenseId | number | 授權碼記錄 ID |
| licenseCode | string | 授權碼(寫入軟件授權信息) |
| productId | number | 產品 ID |
| edition | string | 版本標識 |
| machineId | number | 已綁定機器記錄 ID |
| activatedAt | string | 激活時間(ISO8601) |
| expiryTime | string/null | 到期時間(ISO8601),null=永久 |
| maxMachines | number | 最大可綁定機器數 |
| activationToken | string | 激活憑證,軟件保存用於啟動校驗 |
響應示例:
{
"code": "SUCCESS",
"requestId": "xxx",
"success": true,
"content": {
"licenseId": 1001,
"licenseCode": "AB12-CD34-EF56-GH78",
"productId": 88,
"edition": "PRO",
"machineId": 2001,
"activatedAt": "2026-08-05T10:00:00.000Z",
"expiryTime": "2027-08-05T10:00:00.000Z",
"maxMachines": 1,
"activationToken": "eyJhbGciOiJIUzI1NiJ9..."
}
}
本接口錯誤碼:productIdRequired、machineCodeInvalid、orderIdRequired、productNotFound、productNotEnabled、apiSecretMissing、signatureInvalid、orderAlreadyUsed。
5.2 升級版本 / 續費(支付後調用)
調用時機:用戶在軟件內完成續費或升級版本支付後調用;同一訂單只應調用一次。
POST /license/software/upgrade
請求參數(JSON body):
| 參數 | 類型 | 必填 | 來源 | 說明 |
|---|---|---|---|---|
| productId | number | 是 | 軟件內置 / 服務端配置 | 產品 ID |
| licenseCode | string | 是 | 軟件本地保存 | 當前授權碼,≥10 位 |
| machineCode | string | 否 | 客戶端生成 | 當前機器碼;換新碼策略遷移綁定、補綁機器時傳 |
| edition | string | 是 | 客戶端支付時選擇 | 目標版本標識 |
| expiryDays | number | 否 | 客戶端支付時選擇 | 新增有效期天數,0=永久;範圍 0-3650 |
| clientOrderId | string | 是 | 客戶端 / 服務端生成 | 本次訂單號;冪等鍵 |
| timestamp | number | 是 | 軟件服務端生成 | 毫秒時間戳 |
| signature | string | 是 | 軟件服務端計算 | HMAC 簽名 |
處理策略(由產品配置決定):
- SAME_CODE(原碼升級):授權碼不變,機器綁定不失效,有效期順延(永久授權保持永久);響應在 5.1 字段基礎上增加
upgraded: true; - NEW_CODE(換新碼):吊銷舊碼、生成新碼並遷移機器綁定;響應額外返回
oldLicenseId,licenseCode為新碼。
成功響應 content 字段:與 5.1 相同,另加 upgraded: true;NEW_CODE 策略下返回 oldLicenseId(舊授權碼記錄 ID,舊碼已被吊銷)。
本接口錯誤碼:productIdRequired、licenseCodeRequired、orderIdRequired、productNotFound、productNotEnabled、apiSecretMissing、signatureInvalid、codeNotFound、revoked、orderAlreadyUsed、editionRequired。
5.3 激活授權(用戶首次激活 / 換新設備)
調用時機:用戶拿到授權碼(自助發碼、後台發碼等場景)後,在客戶端軟件激活頁輸入授權碼並激活;換新設備時在新設備調用。
POST /license/activate
請求參數(JSON body):
| 參數 | 類型 | 必填 | 來源 | 說明 |
|---|---|---|---|---|
| licenseCode | string | 是 | 用戶輸入 | 授權碼,≥10 位 |
| machineCode | string | 是 | 客戶端生成 | 當前設備機器碼,≥8 位 |
成功響應 content:同 5.1(licenseId、licenseCode、productId、edition、machineId、activatedAt、expiryTime、maxMachines、activationToken)。
說明:
- 同一授權碼可綁定多台機器,受
maxMachines限制(默認取產品配置); - 同一機器重複激活:復用原綁定並重新簽發激活憑證(冪等);
- 激活失敗會按 IP + 授權碼計數限流,多次失敗返回
tooManyAttempts。
本接口錯誤碼:codeNotFound、revoked、expired、machineLimit、tooManyAttempts。
5.4 校驗授權(軟件啟動時)
調用時機:軟件每次啟動(或解鎖功能前)調用;軟件須保存 5.1 / 5.2 / 5.3 返回的 activationToken。
POST /license/verify
請求參數(JSON body):
| 參數 | 類型 | 必填 | 來源 | 說明 |
|---|---|---|---|---|
| licenseCode | string | 是 | 軟件本地保存 | 授權碼,≥10 位 |
| machineCode | string | 是 | 客戶端生成 | 當前設備機器碼,≥8 位 |
| activationToken | string | 是 | 平台簽發、軟件保存 | 激活憑證,≥20 位 |
成功響應 content 字段:
| 字段 | 類型 | 說明 |
|---|---|---|
| valid | boolean | 恆為 true(失敗走錯誤碼) |
| licenseId | number | 授權碼記錄 ID |
| productId | number | 產品 ID |
| edition | string | 當前版本標識 |
| expiryTime | string/null | 到期時間(ISO8601),null=永久 |
說明:
- 校驗結果有約 60 秒緩存;吊銷、解綁、升級等寫操作會主動失效緩存,無需擔心延遲;
- 軟件應根據
expiryTime判斷是否過期,過期後停止解鎖功能。
本接口錯誤碼:tokenInvalid、machineNotActivated、invalidOrRevoked、expired、tooManyAttempts。
5.5 解綁設備(換機前,需登入)
調用時機:用戶在「個人中心 → 我的授權」對舊設備執行解綁,然後在新設備調用 5.3 激活。
POST /license/deactivate
請求參數(JSON body):
| 參數 | 類型 | 必填 | 來源 | 說明 |
|---|---|---|---|---|
| licenseCode | string | 是 | 用戶授權列表 | 授權碼,≥10 位 |
| machineCode | string | 是 | 用戶授權列表 | 要解綁的機器碼,≥8 位 |
成功響應 content:true。
說明:
- 僅授權碼歸屬用戶(購買用戶或綁定機器碼登記用戶)可操作;
- 解綁配額:默認 30 天內僅可解綁 1 次(運營後台可配置),超限返回
unbindQuotaExceeded。
本接口錯誤碼:noPermission、machineNotBound、unbindQuotaExceeded。
六、錯誤碼匯總
業務錯誤統一返回(tip 為可讀錯誤信息):
{
"code": "BUSINESS_WARNING",
"requestId": "xxx",
"success": false,
"errorMessage": "LICENSE_GENERATE_FAILED",
"tip": "簽名校驗失敗"
}
參數校驗失敗返回 code: "PARAM_VALIDATE_FAILED",tip 為具體字段提示。
| 錯誤碼 | 含義 |
|---|---|
productNotEnabled |
產品未啟用授權激活 |
apiSecretMissing |
產品未配置軟件發碼密鑰(licenseApiSecret) |
signatureInvalid |
簽名校驗失敗(密鑰不一致、簽名串順序錯誤或時間戳超窗) |
machineCodeInvalid |
機器碼無效(長度不足 8 位) |
orderAlreadyUsed |
該訂單已生成過授權碼(冪等衝突:換機器碼重放) |
codeNotFound |
授權碼不存在 |
revoked |
授權碼已被吊銷或不可用 |
expired |
授權碼已過期 |
invalidOrRevoked |
校驗時授權無效或已被吊銷 |
machineNotActivated |
該機器未激活 |
tokenInvalid |
激活憑證無效 |
machineLimit |
授權碼綁定機器數已達上限 |
machineNotBound |
該機器未綁定 |
noPermission |
無權操作該授權碼 |
unbindQuotaExceeded |
30 天內僅可解綁 1 次,請稍後再試 |
tooManyAttempts |
嘗試次數過多,請稍後再試 |
productNotFound |
產品不存在 |
editionRequired |
請選擇目標版本 |
七、典型流程
- 軟件內支付閉環:支付成功 →
software/generate(返回授權碼 + 激活憑證)→ 軟件保存 → 每次啟動verify→ 解鎖功能;續費 / 升級 →software/upgrade; - 自助發碼 / 後台發碼:開發者中心或平台後台生成授權碼 → 用戶獲得授權碼 → 客戶端
activate綁定設備並獲取激活憑證 → 啟動verify; - 換機:個人中心
deactivate解綁舊設備 → 新設備activate→verify; - 升級策略差異:SAME_CODE 原碼升級(碼不變);NEW_CODE 換新碼(舊碼吊銷、新碼自動遷移機器綁定)。
八、注意事項
- 密鑰只存服務端:簽名只能在你的軟件服務端完成,客戶端拿到密鑰等於授權體系失效;
- 機器碼穩定性:建議使用穩定的機器指紋並做哈希;重裝系統導致機器碼變化時需先解綁再激活;
- 冪等:
clientOrderId請保證全局唯一(如 時間戳 + 隨機數),重複請求不會重複發碼; - 緩存:
verify結果緩存約 60 秒,寫操作即時失效; - 限流:激活 / 校驗失敗會限流,客戶端應做好錯誤提示與重試間隔;
- 以平台返回為準:有效期、版本、機器數上限等以平台判定為準,軟件端不要自行放寬。