# Validation de l’intégration d’application

> Les sondes en mode compte obtiennent désormais des assertions d’identité de courte durée. Un état négatif d’achat Launch constitue uniquement une preuve concernant l’achat, pas une preuve de refus à l’exécution par Licentivo. Cette dernière exige la sonde du SDK officiel ; aucun déploiement en production ni aucune publication de SDK ne sont impliqués. Voir [la frontière de responsabilité du compte](/fr/launch-documents/account-purchase-boundary/).

Deux niveaux de preuve distincts existent : les vérifications automatisées locales contrôlées et les sondes externes dans l’environnement sandbox du marchand. Un substitut de test, une lecture réussie du catalogue, une configuration générée ou un contrôle de santé réussi ne prouvent jamais un paiement, une émission de licence ou une activation réels. La configuration des services externes a été explicitement reportée pour cette itération de développement.

## Vérifications automatisées locales

Exécutez depuis la racine du dépôt :

```powershell
go test ./...
go vet ./...
node --check internal/httpapi/web/app.js
node --check internal/httpapi/web/integration.js
node --check internal/httpapi/web/integration-prompts.js
node --test scripts/integration-prompts.test.mjs scripts/integration-state.test.mjs
python scripts/test_acceptance.py
./scripts/test-mysql.ps1
```

L’utilitaire MySQL crée un serveur et des bases isolés sous `.cache` ; il ne doit jamais viser une base client. Un simple `go test ./...` ignore les scénarios de base de données si les DSN isolés ne sont pas fournis. Les tests et compilations des SDK et paquets sont décrits dans [integration-packages.md](/fr/launch-documents/integration-packages/). Conservez les sorties des tests et les versions des outils avec le dossier de publication.

La matrice locale couvre l’authentification, la vérification conditionnelle de l’adresse e-mail, l’appartenance du produit et de l’environnement, les états en attente, expiré et suspendu, le rejeu des événements de paiement, le rapprochement des licences, les renouvellements et remboursements, le changement de compte, la persistance protégée des sessions et les décisions de repli hors ligne. Les tests du cycle de vie utilisent des moteurs contrôlés ; la véritable vérification cryptographique à l’exécution reste la responsabilité du SDK officiel et fait l’objet de tests distincts avant publication.

Pour **Outils d’exploitation → Intégration rapide avec l’IA**, vérifiez les neuf langages proposés, le choix de la plateforme, du projet et des fonctionnalités, un brouillon non configuré et une consigne produite à partir d’une configuration publique validée. Comparez la copie et le téléchargement à la consigne visible ; changer de produit ou d’environnement ne doit pas conserver une configuration précédemment validée. Les consignes doivent exclure les sessions, mots de passe, identifiants de licence ou d’appareil à l’exécution et clés de gestion ; leur génération ou leur copie ne doit appeler aucun service d’IA. La commande de test Node de l’archive source ci-dessus teste le générateur pur. Une consigne générée, ou le code ensuite produit par un outil d’IA, exige encore les tests du langage et les étapes de validation externe ci-dessous.

## Préparer la validation externe en sandbox

1. Déployez une instance de test Launch dédiée, avec une origine HTTPS accessible et les webhooks des fournisseurs. Laissez les ventes en production désactivées.
2. Configurez les identifiants sandbox d’**un seul** fournisseur de paiement et une connexion Licentivo en lecture/écriture. Les enregistrements de paiement sandbox sont isolés, mais utilisent toujours le service Licentivo configuré et peuvent créer de véritables licences et enregistrements d’appareil de test. Utilisez un produit, une politique et des clients réservés aux tests.
3. Publiez un forfait sandbox puis utilisez **Intégration d’application** pour exporter `launch-config.json` et le fichier `product.json` validé dans `.local/acceptance/`.
4. Installez localement uniquement le paquet Python Launch examiné : `python -m pip install ./sdk/python`, ou installez son fichier wheel. Son implémentation privée du SDK est incluse.
5. Utilisez une fonctionnalité de test non facturée à l’usage, telle que `export`. `--activate` démarre le SDK officiel, appelle `refresh_online()` de façon synchrone, exige un état actif en ligne et invoque son API d’opération protégée. Une autorisation hors ligne en cache ne suffit pas pour réussir cette sonde ; celle-ci ne teste pas la facturation à l’usage.

