Aller au contenu
Retour à la documentation de Launch

Télécharger le MarkdownDocument original sur GitHub

Guide d'Intégration du Système d'Autorisation Personnalisé

Le code source actuel prend en charge deux fournisseurs d'autorisation : Licentivo et custom_http. Les commerçants peuvent en sélectionner et activer un dans Paramètres du système → Système d'autorisation, et tous les produits et environnements sandbox/en direct utiliseront le même fournisseur ; les connexions personnalisées et les mappages de plans sont toujours configurés séparément par produit et environnement. Cette fonctionnalité n'inclut pas de système d'autorisation auto-construit ; les commerçants continuent d'utiliser leurs propres services d'autorisation et SDK.

L'échange de compte Licentivo existant, le SDK en neuf langues et la gestion des appareils continuent d'utiliser le processus original. Les produits personnalisés synchronisent le statut des achats selon ce protocole, et les clients lisent la livraison de l'autorisation dans le centre de compte sans passer par le processus SDK Licentivo.

Démarrage rapide

  1. Implémentez les quatre interfaces HTTP suivantes dans votre propre service, en configurant des clés et identifiants HMAC indépendants pour chaque connexion.
  2. Dans le 'Système d'Authorization', sélectionnez 'Service d'Authorization Personnalisé', ajoutez une nouvelle connexion, remplissez l'adresse, l'environnement, l'identifiant de connexion, l'ID de clé et la clé standard Base64, vérifiez et enregistrez, puis cliquez sur 'Activer le Service d'Authorization Personnalisé'.
  3. Créez des brouillons de produits et de plans de vente. Le type d'achat et le prix sont gérés dans Launch ; les règles d'authorization sont gérées dans votre propre système.
  4. Sélectionnez le produit et l'environnement, sélectionnez la connexion, remplissez les références du produit et du plan externe, et enregistrez. Le fournisseur est déterminé par la sélection globale du site et ne peut pas activer Licentivo en même temps pour d'autres produits.
  5. Publie une version test sur la page du plan de vente, complète les tests d’acceptation pour le paiement, la livraison, le renouvellement, la mise à niveau, le remboursement et la récupération des erreurs, puis configure l’environnement de production séparément.

Une fois que l’adresse, l’environnement, l’identifiant de connexion et la politique d’accès au réseau sont créés, ils ne peuvent plus être modifiés ; crée une nouvelle connexion si nécessaire. Les clés de signature peuvent être renouvelées ; laisse vide pour conserver la clé originale. Lorsqu’il y a des commandes sous un autre système d’autorisation, le fournisseur du site entier ne peut pas être changé directement ; la migration doit être complétée d’abord. Après le changement, le plan original devient uniquement en aperçu et doit être republier ; les identifiants et mappages de connexion enregistrés sont conservés. Les produits avec des commandes existantes ne peuvent pas changer de connexion directement, et les mappages dans les ventes ne peuvent pas être changés directement ; les nouveaux prix ou mappages utilisent une nouvelle version du plan.

Lors de la configuration via l'API, appelez d'abord PUT /api/v1/admin/licensing/provider, avec le corps de la requête étant {"provider":"custom_http"} ou {"provider":"licentivo"}, puis enregistrez la correspondance des produits. Les fournisseurs non activés ne peuvent pas enregistrer les liaisons d'autorisation de produit ni les correspondances de stratégie de plan Licentivo.

Les vérifications de connexion confirment les protocoles, l'authentification, l'environnement et les types d'achat pris en charge, et ne créeront ni ne confirmeront des packages externes au nom des commerçants. L'acceptation de l'intégration en sandbox doit être effectuée avec de vrais packages externes avant la collecte officielle des paiements.

