> ## Documentation Index
> Fetch the complete documentation index at: https://chariow.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Licences

> Apprenez à gérer les licences logicielles via l'API Chariow

Chariow fournit une gestion intégrée des clés de licence pour les produits logiciels. Les licences sont générées automatiquement lorsque les clients achètent des produits de type licence et peuvent être activées, validées et révoquées via l'API.

## Objet Licence

Une licence contient des informations complètes sur son statut, son historique d'activation et sa validité :

```json theme={null}
{
  "id": "lic_abc123",
  "status": "active",
  "customer": {
    "id": "cus_xyz789",
    "name": "Jean Dupont",
    "email": "jean@example.com"
  },
  "product": {
    "id": "prd_abc456",
    "name": "Premium Software License",
    "slug": "premium-software-license"
  },
  "license": {
    "key": "ABC-123-XYZ-789",
    "masked_key": "ABC-***-***-789"
  },
  "is_active": true,
  "is_expired": false,
  "can_activate": true,
  "activations": {
    "count": 3,
    "max": 10,
    "remaining": 7
  },
  "certificate_url": "https://api.chariow.com/certificates/lic_abc123.pdf",
  "metadata": null,
  "activated_at": "2025-01-15T10:30:00.000000Z",
  "expires_at": "2026-01-15T10:30:00.000000Z",
  "expired_at": null,
  "revoked_at": null,
  "created_at": "2025-01-15T09:00:00.000000Z",
  "updated_at": "2025-01-15T10:30:00.000000Z"
}
```

### Champs Clés

* **`license.key`** : La chaîne de clé de licence unique (par exemple, `ABC-123-XYZ-789`)
* **`license.masked_key`** : Version masquée pour l'affichage (par exemple, `ABC-***-***-789`)
* **`status`** : Statut actuel de la licence (voir le tableau ci-dessous)
* **`is_active`** : Booléen indiquant si la licence est actuellement active et utilisable
* **`is_expired`** : Booléen indiquant si la licence a expiré
* **`can_activate`** : Booléen indiquant si la licence peut être activée (a des emplacements restants)
* **`activations.count`** : Nombre actuel d'activations d'appareils
* **`activations.max`** : Nombre maximal d'activations autorisées
* **`activations.remaining`** : Nombre d'emplacements d'activation restants
* **`certificate_url`** : URL pour télécharger le certificat de licence (si disponible)
* **`activated_at`** : Date de la première activation de la licence (null si jamais activée)
* **`expires_at`** : Date d'expiration de la licence (null pour les licences à vie)
* **`revoked_at`** : Date de révocation de la licence (null si non révoquée)

## Statuts des Licences

| Statut               | Description                                |
| -------------------- | ------------------------------------------ |
| `pending_activation` | Licence créée mais pas encore activée      |
| `active`             | Licence activée et valide pour utilisation |
| `expired`            | Licence ayant dépassé sa date d'expiration |
| `revoked`            | Licence révoquée de manière permanente     |

## Lister les Licences

Récupérez toutes les licences émises pour votre boutique :

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.chariow.com/v1/licenses" \
    -H "Authorization: Bearer sk_live_your_api_key"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.chariow.com/v1/licenses', {
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key'
    }
  });

  const { data } = await response.json();
  ```
</CodeGroup>

### Paramètres de Requête

| Paramètre     | Type    | Description                                                               |
| ------------- | ------- | ------------------------------------------------------------------------- |
| `per_page`    | integer | Nombre de licences par page (par défaut 50, maximum 100)                  |
| `cursor`      | string  | Curseur de pagination de la réponse précédente                            |
| `status`      | string  | Filtrer par statut (`pending_activation`, `active`, `expired`, `revoked`) |
| `customer_id` | string  | Filtrer par ID public du client (par exemple, `cus_abc123`)               |
| `product_id`  | string  | Filtrer par ID public du produit (par exemple, `prd_def456`)              |

### Exemples de Filtrage

```bash theme={null}
# Obtenir uniquement les licences actives
curl -X GET "https://api.chariow.com/v1/licenses?status=active" \
  -H "Authorization: Bearer sk_live_your_api_key"

# Obtenir les licences pour un produit spécifique
curl -X GET "https://api.chariow.com/v1/licenses?product_id=prd_abc123" \
  -H "Authorization: Bearer sk_live_your_api_key"

# Obtenir les licences pour un client spécifique
curl -X GET "https://api.chariow.com/v1/licenses?customer_id=cus_xyz789" \
  -H "Authorization: Bearer sk_live_your_api_key"
