Offene Lizenz-API-Dokumentation

v1.0

Offene Lizenz-API-Dokumentation

Dieses Dokument richtet sich an Entwickler, die den Ablauf „Zahlung → Ausstellung → Aktivierung → Verifizierung“ in ihre eigene Software integrieren möchten (Client-Software / reine Vertriebsprodukte). Jede API wird mit Aufrufzeitpunkt, Anfrageparametern, Antwortfeldern und Fehlercodes beschrieben.

1. Grundkonzepte

Konzept Feld / Begriff Beschreibung
Software-API-Geheimnis licenseApiSecret Wird automatisch erzeugt, wenn das Produkt die „Lizenzaktivierung“ aktiviert. Im Produktbearbeitungsformular im Entwicklerzentrum einsehbar. Ihr Softwareserver berechnet damit die HMAC-Signatur, die Plattform verifiziert damit. Nur auf Ihrem Server speichern, niemals im Client einbetten.
Lizenzcode licenseCode Ein von der Plattform erzeugter eindeutiger Code. Benutzer aktivieren damit Ihre Software.
Maschinencode machineCode Eine vom Client erzeugte Gerätekennung (pro Computer eindeutig; stabilen Maschinen-Fingerabdruck hashen, mindestens 8 Zeichen).
Aktivierungstoken activationToken Wird von der Plattform bei Aktivierung / Ausstellung ausgestellt. Die Software speichert ihn und sendet ihn bei jeder Startprüfung zurück.
Bestell-ID clientOrderId Die Bestell-ID der In-Software-Zahlung (vom Client oder Server erzeugt). Die Plattform dedupliziert über „Produkt + Bestell-ID“, um doppelte Abbuchungen und doppelte Ausstellung zu verhindern.

2. Vorbereitung

  1. Aktivieren Sie beim Veröffentlichen des Produkts die „Lizenzaktivierung“ und speichern Sie das erzeugte Software-API-Geheimnis (licenseApiSecret);
  2. Konfigurieren Sie im Veröffentlichungsformular die Editionsliste (z. B. BASIC/PRO/ULTIMATE) und die Upgrade-Strategie (SAME_CODE = Upgrade mit gleichem Code / NEW_CODE = neuen Code ausstellen);
  3. Speichern Sie das Geheimnis auf Ihrem Softwareserver; der Client hält nur Lizenzcode und Aktivierungstoken.

3. API-Übersicht

Basispfad: https://www.powersoftware.app/frontApi (für lokale / Testumgebungen durch Ihre Bereitstellungsdomain ersetzen).

API Aufrufzeitpunkt Authentifizierung Signatur
POST /license/software/generate Direkt nach erfolgreicher In-Software-Zahlung Keine (Signaturprüfung) Erforderlich
POST /license/software/upgrade Direkt nach erfolgreicher Verlängerungs- / Editions-Upgrade-Zahlung Keine (Signaturprüfung) Erforderlich
POST /license/activate Erste Aktivierung durch den Benutzer / Gerätewechsel Keine Nicht erforderlich
POST /license/verify Bei jedem Start der Software Keine Nicht erforderlich
POST /license/deactivate Benutzer hebt Bindung des alten Geräts auf (Profilbereich) Anmeldung Nicht erforderlich

4. Signaturregeln (erforderlich für generate / upgrade)

Signaturtext: Fügen Sie die folgenden Felder in genau dieser Reihenfolge mit Zeilenumbrüchen (\n) zusammen (fehlende optionale Felder mit Leerwerten: edition leere Zeichenkette, expiryDays = 0):

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

Signatur: HMAC-SHA256(Software-API-Geheimnis licenseApiSecret, Signaturtext), Base64URL-kodiert, in das Feld signature eintragen.

Replay-Schutz: timestamp ist ein Zeitstempel in Millisekunden. Die Plattform verlangt eine Abweichung von höchstens 5 Minuten zur Serverzeit, sonst wird signatureInvalid zurückgegeben.

Node.js-Beispiel:

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-Beispiel:

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 ist Standard-Base64, bei dem + durch -, / durch _ ersetzt und die =-Auffüllung am Ende entfernt wird.)

5. API-Details

5.1 Lizenzcode erzeugen (nach In-Software-Zahlung aufrufen)