3. Processus d'intégration du commerçant

  1. Implémentez les quatre interfaces de ce document avant un système d'autorisation existant ; la logique de licence existante dans le système d'autorisation reste intacte.
  2. Créez une connexion « Service d'autorisation personnalisé » dans Launch, en configurant l'adresse HTTPS, l'identifiant de connexion, l'environnement et la clé de signature.
  3. Launch appelle l'interface de vérification des capacités pour confirmer la version du protocole, la prise en charge des achats permanents/temporaire et la méthode de livraison.
  4. Sélectionnez cette connexion pour le produit ; mappez la version du package de vente sur product_ref et plan_ref externes. Les codes externes peuvent utiliser les propres chaînes du commerçant et n'ont pas besoin d'utiliser l'UUID Licentivo.
  5. Complétez le paiement, le renouvellement, la mise à niveau, le remboursement et la récupération des pannes dans le bac à sable, puis publiez la configuration en direct séparément.
  6. Après vérification du paiement, Launch enregistre la commande, la couverture d'achat et les tâches en attente dans la même transaction de base de données.
  7. Le backend envoie un instantané complet de l'achat au Service d'Autorisation Personnalisé ; le service conserve l'enregistrement reçu avant de confirmer la réception.
  8. Le service d'autorisation traite le statut cible. Launch interroge le reçu de l'événement original, et seul applied confirme que cette synchronisation est terminée.
  9. Launch récupère les informations de livraison pour les clients connectés qui possèdent l'achat et affiche le code d'autorisation, l'entrée d'activation ou les instructions en texte clair dans le centre client. L'application se connecte au propre système d'autorisation du marchand.
  10. Le renouvellement, la mise à niveau, le remboursement, le retrait, la suspension et l'expiration génèrent tous une nouvelle version de l'instantané complet. Le service d'autorisation traite selon le dernier statut cible.

Les connexions sandbox/live du même produit sont liées séparément. Après un achat existant, le changement de fournisseur nécessite un processus de migration indépendant ; les anciennes commandes et les anciennes tâches ne peuvent pas suivre la sélection du backend et être envoyées silencieusement au nouveau service.

4. APIs requises par le service d'autorisation personnalisé

Les interfaces suivantes sont reçues par le service d'autorisation du commerçant et appelées par le serveur Launch. base_url peut inclure un préfixe de chemin fixe ; les chemins dans le tableau sont ajoutés après ce préfixe.

Méthodes et chemins Usage
GET /launch/v1/capabilities Vérifications de connexion, protocoles et déclarations de capacités
POST /launch/v1/events Recevoir le statut complet de l'achat cible ; réessayer en utilisant l'événement original
GET /launch/v1/events/{event_id} Vérifier si l'événement est réellement appliqué et restaurer les réponses perdues
GET /launch/v1/entitlements/{entitlement_ref}/delivery Lire les informations de livraison déjà autorisées sans créer une deuxième autorisation

La première édition utilise des reçus de requête actifs et n'ajoute pas de callbacks externes pour modifier les commandes. Les services personnalisés n'ont pas le pouvoir de confirmer le paiement, de changer les prix ou de réécrire les périodes d'achat.

4.1 Conventions générales et authentification

  • JSON utilise UTF-8 ; le temps utilise UTC RFC 3339 ; version utilise des entiers positifs.
  • Une réponse réussie est {"data": {...}, "request_id": "..."} ; une réponse d'erreur est {"error": {"code": "...", "message": "..."}, "request_id": "..."}.
  • Chaque environnement et connexion utilise une clé séparée. La clé doit contenir au moins 32 octets aléatoires, référencés dans Launch depuis le stockage de clés chiffrées existant, et ne doit pas être placée dans la configuration front-end, les exemples ou les packages d'application.
  • Chaque requête transporte X-Launch-Key-Id, X-Launch-Timestamp, X-Launch-Nonce, X-Launch-Signature.
  • L'horodatage est en secondes Unix décimales. Le nonce est un encodage base64 d'au moins 128 bits de valeur aléatoire sans remplissage, et une nouvelle valeur est générée à chaque tentative réseau.

