Autoriser les spécifications SDK

vv3.1

Licence SDK spécification (v3)

Basé sur:ps-help/v3/doc/售卖方式与授权购买链路_v3.md, centre d’aide licence_API_DOC (v3). Objectif: le SDK trilingue Node/Python/Java se comporte de manière cohérente (code machine, signature, interface, cache, code d’erreur, saut de page d’achat).

1. Algorithmes de code machine (cohérents entre les langues)

Un SDK trilingue doit être généré sur la même machine machineCode.

Source d’empreintes parPriorité et prioritéSelection, s’arrête lorsque vous atteignez une valeur valide:

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

Priorité 1: numéro de série du matériel (BIOS SN, système réinstallé inchangé)

Le système sources Modalités d’accès La compétence
Windows BIOS SerialNumber wmic bios get serialnumber(rétrograder PowerShell Get-CimInstance Win32_BIOS) Pour l’utilisateur ordinaire
macOS Numéro de série hardware system_profiler SPHardwareDataType extraction Serial Number Pour l’utilisateur ordinaire
Linux Numéro de série lu /sys/class/dmi/id/product_serial(régression de dmidecode -s system-serial-number) Pour root

Priorité 2: système machine ID (généré lors de l’installation, inchangé dans la même machine)

Le système sources Modalités d’accès La compétence
Windows MachineGuid Le formulaire d’inscription HKLM\SOFTWARE\Microsoft\Cryptography Pour l’utilisateur ordinaire
macOS IOPlatformUUID ioreg -d2 -c IOPlatformPlatformDevice Pour l’utilisateur ordinaire
Linux machine-id lu /etc/machine-id(régression de /var/lib/dbus/machine-id) Pour tous utilisateurs

Priorité 3: roulette (hostname) 1 | os | Arch)

Utilisé lorsque le numéro de série du matériel et l’id de la machine système échouent à obtenir.

Les champs 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")

Un traitement uniforme

  • Tous les champs sont enlevés et transformés en minuscules;
  • Filtrer par fabricant placeholder value (To be filled by O.E.M. / None / 0 / Default / Not Available / Not Specified);
  • L’épissure est unifiée comme |, la totalité toLowerCase().
machineCode = 'M' + base64url( sha256( fingerprint ) ).slice(0, 32)

machineCode Au moins 8 bits, unique pour toute la plateforme et en cache interne du SDK (in-process).

2. Règles de signature (obligatoire pour software/generate, software/upgrade)

Les chaînes de signatures sont séparées par un ordre fixe, une nouvelle ligne (les valeurs sont remplies par défaut:edition Chaîne vide,expiryDays 0,licenseCode Chaîne vide) :

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

signature = base64url( HMAC-SHA256( licenseApiSecret, 签名串 ) );timestamp C’est la milliseconde, la différence de temps entre le contrôle de plate-forme et le serveur ≤ 5 minutes (anti-replay).

3. Liste des interfaces

Le préfixe:https://www.powersoftware.app/frontApi(disponible par baseUrl Couverture).

interface La trajectoire Des pouvoirs L’approche du SDK
l’activation POST /license/activate sans activate(licenseCode, machineCode)
L’exclusion des balances sensibles POST /license/verify sans verify(licenseCode, machineCode, activationToken)
Le déliement POST /license/deactivate Connexion (scénario navigateur) deactivate(licenseCode, machineCode)
Code d’émission dans le logiciel POST /license/software/generate Signé par HMAC generateForSoftware({...})
Mise à niveau/renouvellement du logiciel POST /license/software/upgrade Signé par HMAC upgradeForSoftware({...})
Demandez votre essai POST /license/trial/claim sans claimTrial(machineCode)

generateForSoftware / upgradeForSoftware Le remplissage automatique timestamp + signature;claimTrial Produit nécessaire pour utiliser d’abord et payer ensuite.

4. Authentification locale avec cache de vérification

  • locauxDépôt uniquement:licenseCode,activationToken, dernier résultat vérifié ({ valid, edition, expiryTime, trialExpiryTime } + horodatage). trialExpiryTime est l’instantané de l’expiration d’essai (ISO8601, null sans origine essai) et sert de période de grâce pour les fonctions supérieures.
  • neInformations d’autorisation complètes déchiffrables (anti-inverse sans sens, sert uniquement de cache).
  • Cache de vérification TTL 60s: vérifier le cache en premier lorsque la fonction de paiement par clic, pas expiré directement avec; Expiration ou échec du service de rappel verify.
  • Le retrait/remboursement/mise à niveau du côté du service invalidera activement le cache (côté plate-forme a été implémenté), SDK n’a pas besoin de percevoir.

5. Fonction premium pour bloquer et acheter le saut de page

Cliquez sur le bouton menu premium:

  1. verifyCached(licenseCode, machineCode, activationToken) Retour valide et non expiré → libération;
  2. Retour invalide/expiré/inactif → message pop-up «besoin d’acheter une autorisation d’activation»;
  3. générer machineCode, sauter à la page d’achat (le produit est identifié comme productUniqueCode, porte le code machine) :
https://www.powersoftware.app/product/license/purchase?productUniqueCode={productUniqueCode}&machineCode={machineCode}

(site multilingue avec préfixe de langue avant le chemin, comme /en-US/product/license/purchase;productUniqueCode Entrant par le constructeur.)

5.1 choix de la station d’achat:.app(station internationale) vs .cn(stations domestiques)

Le réseau powerstack dispose de deux sites, SDK purchaseUrl() Grâce à base Commutation des paramètres:

powersoftware.app(station internationale) powersoftware.cn(stations domestiques)
Moyens de paiement Alipay + PayPal Seulement avec alipay
Pays/devise Cloudflare automatiquement identifié par IP (CN→CNY, le reste →USD) fixes country=CN, yuan chinois
Langue (S) Par URL préfixe / Accept-Language Détection automatique de fixes zh-CN
Pour les utilisateurs Utilisateurs internationaux/outre-mer Utilisateurs en Chine continentale

SDK par défaut .app, ne pas faire de jugement automatique. Le logiciel client doit décider de transférer qui base.

Mode de jugement

Mode 1: par langue de système (recommandé)

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";
}

Mode 2: article défini par l’utilisateur - l’écran de configuration offre l’option «région», que l’utilisateur choisit lui-même.

Mode 3: codage dur - ecriture directe pour les logiciels pour les utilisateurs domestiques seulement base="https://www.powersoftware.cn".

Pour plus de détails, voir 语言与国家逻辑 La section 2.4.

6. Code d’erreur (SDK lance l’erreur unifiée porte errorCode)

codeNotFound,revoked,expired,machineLimit,tooManyAttempts,signatureInvalid,apiSecretMissing,productNotEnabled,trialNotEnabled,trialAlreadyPurchased,trialAlreadyPurchased,trialAlreadyPurchased,machineCodeInvalid,orderAlreadyUsed,editionRequired,productNotFound,trialFirstRequired,alreadyOwned , etc.; Erreur réseau/timeout unifiée comme NETWORK_ERROR.

7. Structure de paquet

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

Les trois packs sont disponibles:machineCode(),sign(),LicenseClient(6 méthodes ci-dessus + verifyCached + purchaseUrl).