Aufrufzeitpunkt: Direkt nach Abschluss einer In-Software-Zahlung ruft Ihr Server die API einmal auf und speichert Lizenzcode und Aktivierungstoken. Dieselbe Bestellung soll nur einmal gesendet werden; Wiederholungen sind idempotent und führen nicht zu einer zweiten Ausstellung.

POST /license/software/generate

Anfrageparameter (JSON-Body):

Parameter Typ Pflicht Quelle Beschreibung
productId number Ja Fest verdrahtet / Server-Konfiguration Produkt-ID, passend zum auf der Plattform veröffentlichten Produkt
machineCode string Ja Client erzeugt Maschinencode des aktuellen Geräts, mindestens 8 Zeichen
edition string Nein Bei Zahlung vom Client gewählt Editionskennung; muss in der Editionsliste des Produkts stehen; Standard ist die erste Edition
expiryDays number Nein Bei Zahlung vom Client gewählt Gültigkeitsdauer in Tagen, 0 = dauerhaft; Bereich 0-3650
clientOrderId string Ja Client / Server erzeugt Bestell-ID der In-Software-Zahlung, 1-64 Zeichen; Idempotenzschlüssel
timestamp number Ja Server erzeugt Zeitstempel in Millisekunden
signature string Ja Server berechnet HMAC-Signatur, mindestens 10 Zeichen

Antwortfelder von content:

Feld Typ Beschreibung
licenseId number ID des Lizenzdatensatzes
licenseCode string Der Lizenzcode (in Ihre Lizenzdaten schreiben)
productId number Produkt-ID
edition string Editionskennung
machineId number ID des gebundenen Maschinendatensatzes
activatedAt string Aktivierungszeit (ISO8601)
expiryTime string/null Ablaufzeit (ISO8601), null = dauerhaft
maxMachines number Maximale Anzahl bindbarer Maschinen
activationToken string Aktivierungstoken; für die Startprüfung speichern

Antwortbeispiel:

{
  "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..."
  }
}

Fehlercodes dieser API: productIdRequired, machineCodeInvalid, orderIdRequired, productNotFound, productNotEnabled, apiSecretMissing, signatureInvalid, orderAlreadyUsed.

5.2 Edition upgraden / verlängern (nach Zahlung aufrufen)

Aufrufzeitpunkt: Nach Abschluss einer Zahlung für Verlängerung oder Editions-Upgrade. Dieselbe Bestellung soll nur einmal gesendet werden.

POST /license/software/upgrade

Anfrageparameter (JSON-Body):

Parameter Typ Pflicht Quelle Beschreibung
productId number Ja Fest verdrahtet / Server-Konfiguration Produkt-ID
licenseCode string Ja In der Software gespeichert Aktueller Lizenzcode, mindestens 10 Zeichen
machineCode string Nein Client erzeugt Aktueller Maschinencode; bei Bindungsmigration (NEW_CODE) oder zusätzlicher Bindung angeben
edition string Ja Bei Zahlung vom Client gewählt Ziel-Editionskennung
expiryDays number Nein Bei Zahlung vom Client gewählt Zusätzliche Gültigkeitsdauer in Tagen, 0 = dauerhaft; Bereich 0-3650
clientOrderId string Ja Client / Server erzeugt Bestell-ID dieses Kaufs; Idempotenzschlüssel
timestamp number Ja Server erzeugt Zeitstempel in Millisekunden
signature string Ja Server berechnet HMAC-Signatur

Verarbeitungsstrategie (durch Produktkonfiguration bestimmt):

  • SAME_CODE (Upgrade mit gleichem Code): Der Lizenzcode bleibt gleich, Maschinenbindungen bleiben gültig, die Gültigkeit wird verlängert (dauerhaft bleibt dauerhaft). Die Antwort enthält zusätzlich upgraded: true;
  • NEW_CODE (neuen Code ausstellen): Der alte Code wird gesperrt, ein neuer Code wird ausgestellt und die Maschinenbindungen werden migriert. Die Antwort enthält zusätzlich oldLicenseId, und licenseCode ist der neue Code.

Antwortfelder von content: wie in 5.1, zusätzlich upgraded: true; bei NEW_CODE zusätzlich oldLicenseId (ID des alten Lizenzdatensatzes; der alte Code ist bereits gesperrt).

