Authorization SDK Specification

vv3.1

Authorization SDK Specification (v3

Basis:ps-help/v3/doc/售卖方式与授权购买链路_v3.mdHelp Center LICENSE_API_DOC (v3). Objective: Consistent behavior of the Node/Python/Java SDKS (machine code, signature, interface, cache, error code, purchase page redirect).

Machine code algorithm (Consistent across languages)

The three language SDKS on the same machine must generate the same one machineCode.

Fingerprint source pressPrioritySelect, stop when a valid value is reached:

fingerprint = 硬件序列号 → 系统机器 ID → hostname | os | arch(兜底)

Priority 1: Hardware serial number (BIOS SN, unchanged after reinstalling the system)

System Source Acquisition method Permission
Windows BIOS SerialNumber wmic bios get serialnumberDowngrade PowerShell Get-CimInstance Win32_BIOS) Ordinary user
macOS Hardware serial number system_profiler SPHardwareDataType "Extract" Serial Number Ordinary user
Linux Product serial number read /sys/class/dmi/id/product_serial"Demotion dmidecode -s system-serial-number) root required

Priority 2: System machine ID (generated during installation, unchanged on the same machine)

System Source Acquisition method Permission
Windows MachineGuid Registration form HKLM\SOFTWARE\Microsoft\Cryptography Ordinary user
macOS IOPlatformUUID ioreg -d2 -c IOPlatformPlatformDevice Ordinary user
Linux machine-id read /etc/machine-id"Demotion /var/lib/dbus/machine-id) All users

Priority 3: Fallback (hostname | os | "arch"

It is used when both the hardware serial number and the system machine ID fail to be obtained.

Field Node Python Java
hostname os.hostname() socket.gethostname() InetAddress.getLocalHost().getHostName()
os os.platform() sys.platform System.getProperty("os.name")
arch os.arch() platform.machine() System.getProperty("os.arch")

Unified processing

  • Remove the first and last Spaces from all fields and convert them to lowercase.
  • Filter manufacturer placeholder valueTo be filled by O.E.M. / None / 0 / Default / Not Available / Not Specified";"
  • The concatenation characters are unified as |Overall again toLowerCase().
machineCode = 'M' + base64url( sha256( fingerprint ) ).slice(0, 32)

machineCode At least 8 bits, unique across all platforms, and internally cached in the SDK (within the process).

2. Signature Rules (Mandatory for software/generate and software/upgrade)

The signature string is in a fixed order and separated by line breaks (default blank value:edition Empty stringexpiryDays "0licenseCode Empty string:

productUniqueCode \n machineCode \n edition \n expiryDays \n clientOrderId \n licenseCode \n timestamp

signature = base64url( HMAC-SHA256( licenseApiSecret, 签名串 ) );timestamp It is in milliseconds. The time difference between the platform verification and the server is no more than 5 minutes (anti-replay).

3. Interface list

Prefixhttps://www.powersoftware.app/frontApi(Can be passed baseUrl "Cover".

Interface "Path" Authentication SDK method
Activate POST /license/activate no activate(licenseCode, machineCode)
Verification POST /license/verify no verify(licenseCode, machineCode, activationToken)
Unbind POST /license/deactivate Log in (browser scene) deactivate(licenseCode, machineCode)
The code is sent within the software POST /license/software/generate HMAC signature generateForSoftware({...})
Software in-app upgrade/renewal POST /license/software/upgrade HMAC signature upgradeForSoftware({...})
Claim a trial POST /license/trial/claim no claimTrial(machineCode)

generateForSoftware / upgradeForSoftware Automatic supplementation timestamp + signature;claimTrial The product requires payment after use.

4. Local credentials and verification cache

  • "LocalOnly remaining:licenseCode,activationTokenThe most recent verify result{ valid, edition, expiryTime, trialExpiryTime } + Timestamp. trialExpiryTime is the trial expiry snapshot (ISO8601, null when not upgraded from a trial) and can be used as a grace window for top-tier features.
  • No longer existDecryptable complete authorization information (anti-reverse engineering is meaningless, only used for caching).
  • Verify the cache TTL for 60 seconds: When clicking on the payment function, check the cache first. Use it directly if it has not expired. Call the server again if it has expired or failed verify.
  • Server-side revocation, refund or upgrade will actively invalidate the cache (the platform side has already implemented this), and the SDK does not need to be aware of it.

5. Paid function interception and purchase page redirection

Click the paid menu button:

  1. verifyCached(licenseCode, machineCode, activationToken) Return valid and not expired → Pass;
  2. Return invalid/Expired/unactivated → Pop-up prompt "Activation authorization needs to be purchased";
  3. "Generated machineCodeJump to the purchase page (the product identification is. productUniqueCode(Carry the machine code)
https://www.powersoftware.app/product/license/purchase?productUniqueCode={productUniqueCode}&machineCode={machineCode}

Multilingual sites add a language prefix before the path, such as /en-US/product/license/purchase;productUniqueCode Passed in by the constructor."

5.1 Purchase Station Selection:.app(International Station) vs .cn(Domestic Station

Powerstack has two sites, one with SDK purchaseUrl() "Through base Parameter switching

powersoftware.app(International Station powersoftware.cn(Domestic Station
Payment method Alipay + PayPal Only Alipay
Country/Currency Cloudflare automatically identifies by IP (CN→CNY, rest →USD) Fixed country=CNRMB
"Language" Press the URL prefix / Accept-Language Automatic detection Fixed zh-CN
Applicable users International users/overseas Users in Chinese mainland

SDK default .appNo automatic judgment is made. The client software needs to decide which one to upload by itself base.

Judgment method

Method One: By system language (recommended

import locale

def get_purchase_base():
    sys_lang = locale.getdefaultlocale()[0] or ""
    if sys_lang.startswith("zh"):
        return "https://www.powersoftware.cn"
    return "https://www.powersoftware.app"
function getPurchaseBase() {
    const lang = process.env.LANG || "";
    return lang.toLowerCase().startsWith("zh")
        ? "https://www.powersoftware.cn"
        : "https://www.powersoftware.app";
}
String getPurchaseBase() {
    return "zh".equals(Locale.getDefault().getLanguage())
        ? "https://www.powersoftware.cn"
        : "https://www.powersoftware.app";
}

Method Two: User Settings items The Settings interface offers a "Region" option, which users can choose by themselves.

Method Three: Hard coding Software that is only targeted at domestic users is directly hardcoded base="https://www.powersoftware.cn".

For details, please refer to 语言与国家逻辑 Section 2.4

6. Error Code (SDK throws errors uniformly carry errorCode)

codeNotFound,revoked,expired,machineLimit,tooManyAttempts,signatureInvalid,apiSecretMissing,productNotEnabled,trialNotEnabled,trialAlreadyPurchased,trialAlreadyPurchased,trialAlreadyPurchased,trialAlreadyPurchased,machineCodeInvalid,orderAlreadyUsed,editionRequired,productNotFound,trialFirstRequired,alreadyOwned Etc. Network/timeout errors are unified as NETWORK_ERROR.

7. Package structure

ps-sdk/
  node/     @mizhanchengxi/ps-license-sdk(ESM,零依赖)
  python/   ps-license-sdk(py3,零依赖)
  java/     com.powersoftware:sdk(Java 8+,JDK 自带 HTTP/加密)

All three packages are provided:machineCode(),sign(),LicenseClient(The above 6 methods + verifyCached + purchaseUrl"