```

## Obtenir une Licence par Clé

Récupérez une licence spécifique en utilisant sa clé de licence :

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.chariow.com/v1/licenses/ABC-123-XYZ-789" \
    -H "Authorization: Bearer sk_live_your_api_key"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.chariow.com/v1/licenses/ABC-123-XYZ-789', {
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key'
    }
  });

  const { data } = await response.json();
  ```
</CodeGroup>

## Valider une Licence

Pour valider une licence dans votre application, récupérez-la et vérifiez son statut :

```javascript theme={null}
async function validateLicense(licenseKey) {
  const response = await fetch(
    `https://api.chariow.com/v1/licenses/${licenseKey}`,
    { headers: { 'Authorization': 'Bearer sk_live_your_api_key' }}
  );

  if (!response.ok) {
    return { valid: false, reason: 'Licence introuvable' };
  }

  const { data } = await response.json();

  if (!data.is_active) {
    return { valid: false, reason: 'La licence n\'est pas active' };
  }

  if (data.is_expired) {
    return { valid: false, reason: 'La licence a expiré' };
  }

  return { valid: true, license: data };
}
```

## Activer une Licence

Activez une licence sur un appareil. Le système capture automatiquement l'adresse IP et l'agent utilisateur :

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.chariow.com/v1/licenses/ABC-123-XYZ-789/activate" \
    -H "Authorization: Bearer sk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "device_identifier": "00:1B:44:11:3A:B7"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.chariow.com/v1/licenses/ABC-123-XYZ-789/activate',
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer sk_live_your_api_key',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        device_identifier: '00:1B:44:11:3A:B7'  // Adresse MAC, UUID, etc.
      })
    }
  );
  ```
</CodeGroup>

### Comportement de la Première Activation

Lors de la première activation :

* Le statut passe de `pending_activation` à `active`
* L'horodatage `activated_at` est défini
* `expires_at` est calculé en fonction de la période de validité du produit
* `activation_count` s'incrémente à 1

### Activations Suivantes

Lors des activations supplémentaires :

* `activation_count` est incrémenté
* Un nouveau record d'activation est créé
* Le statut de la licence reste `active`

### Limites d'Activation

Chaque licence a un nombre maximal d'activations (`max_activations`). Lorsque la limite est atteinte, les activations supplémentaires échoueront :

```json theme={null}
{
  "message": "Limite d'activation atteinte",
  "data": [],
  "errors": []
}
```

Vérifiez `can_activate` et `activations.remaining` avant de tenter une activation.

## Révoquer une Licence

Révoquez une licence pour empêcher toute utilisation ultérieure :

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.chariow.com/v1/licenses/ABC-123-XYZ-789/revoke" \
    -H "Authorization: Bearer sk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "reason": "Le client a demandé un remboursement"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.chariow.com/v1/licenses/ABC-123-XYZ-789/revoke',
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer sk_live_your_api_key',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        reason: 'Le client a demandé un remboursement'
      })
    }
  );
  ```
</CodeGroup>

<Warning>
  La révocation d'une licence est permanente. La licence ne peut pas être réactivée après révocation.
</Warning>

## Obtenir l'Historique des Activations

Consultez toutes les activations pour une licence spécifique avec un suivi détaillé des appareils :

```bash theme={null}
curl -X GET "https://api.chariow.com/v1/licenses/ABC-123-XYZ-789/activations?per_page=20" \
  -H "Authorization: Bearer sk_live_your_api_key"