La saisie des identifiants se fait sans affichage. L’automatisation peut fournir `LAUNCH_ACCEPTANCE_EMAIL` et `LAUNCH_ACCEPTANCE_PASSWORD` dans l’environnement privé du processus. Ne placez aucun mot de passe dans les arguments de commande, rapports, captures d’écran ou fichiers suivis. L’outil révoque sa session de bureau temporaire après chaque sonde authentifiée, mais ne désactive pas les appareils à la fermeture normale.

```powershell
python scripts/acceptance.py preflight --config .local/acceptance/launch-config.json --report .local/acceptance/01-preflight.json
python scripts/acceptance.py verify --config .local/acceptance/launch-config.json --expect not_purchased --report .local/acceptance/02-no-purchase.json
```

L’outil refuse les configurations de production, HTTP hors boucle locale, les redirections transportant des identifiants, les produits différents et les configurations publiques contenant des secrets d’exécution. Avant toute requête, il rejette les assertions d’activation ou de commande hors de `verify`, ainsi que les options de création de paiement hors de `checkout`. Les rapports existants ne sont jamais écrasés. Les rapports contiennent uniquement les preuves autorisées, sans réponses brutes, jetons d’accès ni clés de licence. L’absence de serveur ou de SDK provoque l’échec de la sonde, pas une réussite artificielle.

Les sondes locales du marchand utilisent `scope: local_sandbox_probe` et `licensing_scope: not_called`. `verify --activate` contacte le service officiel externe de licences, même lorsque le marchand s’exécute sur localhost ; cette combinaison est enregistrée comme `local_merchant_external_licensing_probe`, avec `licensing_scope: official_external_service`.

## Premier paiement et activation

Créez un paiement de test sur le site du marchand, ou créez-en un avec un UUID d’opération stable :

```powershell
$operation = [guid]::NewGuid().ToString()
python scripts/acceptance.py checkout --config .local/acceptance/launch-config.json --provider stripe --plan-version-id PLAN_VERSION_UUID --operation-id $operation --report .local/acceptance/03-checkout.json
```

Remplacez le fournisseur et la version du forfait par votre forfait sandbox publié. Conservez le même UUID d’opération lorsque vous réessayez une création de paiement dont le résultat est incertain. L’outil affiche l’ID de commande. Terminez cette commande appartenant au compte depuis l’espace client du marchand, via le paiement sandbox officiel du fournisseur. La sonde ne simule volontairement pas les interactions avec l’interface du fournisseur.

Après la confirmation du paiement par le fournisseur et la réception du webhook :

```powershell
python scripts/acceptance.py verify --config .local/acceptance/launch-config.json --order-id ORDER_UUID --expect-order paid --expect active --activate --product-config .local/acceptance/product.json --feature export --report .local/acceptance/04-activation.json
```

Cette vérification contrôle le compte authentifié, la commande sandbox lui appartenant, le droit d’accès, la correspondance entre identifiants et produit ainsi qu’une véritable opération protégée du SDK officiel. Une autorisation en attente est réessayée au maximum cinq fois dans une fenêtre bornée (30 secondes par défaut, 120 au maximum), en respectant `Retry-After`. Un échec d’autorisation inattendu est consigné sans exposer le texte brut d’erreur du SDK.

## Matrice de validation du cycle de vie

Pour chaque couple langage/système publié, conservez un relevé daté indiquant la révision source, les versions Launch/client/SDK, l’environnement du fournisseur, un libellé client anonymisé, les ID de commande, le résultat attendu, le résultat observé et le nom du rapport concerné. Marquez les lignes non exécutées **non exécutées**. Ne déclarez pas toute la matrice réussie à partir de la seule sonde du premier paiement.