L'entrée de la signature se compose des sept éléments suivants, encodés en octets UTF-8 et reliés par un seul saut de ligne, sans saut de ligne final :

v1
<key_id>
<timestamp>
<nonce>
<UPPERCASE HTTP method>
<encoded request path and raw query, including the base_url path prefix>
<lowercase hexadecimal SHA-256 digest of the exact request body>

X-Launch-Signature se compose du préfixe v1= suivi du résultat de HMAC-SHA256 encodé en base64url sans remplissage. Le corps des requêtes GET est vide. Le destinataire vérifie la signature et la fenêtre temporelle avant la désérialisation, utilise une comparaison en temps constant, accepte par défaut un décalage de ±300 secondes et conserve les nonces pendant au moins 600 secondes pour empêcher le rejeu. Ne réutilisez pas les nonces entre les tentatives ; l’ID d’événement et le corps métier de la requête restent inchangés.

Les signatures ne remplacent pas HTTPS. Les requêtes ne contiennent pas de mots de passe clients, de clés de paiement ou de clés de gestion Licentivo ; par défaut, seules des références de compte anonymes sont envoyées, pas les adresses e-mail. Les clients HTTP du serveur ont besoin de délais d’attente, de limites de taille pour les réponses et du désactivation du transfert des identifiants lors des redirections. Les adresses personnalisées doivent être validées ; l’accès à l’intranet doit être configuré explicitement par les administrateurs.

Vérification des capacités 4.2

GET /launch/v1/capabilities renvoie HTTP 200, par exemple :

{
  "data": {
    "protocol": "launch-external-licensing-v1",
    "connection_ref": "merchant-01-sandbox",
    "environment": "sandbox",
    "purchase_types": ["perpetual", "fixed_term"],
    "delivery_types": ["license_key", "activation_url", "instructions"],
    "devices": false,
    "identity_exchange": false
  },
  "request_id": "check-001"
}

protocol, connection_ref, environment, purchase_types, delivery_types sont requis. Les deux derniers doivent être des tableaux non vides, et les types d’achat non pris en charge ne peuvent pas être listés à la vente. Les premières versions devices et identity_exchange doivent être false ; le support ne peut être déclaré qu’après la finalisation du contrat étendu et de la mise en œuvre.

Instantané d’achat 4.3

Exemple de demande pour POST /launch/v1/events :

{
  "schema": "launch-external-licensing-v1",
  "event_id": "7bf84b91-2749-4b01-a6a7-bd527c488ee8",
  "connection_ref": "merchant-01-sandbox",
  "environment": "sandbox",
  "type": "entitlement.snapshot",
  "change_reason": "purchase",
  "account_ref": "customer_opaque_001",
  "entitlement_ref": "purchase_opaque_001",
  "launch_product_id": "c6dd463e-50f7-4b76-8239-0a8ec6fc304b",
  "launch_plan_version_id": "5459a073-9362-4b46-949d-9b0c5d84421a",
  "product_ref": "desktop-editor",
  "plan_ref": "professional-yearly-v1",
  "version": 1,
  "desired_state": "active",
  "valid_from": "2026-10-25T00:00:00Z",
  "valid_until": "2027-10-25T00:00:00Z"
}

Tous les champs de l'exemple ci-dessus sont obligatoires. valid_until en tant que null signifie achat permanent ; les autres valeurs doivent être postérieures à valid_from.

Champ Contraintes et signification
event_id UUID généré par Launch ; reste le même si le même événement est réessayé
connection_ref / environment Doit correspondre à la connexion et à l'environnement de la clé de signature
account_ref Référence de compte anonyme stable ; le destinataire identifie le client en utilisant la connexion, l'environnement et cette référence ensemble
entitlement_ref Référence stable pour une relation d'achat ; si entièrement révoquée, une nouvelle référence est utilisée pour un nouvel achat
launch_product_id / launch_plan_version_id Produit de Launch et UUID de version de package immuable
product_ref / plan_ref Référence externe configurée par l'intégrateur ; caractères ASCII 1–128, lettres, chiffres, _, -, . autorisés ; les packages externes ne sont pas créés automatiquement
version Version cible qui augmente de manière monotone sous la même connexion, environnement et référence d'achat
desired_state active、suspended、expired、revoked
change_reason purchase、renewal、upgrade、refund、reversal、suspension、resumption、expiry、reconciliation