```

### Réponse

```json theme={null}
{
  "data": [
    {
      "id": "act_abc123",
      "activated_by": {
        "ip": {
          "value": "203.0.113.45",
          "country": {
            "code": "US",
            "name": "États-Unis"
          }
        },
        "user_agent": {
          "browser": "Chrome",
          "platform": "Windows",
          "device": "desktop"
        },
        "device": "00:1B:44:11:3A:B7"
      },
      "metadata": null,
      "activated_at": "2025-01-18T15:42:00.000000Z",
      "created_at": "2025-01-18T15:42:00.000000Z"
    },
    {
      "id": "act_def456",
      "activated_by": {
        "ip": {
          "value": "198.51.100.12",
          "country": {
            "code": "FR",
            "name": "France"
          }
        },
        "user_agent": {
          "browser": "Safari",
          "platform": "macOS",
          "device": "desktop"
        },
        "device": "A4:5E:60:D8:2F:11"
      },
      "metadata": null,
      "activated_at": "2025-01-16T09:15:00.000000Z",
      "created_at": "2025-01-16T09:15:00.000000Z"
    }
  ],
  "pagination": {
    "count": 2,
    "per_page": 20,
    "next_cursor": null,
    "prev_cursor": null,
    "has_more_pages": false
  }
}
```

### Ce qui est Suivi

Chaque enregistrement d'activation contient :

* **Adresse IP** : Automatiquement capturée depuis la requête d'activation, avec géolocalisation
* **User Agent** : Informations de navigateur et de plateforme analysées
* **Identifiant de l'Appareil** : Identifiant optionnel que vous fournissez (adresse MAC, UUID, etc.)
* **Horodatage** : Moment de l'activation
* **Métadonnées** : Données personnalisées optionnelles

Ceci est utile pour :

* Auditer l'utilisation des licences
* Détecter les activités suspectes
* Fournir aux clients une gestion des appareils
* Déboguer les problèmes d'activation

## Exemple d'Implémentation

Voici un exemple complet de validation de licence dans une application de bureau :

```javascript theme={null}
class LicenseManager {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://api.chariow.com/v1';
  }

  async validate(licenseKey) {
    const response = await fetch(
      `${this.baseUrl}/licenses/${licenseKey}`,
      { headers: { 'Authorization': `Bearer ${this.apiKey}` }}
    );

    if (!response.ok) {
      throw new Error('Clé de licence invalide');
    }

    const { data } = await response.json();

    if (!data.can_activate) {
      throw new Error('La licence ne peut pas être activée');
    }

    return data;
  }

  async activate(licenseKey, deviceId) {
    const response = await fetch(
      `${this.baseUrl}/licenses/${licenseKey}/activate`,
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${this.apiKey}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ device_identifier: deviceId })
      }
    );

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.message);
    }

    return response.json();
  }
}

// Utilisation
const manager = new LicenseManager('sk_live_your_api_key');

try {
  const license = await manager.validate('ABC-123-XYZ-789');
  console.log('Licence valide:', license.is_active);

  await manager.activate('ABC-123-XYZ-789', getDeviceId());
  console.log('Licence activée avec succès');
} catch (error) {
  console.error('Erreur de licence:', error.message);
}
```

## Résumé des Endpoints API

| Endpoint                                | Méthode | Description                                  |
| --------------------------------------- | ------- | -------------------------------------------- |
| `/v1/licenses`                          | GET     | Lister toutes les licences avec filtrage     |
| `/v1/licenses/{licenseKey}`             | GET     | Obtenir les détails d'une licence spécifique |
| `/v1/licenses/{licenseKey}/activate`    | POST    | Activer la licence sur un appareil           |
| `/v1/licenses/{licenseKey}/revoke`      | POST    | Révoquer définitivement une licence          |
| `/v1/licenses/{licenseKey}/activations` | GET     | Obtenir l'historique des activations         |

## Bonnes Pratiques

### Sécurité

* N'exposez jamais votre clé API dans le code côté client
* Utilisez les clés API côté serveur uniquement
* Validez les licences côté serveur avant d'accorder l'accès
* Stockez les clés de licence de manière sécurisée sur l'appareil du client

### Identification des Appareils

* Utilisez des identifiants d'appareils uniques et persistants (adresse MAC, UUID matériel)
* N'utilisez pas d'identifiants modifiables par l'utilisateur (nom d'ordinateur, nom d'utilisateur)
* Considérez les identifiants spécifiques à la plateforme (Windows : GUID de machine, macOS : UUID matériel)

### Gestion des Activations

* Vérifiez `can_activate` avant de tenter une activation
* Affichez `activations.remaining` aux utilisateurs
* Implémentez une interface de gestion des appareils pour les clients
* Gérez les erreurs d'activation avec élégance

### Fréquence de Validation

* Validez au démarrage de l'application
* Re-validez périodiquement (par exemple, toutes les 24 heures)
* Mettez en cache les résultats de validation localement
* Implémentez une période de grâce hors ligne

### Gestion des Erreurs

* Gérez les erreurs réseau avec élégance
* Fournissez des messages d'erreur clairs aux utilisateurs
* Implémentez une logique de nouvelle tentative avec backoff exponentiel
* Enregistrez les tentatives d'activation pour le débogage

## Ressources Connexes

<CardGroup cols={2}>
  <Card title="Guide des Produits" icon="box" href="/fr/guides/products">
    Créer des produits de type licence
  </Card>

  <Card title="API Licences" icon="code" href="/api-reference/licenses/list-licenses">
    Consultez la référence complète de l'API Licences
  </Card>

  <Card title="Obtenir une Licence" icon="key" href="/api-reference/licenses/get-license">
    Récupérer les détails de la licence
  </Card>

  <Card title="Activer une Licence" icon="check" href="/api-reference/licenses/activate-license">
    Activer sur un appareil
  </Card>
</CardGroup>
