# Rezept: Lizenzschlüssel

> Verkaufen Sie eine Desktop-App, ein CLI, ein Plugin oder eine Vorlage mit Lizenzschlüsseln. Die App prüft den Schlüssel ohne jedes Geheimnis im Code.

Perly Pay stellt einen Schlüssel aus, wenn die Zahlung erfüllt ist, zählt Aktivierungen auf Geräten und beantwortet „ist dieser Schlüssel für dieses Produkt hier gültig?“ über öffentliche Endpunkte. Die Software, die Sie verteilen, nutzt `LicenseClient` – der braucht keinen geheimen Schlüssel.

> **Hinweis:** Mit einem Assistenten: Dieses Rezept setzt der Skill `sell-license-keys` des Perly-Pay-Plugins in Ihrem Projekt um. Ein lauffähiges Beispiel ist `examples/license-keys` (MIT) im Repository des Plugins.

## So funktioniert es

1. **Ein Produkt, das Schlüssel ausstellt** — `issues_license: true` und `license_activation_limit` (Geräte pro Schlüssel), mit Einmal-, Lebenslang-, Laufzeitpreis oder Abo.
2. **Verkaufen** — Ein [Zahlungslink](https://pay.perly.io/docs/payment-links.md) auf Ihrer Website oder eine Rechnung pro Käufer.
3. **Schlüssel senden** — Über den Webhook `license.created` (sein Objekt ist der Schlüssel) oder über `licenseKeys.list({ customer })` nach `invoice.fulfilled`. Der Beleg enthält keinen Schlüssel.
4. **Aktivierung in der App** — `activate({ key, product, instance_name })` mit einem Namen, der auf diesem Gerät gleich bleibt; speichern Sie die Aktivierungs-ID.
5. **Prüfung beim Start** — `validate({ key, product, instance })`. Ein klares `valid: false` sperrt; ohne Netz gilt die letzte gute Antwort ein paar Tage.

**Node**

```js
import { LicenseClient } from "perly-pay";

const licenses = new LicenseClient(); // no secret key, ever
const result = await licenses.activate({ key, product: "prod_…", instance_name: deviceName });
if (!result.valid) showWhy(result.reason); // limit_reached, revoked, expired, …
```

**PHP**

```php
use Perly\Pay\LicenseClient;

$result = (new LicenseClient())->activate(['key' => $key, 'product' => 'prod_…', 'instance_name' => home_url()]);
if (!$result['valid']) echo $result['reason'];
```

## Beispiel starten

1. **Installieren** — `npm install` in `examples/license-keys` (Node 20.12+).
2. **Schlüssel** — Kopieren Sie `.env.example` nach `.env` und tragen Sie einen Testschlüssel (`sk_test_…`) in `PERLY_PAY_SECRET_KEY` ein.
3. **Vorbereiten** — `npm run setup` legt mit Ihrem Schlüssel Produkt und Preis an und gibt ihre IDs für `.env` aus.
4. **Starten** — `npm start` (oder `npm run dev`), wie seine README sagt.
5. **Ohne Wallet bezahlen** — `npm run buy-test -- you@example.com` kauft eine Kopie im Testmodus und gibt den Schlüssel aus; dann `npm run app -- activate <key>` und `npm run app -- pro hello`.

## Fallstricke

- Ein Schlüssel `sk_…` in der App. Jeder kann ihn herausziehen; Software, die Sie verteilen, nutzt nur `LicenseClient`.
- Ohne `product` wird der Aufruf abgelehnt (`parameter_missing`). Geben Sie es immer mit; ein Schlüssel für etwas anderes ergibt `wrong_product`.
- Ein `instance_name`, der sich bei jedem Start ändert: Jeder Start verbraucht eine Aktivierung.