account_ref, entitlement_ref utilisent les lettres, chiffres, underscores ou tirets de 1–128. schema, type sont fixés aux valeurs d'exemple. Le récepteur applique les résultats selon desired_state et le terme absolu complet, sans ajouter de jours ni révoquer lui-même l'autorisation entière.

Surtout pour les remboursements : après avoir retourné une commande de renouvellement ou de mise à niveau, l'achat de base valide peut encore rester ; dans ce cas, la capture instantanée peut toujours être active, mais la durée est raccourcie ou le forfait change. Ce n'est qu'après que le grand livre est recalculé et qu'aucun achat valide ne le couvre que le statut de résiliation correspondant est envoyé.

Réception, Accusé de réception et Récupération de 4.4

Le récepteur doit retourner HTTP 202 uniquement après avoir conservé l'ID de l'événement, le résumé du corps de la requête initiale et la tâche à exécuter ; les requêtes répétées qui ont déjà été synchronisées peuvent retourner HTTP 200. Les deux retourneront la structure d'accusé de réception suivante.

{
  "data": {
    "event_id": "7bf84b91-2749-4b01-a6a7-bd527c488ee8",
    "connection_ref": "merchant-01-sandbox",
    "environment": "sandbox",
    "entitlement_ref": "purchase_opaque_001",
    "version": 1,
    "payload_sha256": "<64-character lowercase hexadecimal SHA-256 digest of the exact event body>",
    "status": "pending",
    "error_code": null
  },
  "request_id": "receipt-001"
}

Remplacez le marqueur du condensat par le condensat réel. Tous les champs du reçu ci-dessus sont obligatoires ; error_code vaut null en l’absence d’erreur. GET /launch/v1/events/{event_id} renvoie la même structure avec HTTP 200. L’état peut être :

status Signification Traitement de Launch
pending Persisté mais le changement d'autorisation réel n'est pas encore terminé Requête retardée, impossible de marquer comme synchronisé
applied Le service d'autorisation confirme que l'état cible a été effectivement appliqué Synchronisation confirmée après vérification de tous les champs liés et du digest
rejected Clairement non applicable, par ex. le paquet externe n'existe pas Arrêter les tentatives automatiques, afficher une erreur claire
manual_review Résultat incertain ou conflit d'état, nécessite une vérification manuelle La tâche et l'événement d'origine sont conservés, en attente de traitement auditable

Le statut de livraison est indépendant du reçu de synchronisation ; applied ne peut pas servir directement de permission opérationnelle pour l'application client.

Exigences de fiabilité :

  • Livraison au moins une fois ; le récepteur doit garantir l'idempotence métier ; il ne peut pas promettre « appel unique » au niveau réseau.
  • Retourner les résultats existants pour le même ID d'événement et le même corps de requête original ; retourner HTTP 409 IDEMPOTENCY_CONFLICT pour le même ID mais un corps de requête différent.
  • Les anciennes versions ne doivent pas écraser les nouvelles versions. Différents événements ou cibles de la même version d'achat ne doivent pas être acceptés silencieusement et doivent renvoyer HTTP 409 STATE_VERSION_CONFLICT pour vérification.
  • Si une réponse POST est perdue ou si le processus redémarre, Launch effectue d'abord un GET sur l'événement original ; ce n'est qu'après avoir explicitement renvoyé EVENT_NOT_FOUND que l'ID original et le corps de requête doivent être renvoyés.
  • Si le résultat réel de la livraison à distance est incertain, l'intégrateur doit également utiliser sa propre référence idempotente persistée pour vérification et ne peut pas générer une autre autorisation en renvoyant simplement une fois.
  • HTTP 429 suit Retry-After ; les erreurs de délai d'attente et 5xx se récupèrent avec une reprise progressive ; dépasser la limite nécessite une vérification manuelle. L'authentification, la configuration et les rejets commerciaux ne doivent pas être considérés comme une synchronisation réussie.