Fehlercodes dieser API: productIdRequired, licenseCodeRequired, orderIdRequired, productNotFound, productNotEnabled, apiSecretMissing, signatureInvalid, codeNotFound, revoked, orderAlreadyUsed, editionRequired.

5.3 Lizenz aktivieren (erste Aktivierung / neues Gerät)

Aufrufzeitpunkt: Nachdem der Benutzer einen Lizenzcode erhalten hat (Selbstausstellung, Verwaltungsausstellung usw.) und ihn auf der Aktivierungsseite der Client-Software eingibt. Beim Gerätewechsel auf dem neuen Gerät aufrufen.

POST /license/activate

Anfrageparameter (JSON-Body):

Parameter Typ Pflicht Quelle Beschreibung
licenseCode string Ja Benutzereingabe Lizenzcode, mindestens 10 Zeichen
machineCode string Ja Client erzeugt Maschinencode des aktuellen Geräts, mindestens 8 Zeichen

Antwortfelder von content: wie in 5.1 (licenseId, licenseCode, productId, edition, machineId, activatedAt, expiryTime, maxMachines, activationToken).

Hinweise:

  • Ein Lizenzcode kann an mehrere Maschinen gebunden werden, begrenzt durch maxMachines (Standard aus Produktkonfiguration);
  • Erneutes Aktivieren derselben Maschine nutzt die bestehende Bindung und stellt ein neues Aktivierungstoken aus (idempotent);
  • Fehlgeschlagene Aktivierungen werden pro IP + Lizenzcode begrenzt; zu viele Fehlversuche ergeben tooManyAttempts.

Fehlercodes dieser API: codeNotFound, revoked, expired, machineLimit, tooManyAttempts.

5.4 Lizenz verifizieren (bei jedem Start)

Aufrufzeitpunkt: Bei jedem Start der Software (oder vor dem Entsperren von Funktionen). Die Software muss das von 5.1 / 5.2 / 5.3 zurückgegebene activationToken speichern.

POST /license/verify

Anfrageparameter (JSON-Body):

Parameter Typ Pflicht Quelle Beschreibung
licenseCode string Ja In der Software gespeichert Lizenzcode, mindestens 10 Zeichen
machineCode string Ja Client erzeugt Maschinencode des aktuellen Geräts, mindestens 8 Zeichen
activationToken string Ja Von der Plattform ausgestellt, von der Software gespeichert Aktivierungstoken, mindestens 20 Zeichen

Antwortfelder von content:

Feld Typ Beschreibung
valid boolean Immer true (Fehler werden als Fehlercodes zurückgegeben)
licenseId number ID des Lizenzdatensatzes
productId number Produkt-ID
edition string Aktuelle Editionskennung
expiryTime string/null Ablaufzeit (ISO8601), null = dauerhaft

Hinweise:

  • Verifizierungsergebnisse werden ca. 60 Sekunden zwischengespeichert; Schreiboperationen (Sperren, Bindung aufheben, Upgrade) invalidierten den Cache sofort, Verzögerungen sind also kein Thema;
  • Die Software sollte expiryTime prüfen und nach Ablauf das Entsperren von Funktionen beenden.

Fehlercodes dieser API: tokenInvalid, machineNotActivated, invalidOrRevoked, expired, tooManyAttempts.

5.5 Gerätebindung aufheben (vor Gerätewechsel, Anmeldung erforderlich)

Aufrufzeitpunkt: Der Benutzer hebt die Bindung des alten Geräts unter „Profilbereich → Meine Lizenzen“ auf und aktiviert anschließend auf dem neuen Gerät über 5.3.

POST /license/deactivate

Anfrageparameter (JSON-Body):

Parameter Typ Pflicht Quelle Beschreibung
licenseCode string Ja Lizenzliste des Benutzers Lizenzcode, mindestens 10 Zeichen
machineCode string Ja Lizenzliste des Benutzers Der aufzuhebende Maschinencode, mindestens 8 Zeichen

Antwortfelder von content: true.

Hinweise:

  • Nur der Eigentümer der Lizenz (Käufer oder Benutzer, der den gebundenen Maschinencode registriert hat) kann dies ausführen;
  • Aufhebe-Kontingent: Standardmäßig kann dieselbe Lizenz innerhalb von 30 Tagen nur einmal aufgehoben werden (im Verwaltungsbereich konfigurierbar); bei Überschreitung wird unbindQuotaExceeded zurückgegeben.