| Scénario | Procédure | Preuves requises |
| --- | --- | --- |
| Inscription / vérification | Inscrivez-vous sans acheter ; répétez avec la vérification activée puis désactivée | La vérification désactivée ne bloque pas ; lorsqu’elle est activée, `EMAIL_VERIFICATION_REQUIRED` est renvoyé jusqu’à sa réalisation |
| Aucun achat | Exécutez `verify --expect not_purchased` | Identifiants refusés ; aucune opération protégée ne s’exécute |
| Premier achat | Terminez le paiement sandbox puis exécutez la sonde d’activation | Le fournisseur confirme le paiement ; un droit payé, une licence synchronisée et une opération SDK réussie |
| Redémarrage | Fermez l’exemple du langage choisi avec la connexion mémorisée, démarrez un nouveau processus et restaurez | Aucune demande de mot de passe ; même cache de compte/produit et autorisation signée valide |
| Démarrage hors ligne | Après une activation mémorisée réussie, désactivez le réseau du processus ou de la machine de test puis redémarrez | L’autorisation signée en cache permet uniquement les opérations autorisées par la politique ; une politique sans mode hors ligne ou à postes flottants refuse le démarrage |
| Expiration hors ligne / recul de l’horloge | Utilisez une politique de test de courte durée et une machine de test jetable | Le SDK rejette l’état expiré ou l’horloge reculée ; le rappel de fonctionnalité ne s’exécute pas |
| Renouvellement / mise à niveau | Achetez un renouvellement ou une mise à niveau sur devis dans la boutique sandbox | Commande et couverture correctes ; nouvelle validité et nouvelles fonctionnalités visibles après synchronisation et actualisation du SDK |
| Rembourser | Demandez et approuvez un remboursement sandbox intégral ; attendez la confirmation du fournisseur | Le remboursement du fournisseur et la couverture locale concordent ; `verify --expect suspended` ou `--expect expired` selon le cas ; les autres couvertures payées restent utilisables |
| Déconnexion / changement de compte | Déconnectez A, connectez B sans achat ; redémarrez et observez le comportement | La session et le cache enregistrés de A sont supprimés ; B ne peut utiliser ni la licence, ni les appareils, ni les fonctionnalités de A |
| Isolation produit / environnement | Utilisez un autre produit et basculez séparément entre les configurations sandbox/live | Les identifiants et caches ne traversent pas les périmètres d’identité ; la sonde externe refuse elle-même la production |
| Quota d’appareils atteint / libération | Activez le nombre maximal d’appareils de test distincts autorisé par la politique ; essayez d’en ajouter un, puis libérez-en un explicitement | Le SDK refuse l’appareil excédentaire et autorise son remplacement après confirmation de la libération ; une fermeture ordinaire ne consomme pas le quota de libération |
| Récupération | Redémarrez Launch pendant une émission en attente et rejouez un webhook sandbox signé | Une seule couverture de commande/licence, rapprochement final ; aucune création de paiement ni facturation en double |

Les effets d’un remboursement ou d’une suspension sur une autorisation hors ligne déjà émise restent limités par la politique hors ligne signée du SDK officiel. Aucune révocation immédiate pendant une déconnexion n’est garantie. Une longue panne Launch à l’expiration du contrat peut retarder la suspension en amont ; voir [les limites du contrat](/fr/launch-documents/licentivo-contract/).

## Achèvement et preuves conservées

Chaque rapport de sonde définit volontairement `acceptance_complete: false` : il consigne uniquement les vérifications réellement exécutées lors de cet appel. Examinez la matrice et les enregistrements du fournisseur avant d’accepter une version. Configurez ultérieurement les services externes puis reprenez les commandes ci-dessus ; ne remplacez pas les résultats manquants par un indicateur de réussite et n’activez pas les ventes en production sur la seule base des tests locaux.