Codes d'erreur suggérés : SIGNATURE_INVALID (401), SIGNATURE_EXPIRED (401), NONCE_REPLAYED (409), SCOPE_MISMATCH (403), EVENT_NOT_FOUND (404), IDEMPOTENCY_CONFLICT (409), STATE_VERSION_CONFLICT (409), PLAN_UNKNOWN (422), PURCHASE_TYPE_UNSUPPORTED (422), RATE_LIMITED (429), SERVICE_UNAVAILABLE (503). Les messages d'erreur ne doivent pas inclure d’identifiants.

4.5 Livraison Autorisée

GET /launch/v1/entitlements/{entitlement_ref}/delivery peut uniquement lire les résultats de livraison existants dans cette connexion et cet environnement et ne doit pas considérer les requêtes comme de nouvelles commandes d'émission. Exemple HTTP 200 :

{
  "data": {
    "connection_ref": "merchant-01-sandbox",
    "environment": "sandbox",
    "entitlement_ref": "purchase_opaque_001",
    "version": 1,
    "status": "ready",
    "delivery": {
      "type": "license_key",
      "value": "EXAMPLE-ONLY-NOT-A-REAL-LICENSE",
      "expires_at": null
    }
  },
  "request_id": "delivery-001"
}

status est pending, ready ou unavailable ; lorsqu’il n’est pas prêt, delivery est null. Lorsqu’il est prêt, type doit être un license_key, activation_url ou instructions déclaré, avec value jusqu’à 4096 UTF-8 octets, et expires_at en temps UTC ou null. Tous les champs liés dans la réponse doivent correspondre à la version actuelle achetée dans Launch ; les livraisons des anciennes versions ne peuvent pas être considérées comme des résultats actuels.

Les codes d'autorisation sont des données sensibles ; les réponses de livraison utilisent Cache-Control: no-store, ne loguez pas le corps et elles doivent être stockées chiffrées si une persistance est nécessaire. Les URL d'activation acceptent uniquement les sources HTTPS autorisées par la configuration de la connexion ; les instructions sont affichées en texte brut, sans exécuter de HTML ni de scripts. Les comptes qui sont révoqués, entièrement remboursés ou sans achat valide ne peuvent pas continuer à obtenir des infos de livraison via Launch ; l'expiration réelle des identifiants livrés est gérée par des systèmes externes.

Gestion Launch et API client

Ces interfaces sont sous l'origine Launch déployée par le marchand et n’utilisent pas l’authentification HMAC via un service externe. Les admins utilisent les sessions existantes du site web, et les requêtes d’écriture doivent inclure X-CSRF-Token. Les clients peuvent seulement lire leurs propres achats.

Méthodes et chemins Usage
GET /api/v1/admin/licensing/connections Retourne connections, bindings, mappings et default_provider ; La liste de connexions contient uniquement des connexions personnalisées, Licentivo l'interface de gestion d'origine est conservée
POST /api/v1/admin/licensing/connections Vérifier et ajouter des connexions personnalisées
PUT /api/v1/admin/licensing/connections/{id} Modifier le nom, les sources d'activation autorisées et la configuration de la signature ; L'adresse de réception historique reste inchangée
POST /api/v1/admin/licensing/connections/{id}/check Reverifier ; last_check_error en HTTP 200 qui n'est pas null signifie que la vérification a échoué
PUT /api/v1/admin/products/{id}/licensing Fournit le fournisseur de la configuration de l'environnement pour le produit, mappant les connexions aux packages externes
GET /api/v1/me/products/{id}/delivery?environment=sandbox Le client actuel lit la livraison d'autorisation d'achat personnalisée actuellement valide ; Authentification par cookie ou par porteur de bureau
GET /api/v1/licensing/documentation Ce document ne nécessite pas de connexion
GET /api/v1/licensing/protocol Le OpenAPI requis pour les services personnalisés ne nécessite pas de connexion