Fehlercodes dieser API: noPermission, machineNotBound, unbindQuotaExceeded.

6. Fehlercodes

Geschäftsfehler werden einheitlich zurückgegeben (tip enthält eine lesbare Meldung):

{
  "code": "BUSINESS_WARNING",
  "requestId": "xxx",
  "success": false,
  "errorMessage": "LICENSE_GENERATE_FAILED",
  "tip": "Signature verification failed"
}

Fehler bei der Parameterprüfung ergeben code: "PARAM_VALIDATE_FAILED" und die konkrete Feldmeldung in tip.

Fehlercode Bedeutung
productNotEnabled Das Produkt hat die Lizenzaktivierung nicht aktiviert
apiSecretMissing Für das Produkt ist kein Software-API-Geheimnis (licenseApiSecret) konfiguriert
signatureInvalid Signaturprüfung fehlgeschlagen (Geheimnis falsch, Reihenfolge des Signaturtexts falsch oder Zeitstempel außerhalb des Fensters)
machineCodeInvalid Maschinencode ungültig (kürzer als 8 Zeichen)
orderAlreadyUsed Diese Bestellung hat bereits einen Lizenzcode erzeugt (Idempotenzkonflikt: mit anderem Maschinencode wiederholt)
codeNotFound Lizenzcode nicht gefunden
revoked Lizenzcode wurde gesperrt oder ist unbrauchbar
expired Lizenzcode ist abgelaufen
invalidOrRevoked Lizenz ist bei der Verifizierung ungültig oder gesperrt
machineNotActivated Diese Maschine ist nicht aktiviert
tokenInvalid Aktivierungstoken ungültig
machineLimit Die Obergrenze gebundener Maschinen ist erreicht
machineNotBound Diese Maschine ist nicht gebunden
noPermission Keine Berechtigung für diese Lizenz
unbindQuotaExceeded Die Lizenz kann innerhalb von 30 Tagen nur einmal aufgehoben werden; später erneut versuchen
tooManyAttempts Zu viele Versuche; später erneut versuchen
productNotFound Produkt nicht gefunden
editionRequired Bitte die Zieledition wählen

7. Typische Abläufe

  1. In-Software-Zahlungsschleife: Zahlung erfolgreich → software/generate (liefert Lizenzcode + Aktivierungstoken) → Software speichert beides → bei jedem Start verify → Funktionen entsperren; Verlängerung / Upgrade → software/upgrade;
  2. Selbstausstellung / Verwaltungsausstellung: Ein Lizenzcode wird im Entwicklerzentrum oder in der Verwaltung erzeugt → der Benutzer erhält den Code → im Client activate, um das Gerät zu binden und das Token zu erhalten → beim Start verify;
  3. Gerätewechsel: Altes Gerät über deactivate im Profilbereich entbinden → auf dem neuen Gerät activateverify;
  4. Unterschied der Upgrade-Strategie: SAME_CODE behält den gleichen Code; NEW_CODE stellt einen neuen Code aus (alter Code gesperrt, Maschinenbindungen werden automatisch migriert).

8. Hinweise

  • Geheimnis nur serverseitig: Die Signatur darf nur auf Ihrem Softwareserver erstellt werden; gelangt das Geheimnis in den Client, ist das Lizenzsystem wirkungslos;
  • Stabilität des Maschinencodes: Verwenden Sie einen stabilen Maschinen-Fingerabdruck und hashen Sie ihn; ändert sich der Maschinencode nach einer Neuinstallation, erst entbinden, dann erneut aktivieren;
  • Idempotenz: Machen Sie clientOrderId global eindeutig (z. B. Zeitstempel + Zufallswert); Wiederholungen führen nicht zu doppelter Ausstellung;
  • Cache: verify-Ergebnisse werden ca. 60 Sekunden gecacht und durch Schreiboperationen sofort invalidiert;
  • Ratenbegrenzung: Fehlgeschlagene Aktivierungen / Verifizierungen werden begrenzt; der Client sollte Fehlermeldungen und Wiederholungsabstände angemessen umsetzen;
  • Vertrauen Sie der Plattformantwort: Gültigkeit, Edition und Maschinenobergrenzen werden von der Plattform bestimmt; lockern Sie diese auf Softwareseite nicht selbst.