Ajouter un corps de requête de connexion personnalisée :

{
  "provider": "custom_http",
  "name": "My licensing service",
  "base_url": "https://licenses.example.com",
  "environment": "sandbox",
  "connection_ref": "merchant-01-sandbox",
  "key_id": "key-1",
  "signing_key": "<standard Base64 encoding of 32 to 128 random bytes>",
  "allow_private_network": false,
  "allow_local_http": false,
  "activation_origins": ["https://activate.example.com"]
}

La réponse data est l'objet de connexion désensibilisé et ne renvoie ni la clé de signature ni l'identifiant secret. allow_local_http ne permet que l'adresse localhost/loopback du sandbox ; HTTPS privé nécessite une autorisation explicite de l'administrateur. Laisser la clé vide n'est autorisé que pour modifier des connexions existantes. Licentivo est encore configuré via POST /api/v1/admin/connections/licentivo.

Configurez le corps de la demande du produit :

{
  "provider": "custom_http",
  "environment": "sandbox",
  "connection_id": "<id returned when creating the connection>",
  "mappings": [
    {
      "version_id": "<Launch plan version UUID>",
      "product_ref": "desktop-editor",
      "plan_ref": "professional-yearly-v1"
    }
  ]
}

Lorsque Licentivo est sélectionné, {"provider":"licentivo","environment":"sandbox","mappings":[]} est envoyé, et son mappage produit/politique utilise toujours l'interface originale. Le premier interrupteur transforme une version existante en aperçu, ce qui nécessite une nouvelle vérification et publication par le nouveau fournisseur. Les mappages ne peuvent inclure que la version à ajouter ou à conserver ; les omettre ne supprimera pas les anciens mappages.

La livraison client est l'enveloppe de données standard pour HTTP 200 ; pas de retours d'achat 404, Licentivo, retour de marchandises 409 LICENSING_DELIVERY_UNSUPPORTED, non synchronisé, suspendu, expiré ou retours avec remboursement complet 409 ENTITLEMENT_NOT_READY, externe indisponible ou retours avec réception non correspondante 503. La fonction « Voir la livraison autorisée » du Centre Client revalide la propriété et le statut, sans écrire les identifiants dans les URL ou les journaux.

L'identité, l'appareil et les interfaces de vérification d'intégration du produit personnalisé Licentivo renvoient 409 CUSTOM_LICENSING_SDK_REQUIRED. L'ancien /credential continue de renvoyer 410. Les applications doivent utiliser le SDK du commerçant lui-même, plutôt que de considérer le statut Launch ready comme une autorisation à l'exécution.

Exemples et Acceptation

Python exemple d'adaptateur léger fournit un cadre de réception avec signature, nonce, déduplication d'événements et persistance des reçus ; la gestion réelle de l'autorisation nécessite une intégration avec le système du commerçant.

Le protocole personnalisé OpenAPI et Launch possède OpenAPI décrivent les deux directions séparément. Le récepteur n'a pas besoin de mettre en œuvre le catalogue de produits, le catalogue de politiques ou les interfaces de confiance d'identité de Licentivo.

La vérification locale utilise le MySQL isolé, un vrai adaptateur HTTP, et des services d'autorisation/paiement simulés, couvrant la perte de réponse, le redémarrage, le renouvellement, la mise à jour, le remboursement, la désactivation de compte, la non-correspondance des reçus et l’isolation de la livraison. Pour l’acceptation en production, le service d’autorisation et l’application du marchand sont également requis. Les appareils non enregistrés, la connexion avec un compte partagé et les fonctionnalités hors ligne ne sont pas couverts par Launch.