# UNITY - Adapty Documentation (Full Content) This file contains the complete content of all documentation pages for this platform. Locale: fr Generated on: 2026-08-11T20:58:32.445Z Total files: 52 --- # File: unity-sdk-overview --- --- title: "Vue d'ensemble du SDK Unity" description: "Découvrez le SDK Adapty pour Unity et ses principales fonctionnalités." --- [![Release](https://img.shields.io/github/v/release/adaptyteam/AdaptySDK-Unity.svg?style=flat&logo=unity)](https://github.com/adaptyteam/AdaptySDK-Unity/releases) Bienvenue ! Nous sommes là pour simplifier vos achats intégrés 🚀 Nous avons conçu le SDK Unity Adapty pour vous libérer des tracas des achats intégrés, afin que vous puissiez vous concentrer sur ce que vous faites de mieux : créer des jeux extraordinaires. Voici ce que nous gérons pour vous : - Gestion des achats, validation des reçus et gestion des abonnements prêts à l'emploi - Créez et testez des paywalls sans mettre à jour l'application - Obtenez des analyses d'achats détaillées sans configuration - cohortes, LTV, churn et analyse de tunnel inclus - Maintenez le statut d'abonnement de l'utilisateur toujours à jour entre les sessions et les appareils - Intégrez votre application à des services d'attribution marketing et d'analytique en une seule ligne de code :::note Avant de vous plonger dans le code, vous devrez intégrer Adapty avec App Store Connect et Google Play Console, puis configurer des produits dans le tableau de bord. Consultez notre [guide de démarrage rapide](quickstart) pour tout configurer d'abord. ::: ## Pour commencer \{#get-started\} For a fully automated integration, use the [adapty-sdk-integration skill](https://github.com/adaptyteam/adapty-sdk-integration-skill): it runs the whole integration from your AI coding tool in one command. Voici ce que nous allons couvrir dans ce guide d'intégration : 1. [Installer et configurer le SDK](sdk-installation-unity) : Ajoutez le SDK en tant que dépendance à votre projet et activez-le dans le code. 2. [Activer les achats via les flows](unity-quickstart-paywalls) : Configurez le flow d'achat pour que les utilisateurs puissent acheter des produits. Pour créer votre propre interface, consultez plutôt [Implémenter les paywalls manuellement](unity-quickstart-manual). 3. [Vérifier le statut de l'abonnement](unity-check-subscription-status) : Vérifiez automatiquement l'état de l'abonnement de l'utilisateur et contrôlez son accès au contenu payant. 4. [Identifier les utilisateurs (facultatif)](unity-quickstart-identify) : Associez les utilisateurs à leurs profils Adapty pour garantir que leurs données sont enregistrées de manière cohérente sur tous leurs appareils. ### Voir en action \{#see-it-in-action\} Envie de voir comment tout s'assemble ? On vous a préparé ça : - **Exemple d'application** : Consultez notre [exemple complet](https://github.com/adaptyteam/AdaptySDK-Unity/tree/main/Assets) qui illustre la configuration complète ## Concepts clés \{#main-concepts\} Avant de plonger dans le code, familiarisons-nous avec les concepts clés qui font fonctionner Adapty. L'avantage de l'approche Adapty, c'est que seuls les placements sont codés en dur dans votre app. Tout le reste – produits, designs de paywall, tarifs et offres – peut être géré de manière flexible depuis l'Adapty Dashboard, sans mise à jour de l'app : 1. [**Produit**](product) - Tout ce qui est disponible à l'achat dans votre app – abonnement, produit consommable ou accès à vie. 2. **Flow ou paywall** - Produits regroupés avec une configuration, attachés à un placement. Deux options : - **[Flow](adapty-flow-builder)** - Interface visuelle no-code construite dans le Flow Builder. Adapty génère l'interface et gère l'achat pour vous. - **[Paywall](paywalls)** - Pas de configuration visuelle ; vous construisez l'interface dans votre propre code et appelez `MakePurchase` vous-même. Voir [Implémenter les paywalls manuellement](unity-quickstart-manual). Dans le code du SDK, les deux sont récupérés via la même méthode `GetFlow`. 3. [**Placement**](placements) - Un point stratégique dans le parcours utilisateur où vous souhaitez afficher un flow ou un paywall. Les placements représentent le « où » et le « quand » de votre stratégie de monétisation. Voici quelques placements courants : - `main` - Votre emplacement principal de paywall - `onboarding` - Affiché pendant le flow d'onboarding - `settings` - Accessible depuis les paramètres de votre application Commencez par les basiques comme `main` ou `onboarding` pour votre première intégration, puis [réfléchissez aux autres endroits de votre application où les utilisateurs pourraient être prêts à acheter](choose-meaningful-placements). 4. [**Profil**](profiles-crm) - Lorsque les utilisateurs achètent un produit, un **niveau d'accès** est attribué à leur profil, ce qui vous permet de définir l'accès aux fonctionnalités payantes. --- # File: sdk-installation-unity --- --- title: "Installer et configurer le SDK Unity" description: "Guide étape par étape pour installer le SDK Adapty sur Unity pour les applications basées sur des abonnements." --- Le SDK Adapty comprend deux modules essentiels pour une intégration fluide dans votre application Unity : - **Core Adapty** : ce SDK de base est nécessaire au bon fonctionnement d'Adapty dans votre application. - **AdaptyUI** : ce module est requis si vous utilisez le [Paywall Builder d'Adapty](adapty-paywall-builder), un outil no-code convivial pour créer facilement des paywalls multiplateformes. :::tip Vous voulez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez notre [application exemple](https://github.com/adaptyteam/AdaptySDK-Unity/tree/main/Assets), qui illustre la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. ::: ## Prérequis \{#requirements\} Le SDK Adapty est compatible avec iOS 13.0+, mais nécessite iOS 15.0+ pour utiliser les paywalls créés dans le Paywall Builder. Le SDK Adapty 4.0 (bêta) — qui ajoute la prise en charge du [Flow Builder](adapty-flow-builder) — exige **iOS 15.0+** pour l'ensemble de l'application : un validateur de build dans l'Unity Editor bloque la compilation iOS si la cible de déploiement est inférieure. :::info Adapty est compatible avec Google Play Billing Library jusqu'à la version 8.x. Par défaut, Adapty utilise la version 7.0.0 de Google Play Billing Library. Pour utiliser une version plus récente, [remplacez la dépendance Billing](https://developer.android.com/google/play/billing/integrate#dependency) dans votre build Android. ::: :::info L'installation du SDK correspond à l'étape 5 de la configuration d'Adapty. Avant que les achats fonctionnent dans votre app, vous devez également connecter votre app aux stores, puis créer des produits, un paywall et un placement dans l'Adapty Dashboard. Le [guide de démarrage rapide](quickstart) décrit toutes les étapes requises. ::: ## Installer le SDK Adapty \{#install-adapty-sdk\} [![Release](https://img.shields.io/github/v/release/adaptyteam/AdaptySDK-Unity.svg?style=flat&logo=unity)](https://github.com/adaptyteam/AdaptySDK-Unity/releases) Choisissez votre méthode d'installation préférée : Installez le SDK Adapty via Unity Package Manager en utilisant une URL Git : 1. Dans Unity, ouvrez **Window → Package Manager**. 2. Cliquez sur **+** en haut à gauche, puis sélectionnez **Add package from git URL...**. 3. Saisissez l'URL suivante et cliquez sur **Add** : ``` https://github.com/adaptyteam/AdaptySDK-Unity.git?path=/Packages/com.adapty.unity-sdk ``` Pour plus de détails, consultez le guide Unity sur [l'installation d'un package UPM depuis une URL Git](https://docs.unity3d.com/Manual/upm-ui-giturl.html). Téléchargez le [`adapty-unity-plugin-*.unitypackage`](https://github.com/adaptyteam/AdaptySDK-Unity/tree/main/Releases) depuis GitHub et importez-le dans votre projet. Après avoir installé le SDK, effectuez les étapes suivantes : 1. Installez le [plugin External Dependency Manager (EDM)](https://github.com/googlesamples/unity-jar-resolver#getting-started). Le SDK Adapty l'utilise pour gérer les dépendances iOS et les dépendances gradle Android. 2. Après avoir installé EDM, vous devrez peut-être invoquer le gestionnaire de dépendances : `Assets -> External Dependency Manager -> Android Resolver -> Force Resolve` et `Assets -> External Dependency Manager -> iOS Resolver -> Install Cocoapods` 3. Lors de la compilation de votre projet Unity pour iOS, vous obtiendrez un fichier `Unity-iPhone.xcworkspace`, que vous devez ouvrir à la place de `Unity-iPhone.xcodeproj`, sinon les dépendances Cocoapods ne seront pas utilisées. ### Adapty SDK 4.0 (bêta) SDK 4.0 — qui ajoute la prise en charge du [Flow Builder](adapty-flow-builder) — est une version préliminaire. Pour l'installer via le Unity Package Manager, ajoutez le tag bêta à l'URL Git : ``` https://github.com/adaptyteam/AdaptySDK-Unity.git?path=/Packages/com.adapty.unity-sdk#4.0.0-beta.1 ``` Si vous installez via le package Unity, téléchargez `adapty-unity-plugin-4.0.0-beta.1.unitypackage` depuis la [version 4.0.0-beta.1](https://github.com/adaptyteam/AdaptySDK-Unity/releases/tag/4.0.0-beta.1). Deux modifications de configuration s'accompagnent de la v4 — le SDK natif iOS d'Adapty est déclaré en tant que package Swift distant et ne s'installe plus via CocoaPods : - Mettez à jour l'External Dependency Manager vers la version **1.2.188 ou ultérieure** — les versions antérieures ne prennent pas en charge les dépendances Swift Package Manager. C'est la version que le SDK 4.0 déclare comme dépendance pair, donc Unity vous avertit si votre projet en possède une plus ancienne. - Les étapes CocoaPods ci-dessus (`iOS Resolver -> Install Cocoapods`, ouverture de `Unity-iPhone.xcworkspace`) s'appliquent uniquement au SDK 3.x. Avec le SDK 4.0, EDM ajoute automatiquement le package Swift au projet Xcode généré. - Définissez la cible de déploiement iOS à **15.0 ou ultérieure**. Un validateur de build dans l'éditeur Unity bloque sinon le build iOS. Consultez le [guide de migration](migration-to-unity-sdk-v4) pour la liste complète des changements du SDK 4.0. ## Activer le module Adapty du SDK \{#activate-adapty-module-of-adapty-sdk\} Activez le SDK dans le code de votre application. :::note Le SDK n'a besoin d'être activé qu'une seule fois dans votre application. ::: Pour obtenir votre **Public SDK Key** : 1. Accédez à l'Adapty Dashboard et naviguez vers [**App settings → General**](https://app.adapty.io/settings/general). 2. Dans la section **Api keys**, copiez la **Public SDK Key** (et NON la Secret Key). 3. Remplacez `"YOUR_PUBLIC_SDK_KEY"` dans le code. Ou obtenez-la de façon programmatique via l'[Adapty CLI](developer-cli) : ``` npm install -g adapty adapty auth login adapty apps list ``` Ou, directement : ``` npx adapty auth login adapty apps list ``` - Assurez-vous d'utiliser la **Public SDK key** pour l'initialisation d'Adapty — la **Secret key** ne doit être utilisée que pour l'[API côté serveur](getting-started-with-server-side-api). - Les **SDK keys** sont propres à chaque application, donc si vous avez plusieurs applications, veillez à choisir la bonne. ```csharp showLineNumbers title="C#" using UnityEngine; using AdaptySDK; public class AdaptyListener : MonoBehaviour, AdaptyEventListener { void Start() { DontDestroyOnLoad(this.gameObject); Adapty.SetEventListener(this); var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY"); Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); } public void OnLoadLatestProfile(AdaptyProfile profile) { } public void OnInstallationDetailsSuccess(AdaptyInstallationDetails details) { } public void OnInstallationDetailsFail(AdaptyError error) { } } ``` :::note Dans le SDK 4.0, les interfaces de listener suivent la convention de préfixe I du C# : implémentez `IAdaptyEventListener` plutôt que `AdaptyEventListener`. Les méthodes restent inchangées. Consultez le [guide de migration](migration-to-unity-sdk-v4). ::: :::important Attendez le callback de complétion d'`Activate` avant d'appeler toute autre méthode du SDK Adapty. Consultez [l'ordre d'appel dans le SDK Unity](unity-sdk-call-order) pour la séquence complète. ::: ## Configurer l'écoute des événements \{#set-up-event-listening\} Créez un script pour écouter les événements Adapty. Nommez-le `AdaptyListener` dans votre scène. Nous recommandons d'utiliser la méthode `DontDestroyOnLoad` sur cet objet pour qu'il persiste pendant toute la durée de vie de l'application. Adapty utilise le namespace `AdaptySDK`. En haut de vos fichiers de script qui utilisent le SDK Adapty, vous pouvez ajouter : ```csharp showLineNumbers title="C#" using AdaptySDK; ``` Abonnez-vous aux événements Adapty : ```csharp showLineNumbers title="C#" using UnityEngine; using AdaptySDK; public class AdaptyListener : MonoBehaviour, AdaptyEventListener { public void OnLoadLatestProfile(AdaptyProfile profile) { // handle updated profile data } public void OnInstallationDetailsSuccess(AdaptyInstallationDetails details) { } public void OnInstallationDetailsFail(AdaptyError error) { } } ``` Nous recommandons d'ajuster l'ordre d'exécution des scripts pour placer l'AdaptyListener avant Default Time. Cela garantit qu'Adapty s'initialise le plus tôt possible. Configurez maintenant les paywalls dans votre application : - Si vous utilisez le [Paywall Builder d'Adapty](adapty-paywall-builder), commencez par [activer le module AdaptyUI](#activate-adaptyui-module-of-adapty-sdk) ci-dessous, puis suivez le [guide de démarrage rapide du Paywall Builder](unity-quickstart-paywalls). - Si vous créez votre propre interface de paywall, consultez le [guide de démarrage rapide pour les paywalls personnalisés](unity-quickstart-manual). ## Activer le module AdaptyUI du SDK Adapty \{#activate-adaptyui-module-of-adapty-sdk\} Si vous prévoyez d'utiliser le [Paywall Builder](adapty-paywall-builder) et avez installé le module AdaptyUI, vous devez activer AdaptyUI. Vous pouvez l'activer lors de la configuration : ```csharp showLineNumbers title="C#" var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") .SetActivateUI(true); ``` ## Configuration optionnelle \{#optional-setup\} ### Journalisation \{#logging\} #### Configurer le système de journalisation \{#set-up-the-logging-system\} Adapty enregistre les erreurs et d'autres informations importantes pour vous aider à comprendre ce qui se passe. Les niveaux suivants sont disponibles : | Level | Description | | ---------- | ------------------------------------------------------------ | | `error` | Seules les erreurs seront journalisées | | `warn` | Les erreurs et les messages du SDK qui ne causent pas d'erreurs critiques, mais méritent attention, seront journalisés | | `info` | Les erreurs, avertissements et divers messages d'information seront journalisés | | `verbose` | Toute information supplémentaire pouvant être utile lors du débogage, comme les appels de fonctions, les requêtes API, etc., sera journalisée | Vous pouvez définir le niveau de log dans votre application lors de la configuration d'Adapty : ```csharp showLineNumbers title="C#" // 'verbose' is recommended for development and the first production release var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY"); builder.LogLevel = AdaptyLogLevel.Verbose; ``` Vous pouvez également modifier le niveau de log à l'exécution : ```csharp showLineNumbers title="C#" Adapty.SetLogLevel(AdaptyLogLevel.Verbose, (error) => { // handle result }); ``` ### Politiques de données \{#data-policies\} Adapty ne stocke pas les données personnelles de vos utilisateurs sauf si vous les envoyez explicitement, mais vous pouvez mettre en place des politiques de sécurité des données supplémentaires pour vous conformer aux directives du store ou des pays. #### Désactiver la collecte et le partage des adresses IP \{#disable-ip-address-collection-and-sharing\} Lors de l'activation du module Adapty, définissez `SetIPAddressCollectionDisabled` sur `true` pour désactiver la collecte et le partage des adresses IP des utilisateurs. La valeur par défaut est `false`. Utilisez ce paramètre pour renforcer la confidentialité des utilisateurs, vous conformer aux réglementations régionales de protection des données (comme le RGPD ou le CCPA), ou réduire la collecte de données inutiles lorsque les fonctionnalités basées sur l'adresse IP ne sont pas nécessaires pour votre application. ```csharp showLineNumbers title="C#" var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") .SetIPAddressCollectionDisabled(true); ``` #### Désactiver la collecte et le partage de l'identifiant publicitaire \{#disable-advertising-id-collection-and-sharing\} Lors de l'activation du module Adapty, définissez `SetAppleIDFACollectionDisabled` et/ou `SetGoogleAdvertisingIdCollectionDisabled` à `true` pour désactiver la collecte des identifiants publicitaires. La valeur par défaut est `false`. Utilisez ce paramètre pour respecter les politiques de l'App Store/Google Play, éviter de déclencher l'invite App Tracking Transparency, ou si votre application n'a pas besoin d'attribution publicitaire ni d'analytiques basées sur les identifiants publicitaires. ```csharp showLineNumbers title="C#" var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") .SetAppleIDFACollectionDisabled(true) .SetGoogleAdvertisingIdCollectionDisabled(true); ``` #### Configurer le cache média pour AdaptyUI \{#set-up-media-cache-configuration-for-adaptyui\} Par défaut, AdaptyUI met en cache les médias (images et vidéos) pour améliorer les performances et réduire la consommation réseau. Vous pouvez personnaliser ces paramètres en fournissant une configuration personnalisée. Utilisez `SetAdaptyUIMediaCache` pour remplacer les paramètres de cache par défaut : ```csharp showLineNumbers title="C#" var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") .SetAdaptyUIMediaCache( 100 * 1024 * 1024, // MemoryStorageTotalCostLimit 100MB null, // MemoryStorageCountLimit 100 * 1024 * 1024 // DiskStorageSizeLimit 100MB ); ``` Paramètres : | Paramètre | Requis | Description | |-----------------------------|----------|-----------------------------------------------------------------------------------------------| | memoryStorageTotalCostLimit | optionnel | Taille totale du cache en mémoire en octets. Valeur par défaut spécifique à la plateforme. | | memoryStorageCountLimit | optionnel | Nombre maximal d'éléments dans le stockage en mémoire. Valeur par défaut spécifique à la plateforme. | | diskStorageSizeLimit | optionnel | Taille limite des fichiers sur disque en octets. Valeur par défaut spécifique à la plateforme. | ### Activer les niveaux d'accès locaux (Android) \{#enable-local-access-levels-android\} Par défaut, les [niveaux d'accès locaux](local-access-levels) sont activés sur iOS et désactivés sur Android. Pour les activer également sur Android, définissez `SetGoogleLocalAccessLevelAllowed` sur `true` : ```csharp showLineNumbers title="C#" var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") .SetGoogleLocalAccessLevelAllowed(true); ``` ### Effacer les données lors d'une restauration de sauvegarde \{#clear-data-on-backup-restore\} Lorsque `SetAppleClearDataOnBackup` est défini sur `true`, le SDK détecte quand l'application est restaurée depuis une sauvegarde iCloud et supprime toutes les données SDK stockées localement, notamment les informations de profil en cache, les détails des produits et les paywalls. Le SDK s'initialise ensuite dans un état propre. La valeur par défaut est `false`. :::note Seul le cache local du SDK est supprimé. L'historique des transactions avec Apple et les données utilisateur sur les serveurs Adapty restent inchangés. ::: ```csharp showLineNumbers title="C#" var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") .SetAppleClearDataOnBackup(true); ``` ## Dépannage \{#troubleshooting\} #### Règles de sauvegarde Android (configuration Auto Backup) \{#android-backup-rules-auto-backup-configuration\} Certains SDKs (dont Adapty) embarquent leur propre configuration Android Auto Backup. Si vous utilisez plusieurs SDKs qui définissent des règles de sauvegarde, la fusion du manifeste Android peut échouer avec une erreur mentionnant `android:fullBackupContent`, `android:dataExtractionRules` ou `android:allowBackup`. Symptômes typiques : `Manifest merger failed: Attribute application@dataExtractionRules value=(@xml/your_data_extraction_rules) is also present at [com.other.sdk:library:1.0.0] value=(@xml/other_sdk_data_extraction_rules)` :::note Ces modifications doivent être effectuées dans votre répertoire de la plateforme Android (généralement situé dans le dossier `android/` de votre projet). ::: Pour résoudre ce problème, vous devez : - Indiquer au gestionnaire de fusion de manifeste d'utiliser les valeurs de votre application pour les attributs liés à la sauvegarde. - Créer des fichiers de règles de sauvegarde qui fusionnent les règles d'Adapty avec celles des autres SDKs. #### 1. Ajoutez l'espace de noms `tools` à votre manifeste \{#1-add-the-tools-namespace-to-your-manifest\} Dans votre fichier `AndroidManifest.xml`, assurez-vous que la balise racine `` inclut tools : ```xml ... ``` #### 2. Remplacez les attributs de sauvegarde dans `` \{#2-override-backup-attributes-in-application\} Dans le même fichier `AndroidManifest.xml`, mettez à jour la balise `` afin que votre application fournisse les valeurs finales et indique au gestionnaire de fusion de remplacer les valeurs des bibliothèques : ```xml ... ``` Si un SDK définit également `android:allowBackup`, incluez-le dans `tools:replace` : ```xml tools:replace="android:allowBackup,android:fullBackupContent,android:dataExtractionRules" ``` #### 3. Créez les fichiers de règles de sauvegarde fusionnés \{#3-create-merged-backup-rules-files\} Créez des fichiers XML dans le répertoire `res/xml/` de votre projet Android, en combinant les règles d'Adapty avec celles des autres SDKs. Android utilise des formats de règles de sauvegarde différents selon la version de l'OS, donc créer les deux fichiers garantit la compatibilité avec toutes les versions d'Android prises en charge par votre application. :::note Les exemples ci-dessous utilisent AppsFlyer comme exemple de SDK tiers. Remplacez ou ajoutez des règles pour tout autre SDK que vous utilisez dans votre application. ::: **Pour Android 12 et supérieur** (utilise le nouveau format de règles d'extraction de données) : ```xml title="sample_data_extraction_rules.xml" ``` **Pour Android 11 et inférieur** (utilise l'ancien format de sauvegarde complète) : ```xml title="sample_backup_rules.xml" :::important Dans Unity, appliquez ces modifications à `Assets/Plugins/Android/AndroidManifest.xml` et créez les fichiers de règles de sauvegarde dans `Assets/Plugins/Android/res/xml/`. ::: #### Les achats échouent après un retour depuis une autre application sur Android \{#purchases-fail-after-returning-from-another-app-in-android\} Si l'Activity qui démarre le flow d'achat utilise un `launchMode` non standard, Android peut la recréer ou la réutiliser incorrectement lorsque l'utilisateur revient depuis Google Play, une application bancaire ou un navigateur. Cela peut entraîner la perte du résultat d'achat ou son interprétation comme une annulation. Pour que les achats fonctionnent correctement, utilisez uniquement les modes de lancement `standard` ou `singleTop` pour l'Activity qui démarre le flow d'achat, et évitez tout autre mode. Dans votre `AndroidManifest.xml`, assurez-vous que l'Activity qui démarre le flow d'achat est configurée sur `standard` ou `singleTop` : ```xml ``` #### L'application plante lors de l'affichage d'un paywall sur Android \{#app-crashes-when-a-paywall-is-displayed-on-android\} Si votre application plante sur Android lors de l'affichage d'un paywall, il est possible que le plugin Kotlin soit absent de votre configuration Gradle. Pour l'ajouter : 1. Dans **Player Settings**, assurez-vous que les options **Custom Launcher Gradle Template** et **Custom Base Gradle Template** sont sélectionnées. 2. Ajoutez la ligne suivante à `/Assets/Plugins/Android/launcherTemplate.gradle` : ```groovy showLineNumbers apply plugin: 'com.android.application' // highlight-next-line apply plugin: 'kotlin-android' apply from: 'setupSymbols.gradle' apply from: '../shared/keepUnitySymbols.gradle' ``` 3. Ajoutez la ligne suivante dans `/Assets/Plugins/Android/baseProjectTemplate.gradle` : ```groovy showLineNumbers plugins { // If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity // See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html // See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle // To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version id 'com.android.application' version '8.3.0' apply false id 'com.android.library' version '8.3.0' apply false // highlight-next-line id 'org.jetbrains.kotlin.android' version '1.8.0' apply false **BUILD_SCRIPT_DEPS** } ``` --- # File: unity-quickstart-paywalls --- --- title: "Activer les achats avec Flow Builder dans le SDK Unity" description: "Guide de démarrage rapide pour activer les achats intégrés avec Adapty Flow Builder." --- Ce guide utilise les APIs du SDK Adapty Unity v4 (bêta). Si vous utilisez la v3, consultez le [guide de migration](migration-to-unity-sdk-v4) pour les noms de méthodes correspondants. Pour activer les achats intégrés, vous devez comprendre trois concepts clés : - [**Produits**](product) – tout ce que les utilisateurs peuvent acheter (abonnements, consommables, accès à vie) - [**Flows**](adapty-flow-builder) – séquences d'écrans qui présentent des produits aux utilisateurs, construites dans le Flow Builder sans code. Le SDK les récupère via `GetFlow`. Si vous préférez créer l'interface dans votre propre code, utilisez un paywall à la place — voir [Implémenter des paywalls manuellement](unity-quickstart-manual). - [**Placements**](placements) – où et quand vous affichez des flows dans votre application (par exemple `main`, `onboarding`, `settings`). Vous associez des flows à des placements dans le tableau de bord, puis vous les demandez par ID de placement dans votre code. Cela facilite l'exécution de tests A/B et l'affichage de flows différents selon les utilisateurs. Adapty vous propose trois façons d'activer les achats dans votre application. Choisissez celle qui correspond à vos besoins : | Implémentation | Complexité | Quand l'utiliser | |---|---|---| | Adapty Flow Builder | ✅ Facile | Vous [créez un flow complet et prêt à l'achat dans le builder no-code](quickstart-paywalls). Adapty le rend automatiquement et gère en coulisses tout le flow d'achat, la validation des reçus et la gestion des abonnements. | | Paywalls créés manuellement | 🟡 Moyen | Vous implémentez l'interface de votre paywall dans le code de votre application, mais récupérez tout de même l'objet flow depuis Adapty pour conserver une flexibilité dans les offres de produits. Consultez le [guide](unity-quickstart-manual). | | Mode Observer | 🔴 Difficile | Vous disposez déjà de votre propre infrastructure de gestion des achats et souhaitez continuer à l'utiliser. Notez que le mode Observer présente certaines limitations dans Adapty. Consultez l'[article](observer-vs-full-mode). | :::important **Les étapes ci-dessous montrent comment implémenter un flow créé dans l'Adapty Flow Builder.** Si vous préférez construire l'UI du paywall vous-même, consultez [Implémenter les paywalls manuellement](unity-quickstart-manual). ::: Pour afficher un flow créé dans l'Adapty Flow Builder, dans le code de votre application, il vous suffit de : 1. **Récupérer le flow** : Obtenez-le depuis Adapty. 2. **L'afficher et Adapty gérera les achats pour vous** : Affichez la vue dans votre application. 3. **Gérer les actions des boutons** : Associez les interactions utilisateur aux réponses de votre application. Par exemple, ouvrir des liens ou fermer le flow lorsque les utilisateurs cliquent sur des boutons. ## Avant de commencer \{#before-you-start\} Avant de commencer, effectuez ces étapes : 1. Connectez votre application à l'[App Store](initial_ios) et/ou à [Google Play](initial-android) dans Adapty Dashboard. 2. [Créez vos produits](create-product) dans Adapty. 3. [Créez un flow et ajoutez-y des produits](create-paywall). 4. [Créez un placement et ajoutez votre flow](create-placement). 5. [Installez et activez le SDK Adapty](sdk-installation-unity) dans le code de votre application. :::tip Le moyen le plus rapide d'effectuer ces étapes est de suivre le [guide de démarrage rapide](quickstart) ou de créer des flows et des placements à l'aide du [CLI développeur](developer-cli-quickstart). ::: ## 1. Récupérer le flow \{#1-get-the-flow\} Vos flows sont associés à des placements configurés dans le tableau de bord. Les placements vous permettent d'afficher des flows différents selon les audiences ou de lancer des [tests A/B](ab-tests). Pour récupérer un flow créé dans l'Adapty Flow Builder, vous devez : 1. Récupérer l'objet `flow` par l'ID du [placement](placements) en utilisant la méthode `GetFlow`. 2. Créer la vue du flow à l'aide de la méthode `CreateFlowView`. La vue contient les éléments d'interface et le style nécessaires à l'affichage du flow. Si le flow n'a pas de vue configurée, `CreateFlowView` retourne une erreur — gérez-la dans le callback. :::important Pour afficher la vue, vous devez activer le bouton **Show on device** dans le Flow Builder. Sinon, `CreateFlowView` retournera une erreur et le flow ne s'affichera pas. ::: ```csharp showLineNumbers Adapty.GetFlow("YOUR_PLACEMENT_ID", (flow, error) => { if (error != null) { // handle the error return; } // Create the flow view AdaptyUI.CreateFlowView(flow, (view, error) => { if (error != null) { // the flow has no view configured, or view creation failed return; } // view - the flow view ready to be presented }); }); ``` :::info Ce démarrage rapide fournit la configuration minimale requise pour afficher un flow. Pour les détails de configuration avancée, consultez notre [guide sur la récupération des flows](unity-get-pb-paywalls). ::: ## 2. Afficher le flow \{#2-display-the-flow\} Maintenant que vous avez la vue du flow, il suffit d'ajouter quelques lignes pour l'afficher. Pour afficher le flow, utilisez la méthode `view.Present()` sur le `view` créé par la méthode `CreateFlowView`. Chaque `view` ne peut être utilisé qu'une seule fois : après l'avoir fermé, appelez à nouveau `CreateFlowView` pour afficher le flow une nouvelle fois. ```csharp showLineNumbers title="Unity" view.Present((error) => { // handle the error }); ``` :::info Pour plus de détails sur la façon d'afficher un flow, consultez notre [guide](unity-present-paywalls). ::: ## 3. Gérer les actions des boutons \{#handle-button-actions\} Lorsque les utilisateurs cliquent sur des boutons dans le flow, le SDK Unity gère automatiquement les achats et la restauration. Cependant, d'autres boutons ont des identifiants personnalisés ou prédéfinis et nécessitent une gestion des actions dans votre code. Par exemple, votre flow dispose probablement d'un bouton de fermeture et d'URLs à ouvrir (par exemple, les conditions d'utilisation et la politique de confidentialité). Pour gérer ces actions, votre classe doit implémenter l'interface `IAdaptyFlowsEventsListener` et s'enregistrer en tant qu'écouteur. Notez que le flow reste ouvert après un achat réussi. Si vous souhaitez le fermer une fois l'achat terminé, fermez la vue dans le callback `FlowViewDidFinishPurchase`. :::tip Consultez nos guides sur la gestion des [actions](unity-handle-paywall-actions) et des [événements](unity-handling-events) de bouton. ::: ```csharp showLineNumbers title="Unity" public class YourClass : MonoBehaviour, IAdaptyFlowsEventsListener { void Start() { // Register this class as the flows events listener Adapty.SetFlowsEventsListener(this); } // IAdaptyFlowsEventsListener method - handles button actions public void FlowViewDidPerformAction( AdaptyUIFlowView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Close: view.Dismiss(null); break; case AdaptyUIUserActionType.OpenUrl: AdaptyUI.OpenUrl(action.Value, AdaptyWebPresentation.ExternalBrowser, null); break; default: break; } } // IAdaptyFlowsEventsListener method - dismiss the flow after a purchase public void FlowViewDidFinishPurchase( AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyPurchaseResult purchasedResult ) { if (purchasedResult.Type != AdaptyPurchaseResultType.UserCancelled) { view.Dismiss(null); } } } ``` ## Prochaines étapes :::tip Des questions ou des problèmes ? Consultez notre [forum d'assistance](https://adapty.featurebase.app/) où vous trouverez des réponses aux questions fréquentes ou pourrez poser les vôtres. Notre équipe et notre communauté sont là pour vous aider ! ::: Votre flow est prêt à être affiché dans l'application. Testez vos achats dans le [sandbox App Store](test-purchases-in-sandbox) ou sur [Google Play Store](testing-on-android) pour vous assurer de pouvoir effectuer un achat test depuis le flow. Ensuite, vous devez [vérifier le niveau d'accès des utilisateurs](unity-check-subscription-status) pour vous assurer d'afficher un flow ou de donner accès aux fonctionnalités payantes aux bons utilisateurs. ## Exemple complet \{#full-example\} Voici comment intégrer toutes ces étapes dans votre application. ```csharp showLineNumbers using System; using System.Collections.Generic; using UnityEngine; using AdaptySDK; public class FlowManager : MonoBehaviour, IAdaptyFlowsEventsListener { [SerializeField] private string placementId = "YOUR_PLACEMENT_ID"; void Start() { // Register for flow events Adapty.SetFlowsEventsListener(this); GetAndDisplayFlow(); } private void GetAndDisplayFlow() { Adapty.GetFlow(placementId, (flow, error) => { if (error != null) { Debug.LogError("Error getting flow: " + error.Message); return; } CreateAndPresentFlowView(flow); }); } private void CreateAndPresentFlowView(AdaptyFlow flow) { AdaptyUI.CreateFlowView(flow, (view, error) => { if (error != null) { // the flow has no view configured — use custom logic Debug.LogError("Error creating flow view: " + error.Message); return; } view.Present((presentError) => { if (presentError != null) { Debug.LogError("Error presenting flow: " + presentError.Message); return; } Debug.Log("Flow presented successfully"); }); }); } // IAdaptyFlowsEventsListener implementation public void FlowViewDidPerformAction( AdaptyUIFlowView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Close: Debug.Log("Close button pressed"); view.Dismiss(null); break; case AdaptyUIUserActionType.OpenUrl: AdaptyUI.OpenUrl(action.Value, AdaptyWebPresentation.ExternalBrowser, null); break; default: break; } } public void FlowViewDidFinishPurchase( AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyPurchaseResult purchasedResult ) { if (purchasedResult.Type != AdaptyPurchaseResultType.UserCancelled) { view.Dismiss(null); } } // Required interface methods (implement as needed) public void FlowViewDidAppear(AdaptyUIFlowView view) { } public void FlowViewDidDisappear(AdaptyUIFlowView view) { } public void FlowViewDidSelectProduct(AdaptyUIFlowView view, string productId) { } public void FlowViewDidStartPurchase(AdaptyUIFlowView view, AdaptyPaywallProduct product) { } public void FlowViewDidFailPurchase(AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyError error) { } public void FlowViewDidStartRestore(AdaptyUIFlowView view) { } public void FlowViewDidFinishRestore(AdaptyUIFlowView view, AdaptyProfile profile) { } public void FlowViewDidFailRestore(AdaptyUIFlowView view, AdaptyError error) { } public void FlowViewDidReceiveError(AdaptyUIFlowView view, AdaptyError error) { } public void FlowViewDidFailLoadingProducts(AdaptyUIFlowView view, AdaptyError error) { } public void FlowViewDidFinishWebPaymentNavigation(AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyError error) { } public void FlowViewDidReceiveAnalyticEvent(AdaptyUIFlowView view, string name, IDictionary @params) { } public void ShowFlow() { GetAndDisplayFlow(); } } ``` --- # File: unity-check-subscription-status --- --- title: "Vérifier le statut d'abonnement dans le SDK Unity" description: "Découvrez comment vérifier le statut d'abonnement dans votre application Unity avec Adapty." --- Pour décider si les utilisateurs peuvent accéder au contenu payant ou voir un paywall, vous devez vérifier leur [niveau d'accès](access-level) dans le profil. Cet article vous explique comment accéder à l'état du profil afin de décider ce que les utilisateurs doivent voir — qu'il s'agisse de leur afficher un paywall ou de leur accorder l'accès aux fonctionnalités payantes. ## Vérifier le statut de l'abonnement \{#get-subscription-status\} Lorsque vous souhaitez décider d'afficher un paywall ou du contenu payant à un utilisateur, vous consultez son [niveau d'accès](access-level) dans son profil. Deux options s'offrent à vous : - Appeler `GetProfile` si vous avez besoin des dernières données du profil immédiatement (par exemple au lancement de l'application) ou si vous souhaitez forcer une mise à jour. - Configurer des **mises à jour automatiques du profil** pour conserver une copie locale qui se rafraîchit automatiquement à chaque changement de statut de l'abonnement. ### Obtenir le profil \{#get-profile\} La façon la plus simple d'obtenir le statut d'abonnement est d'utiliser la méthode `GetProfile` pour accéder au profil : ```csharp showLineNumbers Adapty.GetProfile((profile, error) => { if (error != null) { // handle the error return; } // check the access }); ``` ### Écouter les mises à jour d'abonnement \{#listen-to-subscription-updates\} Pour recevoir automatiquement les mises à jour de profil dans votre application : 1. Étendez `AdaptyEventListener` et implémentez la méthode `OnLoadLatestProfile` — Adapty appellera automatiquement cette méthode chaque fois que le statut d'abonnement de l'utilisateur change. 2. Stockez les données de profil mises à jour lorsque cette méthode est appelée, afin de pouvoir les utiliser dans toute votre application sans effectuer de requêtes réseau supplémentaires. :::note Dans le SDK 4.0, les interfaces de listener suivent la convention C# avec préfixe I : implémentez `IAdaptyEventListener` au lieu de `AdaptyEventListener`. Les méthodes restent inchangées. Consultez le [guide de migration](migration-to-unity-sdk-v4). ::: ```csharp public class SubscriptionManager : MonoBehaviour, AdaptyEventListener { private AdaptyProfile currentProfile; void Start() { // Register this object as an Adapty event listener Adapty.SetEventListener(this); } // Store the profile when it updates public void OnLoadLatestProfile(AdaptyProfile profile) { currentProfile = profile; // Update UI, unlock content, etc. } public void OnInstallationDetailsSuccess(AdaptyInstallationDetails details) { } public void OnInstallationDetailsFail(AdaptyError error) { } // Use stored profile instead of calling getProfile() public bool HasAccess() { if (currentProfile?.AccessLevels != null && currentProfile.AccessLevels.ContainsKey("premium")) { return currentProfile.AccessLevels["premium"].IsActive; } return false; } } ``` :::note Adapty appelle automatiquement `OnLoadLatestProfile` au démarrage de votre application, fournissant des données d'abonnement en cache même si l'appareil est hors ligne. ::: ## Associer le profil à la logique des paywalls \{#connect-profile-with-paywall-logic\} Lorsque vous avez besoin de prendre des décisions immédiates concernant l'affichage des paywalls ou l'accès aux fonctionnalités payantes, vous pouvez consulter directement le profil de l'utilisateur. Cette approche est utile dans des scénarios comme le lancement de l'application, l'accès à des sections premium, ou avant d'afficher du contenu spécifique. ```csharp private void CheckAccessLevel() { Adapty.GetProfile((profile, error) => { if (error != null) { Debug.LogError("Error checking access level: " + error.Message); // Show paywall if access check fails return; } if (!profile.AccessLevels.TryGetValue("YOUR_ACCESS_LEVEL", out var accessLevel) || !accessLevel.IsActive) { // Show paywall if no access } }); } private void InitializePaywall() { LoadPaywall(); CheckAccessLevel(); } ``` ## Étapes suivantes \{#next-steps\} Maintenant que vous savez comment suivre le statut de l'abonnement, découvrez comment [travailler avec les profils utilisateurs](unity-quickstart-identify) pour vous assurer qu'ils peuvent accéder à ce pour quoi ils ont payé. --- # File: unity-quickstart-identify --- --- title: "Identifier les utilisateurs dans le SDK Unity" description: "Guide de démarrage rapide pour configurer Adapty pour la gestion des abonnements intégrés dans Unity." --- :::important Ce guide est fait pour vous si vous disposez de votre propre système d'authentification. Vous y apprendrez comment travailler avec les profils utilisateurs dans Adapty afin de les aligner avec votre système d'authentification existant. ::: La façon dont vous gérez les achats des utilisateurs dépend du modèle d'authentification de votre application : - Si votre application n'utilise pas d'authentification backend et ne stocke pas de données utilisateur, consultez la [section sur les utilisateurs anonymes](#anonymous-users). - Si votre application dispose (ou disposera) d'une authentification backend, consultez la [section sur les utilisateurs identifiés](#identified-users). **Concepts clés** : - Les **profils** sont les entités nécessaires au fonctionnement du SDK. Adapty les crée automatiquement. - Ils peuvent être anonymes **(sans customer user ID)** ou identifiés **(avec customer user ID)**. - Vous fournissez un **customer user ID** afin de faire le lien entre les profils Adapty et votre système d'authentification interne. Voici les différences entre les utilisateurs anonymes et identifiés : | | Utilisateurs anonymes | Utilisateurs identifiés | |------------------------------|---------------------------------------------------------------|----------------------------------------------------------------------------------------------| | **Gestion des achats** | Restauration des achats au niveau du store | Historique des achats conservé sur tous les appareils via leur customer user ID | | **Gestion des profils** | Nouveau profil à chaque réinstallation | Le même profil sur toutes les sessions et tous les appareils | | **Persistance des données** | Les données des utilisateurs anonymes sont liées à l'installation de l'application | Les données des utilisateurs identifiés persistent d'une installation à l'autre | ## Utilisateurs anonymes \{#anonymous-users\} Si vous n'avez pas d'authentification backend, **vous n'avez pas besoin de gérer l'authentification dans le code de l'application** : 1. Lorsque le SDK est activé au premier lancement de l'application, Adapty **crée un nouveau profil pour l'utilisateur**. 2. Lorsque l'utilisateur effectue un achat dans l'application, celui-ci est **associé à son profil Adapty et à son compte store**. 3. Lorsque l'utilisateur **réinstalle** l'application ou l'installe sur un **nouvel appareil**, Adapty **crée un nouveau profil anonyme lors de l'activation**. 4. Si l'utilisateur a déjà effectué des achats dans votre application, par défaut, ses achats sont automatiquement synchronisés depuis l'App Store lors de l'activation du SDK. Ainsi, avec des utilisateurs anonymes, de nouveaux profils sont créés à chaque installation, mais ce n'est pas un problème car, dans les analyses Adapty, vous pouvez [configurer ce qui sera considéré comme une nouvelle installation](general#4-installs-definition-for-analytics). Pour les utilisateurs anonymes, vous devez comptabiliser les installations par **ID d'appareils**. Dans ce cas, chaque installation de l'application sur un appareil est comptée comme une installation, y compris les réinstallations. ## Utilisateurs identifiés \{#identified-users\} Vous avez deux options pour identifier les utilisateurs dans l'application : - [**Lors de la connexion/inscription :**](#during-loginsignup) Si les utilisateurs se connectent après le démarrage de votre application, appelez `identify()` avec un customer user ID lorsqu'ils s'authentifient. - [**Lors de l'activation du SDK :**](#during-the-sdk-activation) Si vous disposez déjà d'un customer user ID stocké au lancement de l'application, envoyez-le lors de l'appel à `activate()`. :::important Par défaut, lorsqu'Adapty reçoit un achat d'un Customer User ID actuellement associé à un autre Customer User ID, le niveau d'accès est partagé, de sorte que les deux profils ont un accès payant. Vous pouvez configurer ce paramètre pour transférer l'accès payant d'un profil à l'autre ou désactiver complètement le partage. Consultez l'[article](general#6-sharing-paid-access-between-user-accounts) pour plus de détails. ::: ### Lors de la connexion/inscription \{#during-loginsignup\} Si vous identifiez les utilisateurs après le lancement de l'application (par exemple, après qu'ils se soient connectés à votre application ou inscrits), utilisez la méthode `identify` pour définir leur customer user ID. - Si vous **n'avez jamais utilisé ce customer user ID auparavant**, Adapty le liera automatiquement au profil actuel. - Si vous **avez déjà utilisé ce customer user ID pour identifier l'utilisateur**, Adapty basculera vers le profil associé à ce customer user ID. :::important Les customer user IDs doivent être uniques pour chaque utilisateur. Si vous codez en dur la valeur du paramètre, tous les utilisateurs seront considérés comme un seul. ::: Attendez le callback de complétion d'`Identify` avant d'appeler d'autres méthodes du SDK. Les appels simultanés produisent `#3006 profileWasChanged` ou atterrissent sur le profil anonyme. Consultez [Ordre des appels dans le SDK Unity](unity-sdk-call-order). ```csharp showLineNumbers Adapty.Identify("YOUR_USER_ID", (error) => { // Unique for each user if(error == null) { // successful identify } }); ``` ### Lors de l'activation du SDK \{#during-the-sdk-activation\} Si vous connaissez déjà un customer user ID lors de l'activation du SDK, vous pouvez l'envoyer dans la méthode `activate` plutôt que d'appeler `identify` séparément. Si vous connaissez un customer user ID mais ne le définissez qu'après l'activation, cela signifie que, lors de l'activation, Adapty créera un nouveau profil anonyme et ne basculera vers le profil existant qu'après l'appel à `identify`. Vous pouvez passer un customer user ID existant (que vous avez déjà utilisé auparavant) ou un nouveau. Si vous en passez un nouveau, le nouveau profil créé lors de l'activation sera automatiquement lié au customer user ID. :::note Par défaut, la création de profils anonymes n'affecte pas les tableaux de bord des analyses, car les installations sont comptées par ID d'appareils. Un ID d'appareil représente une seule installation de l'application depuis le store sur un appareil et n'est régénéré qu'après la réinstallation de l'application. Il ne dépend pas du fait qu'il s'agisse d'une première ou d'une nouvelle installation, ni de l'utilisation d'un customer user ID existant. La création d'un profil (lors de l'activation du SDK ou de la déconnexion), la connexion ou la mise à jour de l'application sans la réinstaller ne génèrent pas d'événements d'installation supplémentaires. Si vous souhaitez comptabiliser les installations par utilisateurs uniques plutôt que par appareils, accédez à **App settings** et configurez [**Installs definition for analytics**](general#4-installs-definition-for-analytics). ::: ```csharp showLineNumbers using UnityEngine; using AdaptySDK; var builder = new AdaptyConfiguration.Builder("YOUR_API_KEY") .SetCustomerUserId("YOUR_USER_ID"); // Customer user IDs must be unique for each user. If you hardcode the parameter value, all users will be considered as one. Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); ``` ### Déconnecter les utilisateurs \{#log-users-out\} Si vous avez un bouton pour déconnecter les utilisateurs, utilisez la méthode `logout`. :::important La déconnexion d'un utilisateur crée un nouveau profil anonyme pour cet utilisateur. ::: ```csharp showLineNumbers Adapty.Logout((error) => { if(error == null) { // successful logout } }); ``` :::info Pour reconnecter les utilisateurs à l'application, utilisez la méthode `identify`. ::: ### Autoriser les achats sans connexion \{#allow-purchases-without-login\} Si vos utilisateurs peuvent effectuer des achats aussi bien avant qu'après s'être connectés à votre application, vous devez vous assurer qu'ils conserveront leur accès après la connexion : 1. Lorsqu'un utilisateur déconnecté effectue un achat, Adapty le lie à son ID de profil anonyme. 2. Lorsque l'utilisateur se connecte à son compte, Adapty bascule vers son profil identifié. - S'il s'agit d'un nouveau customer user ID (par exemple, l'achat a été effectué avant l'inscription), Adapty attribue le customer user ID au profil actuel, de sorte que tout l'historique des achats est conservé. - S'il s'agit d'un customer user ID existant (le customer user ID est déjà lié à un profil), vous devez récupérer le niveau d'accès réel après le changement de profil. Vous pouvez soit appeler [`getProfile`](unity-check-subscription-status) juste après l'identification, soit [écouter les mises à jour du profil](unity-check-subscription-status) pour que les données se synchronisent automatiquement. ## Prochaines étapes \{#next-steps\} Félicitations ! Vous avez implémenté la logique de paiement intégré dans votre application ! Nous vous souhaitons tout le succès possible pour la monétisation de votre application ! Pour tirer encore plus parti d'Adapty, vous pouvez explorer ces sujets : - [**Tests**](troubleshooting-test-purchases) : Assurez-vous que tout fonctionne comme prévu - [**Onboardings**](onboardings) : Engagez les utilisateurs avec des onboardings et favorisez la rétention - [**Intégrations**](configuration) : Intégrez des services d'attribution marketing et d'analyses en une seule ligne de code - [**Définir des attributs de profil personnalisés**](unity-setting-user-attributes) : Ajoutez des attributs personnalisés aux profils utilisateurs et créez des segments pour lancer des tests A/B ou afficher différents paywalls à différents utilisateurs --- # File: adapty-sdk-integration-skill-unity --- --- title: "Intégrer Adapty dans votre application Unity avec la compétence d'intégration SDK" description: "Utilisez la compétence adapty-sdk-integration pour intégrer le SDK Adapty dans votre application Unity de bout en bout avec votre outil de codage IA." --- :::important La compétence est en version bêta. Si elle se bloque ou se comporte de manière inattendue, suivez le [guide d'intégration étape par étape](adapty-cursor-unity) à la place — il guide votre outil IA à travers chaque étape avec la documentation appropriée. ::: Le [skill adapty-sdk-integration](https://github.com/adaptyteam/adapty-sdk-integration-skill) automatise l'intégration d'Adapty de bout en bout : configuration du tableau de bord, installation du SDK, paywall et vérification à chaque étape. Il détecte automatiquement votre plateforme et récupère la documentation Adapty pertinente à chaque étape. **Outils pris en charge** : Claude Code, GitHub Copilot CLI, OpenAI Codex, Gemini CLI. Pour l'installer, choisissez le formulaire correspondant à votre outil. La liste complète se trouve dans le [README du skill](https://github.com/adaptyteam/adapty-sdk-integration-skill). Le dépôt contient deux skills — `adapty-sdk-integration` et `ads-manager`, qui exécute Apple Search Ads via le CLI Adapty. Chaque commande ci-dessous installe les deux. **Claude Code** ``` claude plugin marketplace add adaptyteam/adapty-sdk-integration-skill claude plugin install adapty-sdk-integration@adapty ``` **GitHub Copilot CLI** ``` git clone https://github.com/adaptyteam/adapty-sdk-integration-skill.git cp -r adapty-sdk-integration-skill/skills/* ~/.copilot/skills/ ``` **Gemini CLI** ``` gemini skills install https://github.com/adaptyteam/adapty-sdk-integration-skill ``` **OpenAI Codex ou tout autre outil** — utilisez le [skills CLI](https://skills.sh) (notez que les skills installés de cette façon ne se mettent pas à jour automatiquement) : ``` npx skills add adaptyteam/adapty-sdk-integration-skill --all ``` `--all` installe les deux skills dans chaque agent détecté. Sans ce paramètre, le CLI vous demande lequel des deux vous souhaitez installer. Vous pouvez aussi cloner le dépôt et copier les répertoires sous `skills/` dans le répertoire des skills de votre outil. Après l'installation, exécutez le skill dans votre projet : ``` /adapty-sdk-integration ``` Le skill pose quelques questions de configuration, puis guide à travers la configuration du tableau de bord, l'installation du SDK, le paywall et la vérification. --- # File: adapty-cursor-unity --- --- title: "Intégrer Adapty dans votre application Unity avec l'aide de l'IA" description: "Un guide étape par étape pour intégrer Adapty dans votre application Unity avec Cursor, Context7, ChatGPT, Claude ou d'autres outils IA." --- Ce guide vous accompagne étape par étape dans l'intégration d'Adapty dans votre application Unity à l'aide d'un outil IA — vous lui fournissez les bonnes docs Adapty dans le bon ordre. For a fully automated integration, use the [adapty-sdk-integration skill](https://github.com/adaptyteam/adapty-sdk-integration-skill): it runs the whole integration from your AI coding tool in one command. ## Avant de commencer : configuration du tableau de bord \{#before-you-start-dashboard-setup\} Adapty nécessite quelques réglages dans le tableau de bord avant d'écrire la moindre ligne de code SDK. Vous pouvez le faire via un skill LLM interactif, ou manuellement depuis le Dashboard. ### Approche par skill (recommandée) \{#skill-approach-recommended\} Le skill Adapty CLI permet à votre LLM de configurer votre application, vos produits, niveaux d'accès, paywalls et placements directement — sans ouvrir le Dashboard à chaque étape. Vous n'avez qu'à [connecter vos stores](integrate-payments) dans le Dashboard. ``` npx skills add adaptyteam/adapty-cli --skill adapty-cli ``` Une fois le skill ajouté, lancez `/adapty-cli` dans votre agent. Il vous guidera à chaque étape — y compris quand ouvrir le Dashboard pour connecter vos stores. ### Approche manuelle \{#dashboard-approach\} Si vous préférez tout configurer manuellement, voici ce qu'il vous faut avant d'écrire du code. Votre LLM ne peut pas récupérer les valeurs du tableau de bord à votre place — vous devrez les lui fournir. 1. **Connectez vos stores** : Dans l'Adapty Dashboard, allez dans **App settings → General**. Connectez l'App Store et Google Play si votre application Unity cible les deux plateformes. C'est indispensable pour que les achats fonctionnent. [Connecter les stores](integrate-payments) 2. **Copiez votre clé SDK publique** : Dans l'Adapty Dashboard, allez dans **App settings → General**, puis repérez la section **API keys**. Dans le code, c'est la chaîne que vous passez au builder de configuration Adapty. 3. **Créez au moins un produit** : Dans l'Adapty Dashboard, accédez à la page **Products**. Vous ne référencez pas les produits directement dans le code — Adapty les livre via les paywalls. [Ajouter des produits](quickstart-products) 4. **Créez un paywall et un placement** : Dans l'Adapty Dashboard, créez un paywall sur la page **Paywalls**, puis assignez-le à un placement sur la page **Placements**. Dans le code, l'ID de placement est la chaîne que vous passez à `Adapty.GetPaywall("YOUR_PLACEMENT_ID")`. [Créer un paywall](quickstart-paywalls) 5. **Configurez les niveaux d'accès** : Dans l'Adapty Dashboard, configurez-les par produit sur la page **Products**. Dans le code, la chaîne vérifiée dans `profile.AccessLevels["premium"]?.IsActive`. Le niveau d'accès `premium` par défaut convient à la plupart des applications. Si les utilisateurs payants accèdent à des fonctionnalités différentes selon le produit (par exemple, un plan `basic` vs. un plan `pro`), [créez des niveaux d'accès supplémentaires](assigning-access-level-to-a-product) avant de commencer à coder. :::tip Une fois ces cinq éléments en place, vous êtes prêt à écrire du code. Indiquez à votre LLM : « Ma clé SDK publique est X, mon ID de placement est Y » pour qu'il génère un code d'initialisation et de récupération de paywall correct. ::: ### À configurer quand vous serez prêt \{#set-up-when-ready\} Ces éléments ne sont pas indispensables pour démarrer, mais vous en aurez besoin à mesure que votre intégration mûrit : - **Tests A/B** : Configurez-les sur la page **Placements**. Aucun changement de code nécessaire. [Tests A/B](ab-tests) - **Paywalls et placements supplémentaires** : Ajoutez d'autres appels `GetPaywall` avec des ID de placement différents. - **Intégrations analytics** : Configurez-les sur la page **Integrations**. La mise en place varie selon l'intégration. Voir [intégrations analytics](analytics-integration) et [intégrations attribution](attribution-integration). ## Fournir la documentation Adapty à votre LLM \{#feed-adapty-docs-to-your-llm\} ### Utiliser Context7 (recommandé) \{#use-context7-recommended\} [Context7](https://context7.com) est un serveur MCP qui donne à votre LLM un accès direct à la documentation Adapty à jour. Votre LLM récupère automatiquement les bonnes docs selon vos questions — pas besoin de coller des URL manuellement. Context7 fonctionne avec **Cursor**, **Claude Code**, **Windsurf** et d'autres outils compatibles MCP. Pour le configurer, lancez : ``` npx ctx7 setup ``` Cette commande détecte votre éditeur et configure le serveur Context7. Pour une configuration manuelle, consultez le [dépôt GitHub Context7](https://github.com/upstash/context7). Une fois configuré, référencez la bibliothèque Adapty dans vos prompts : ``` Use the adaptyteam/adapty-docs library to look up how to install the Unity SDK ``` :::warning Même si Context7 évite de coller des liens de docs manuellement, l'ordre d'implémentation est important. Suivez le [parcours d'implémentation](#implementation-walkthrough) ci-dessous étape par étape pour que tout fonctionne correctement. ::: ### Utiliser les docs en texte brut \{#use-plain-text-docs\} Vous pouvez accéder à n'importe quelle doc Adapty en texte brut Markdown. Ajoutez `.md` à la fin de son URL, ou cliquez sur **Copy for LLM** sous le titre de l'article. Par exemple : [adapty-cursor-unity.md](https://adapty.io/docs/fr/adapty-cursor-unity.md). Chaque étape du [parcours d'implémentation](#implementation-walkthrough) ci-dessous inclut un bloc « À envoyer à votre LLM » avec des liens `.md` à coller. Pour accéder à plus de documentation en une fois, consultez les [fichiers d'index et sous-ensembles par plateforme](#plain-text-doc-index-files) ci-dessous. ## Parcours d'implémentation \{#implementation-walkthrough\} La suite de ce guide décrit l'intégration d'Adapty dans l'ordre d'implémentation. Chaque étape inclut les docs à envoyer à votre LLM, ce que vous devez observer une fois terminé, et les problèmes courants. ### Planifier votre intégration \{#plan-your-integration\} Avant de plonger dans le code, demandez à votre LLM d'analyser votre projet et de créer un plan d'implémentation. Si votre outil IA dispose d'un mode planification (comme le mode plan de Cursor ou Claude Code), utilisez-le pour que le LLM puisse lire à la fois la structure de votre projet et les docs Adapty avant d'écrire du code. Indiquez à votre LLM quelle approche vous utilisez pour les achats — cela détermine les guides à suivre : - [**Adapty Paywall Builder**](adapty-paywall-builder) : Vous créez des paywalls dans le builder no-code d'Adapty, et le SDK les affiche automatiquement. - [**Paywalls créés manuellement**](unity-making-purchases) : Vous construisez votre propre interface de paywall dans le code, mais utilisez toujours Adapty pour récupérer les produits et gérer les achats. - [**Mode observateur**](observer-vs-full-mode) : Vous conservez votre infrastructure d'achat existante et utilisez Adapty uniquement pour l'analytics et les intégrations. Vous ne savez pas lequel choisir ? Lisez le [tableau comparatif dans le quickstart](unity-quickstart-paywalls). ### Installer et configurer le SDK \{#install-and-configure-the-sdk\} Ajoutez le package SDK Adapty via Unity Package Manager et activez-le avec votre clé SDK publique. C'est le socle — rien d'autre ne fonctionne sans ça. **Guide :** [Installer et configurer le SDK Adapty](sdk-installation-unity) À envoyer à votre LLM : ``` Read these Adapty docs before writing code: - https://adapty.io/docs/fr/sdk-installation-unity.md ``` :::tip[Checkpoint] - **Attendu :** Le projet se compile et s'exécute. La console Unity affiche le log d'activation Adapty. - **Point d'attention :** « Public API key is missing » → vérifiez que vous avez remplacé le placeholder par votre vraie clé depuis App settings. ::: ### Afficher les paywalls et gérer les achats \{#show-paywalls-and-handle-purchases\} Récupérez un paywall par ID de placement, affichez-le et gérez les événements d'achat. Les guides dont vous avez besoin dépendent de la façon dont vous gérez les achats. Testez chaque achat en sandbox au fur et à mesure — n'attendez pas la fin. Consultez [Tester les achats en sandbox](test-purchases-in-sandbox) pour les instructions de configuration. **Guides :** - [Activer les achats avec les paywalls (quickstart)](unity-quickstart-paywalls) - [Récupérer les paywalls Paywall Builder et leur configuration](unity-get-pb-paywalls) - [Afficher les paywalls](unity-present-paywalls) - [Gérer les événements de paywall](unity-handling-events) - [Répondre aux actions des boutons](unity-handle-paywall-actions) À envoyer à votre LLM : ``` Read these Adapty docs before writing code: - https://adapty.io/docs/fr/unity-quickstart-paywalls.md - https://adapty.io/docs/fr/unity-get-pb-paywalls.md - https://adapty.io/docs/fr/unity-present-paywalls.md - https://adapty.io/docs/fr/unity-handling-events.md - https://adapty.io/docs/fr/unity-handle-paywall-actions.md ``` :::tip[Checkpoint] - **Attendu :** Le paywall s'affiche avec vos produits configurés. Appuyer sur un produit déclenche la boîte de dialogue d'achat sandbox. - **Point d'attention :** Paywall vide ou erreur `GetPaywall` → vérifiez que l'ID de placement correspond exactement à celui du tableau de bord et que le placement a une audience assignée. ::: **Guides :** - [Activer les achats dans votre paywall personnalisé (quickstart)](unity-quickstart-manual) - [Récupérer les paywalls et les produits](fetch-paywalls-and-products-unity) - [Afficher un paywall conçu via Remote Config](present-remote-config-paywalls-unity) - [Effectuer des achats](unity-making-purchases) - [Restaurer des achats](unity-restore-purchase) À envoyer à votre LLM : ``` Read these Adapty docs before writing code: - https://adapty.io/docs/fr/unity-quickstart-manual.md - https://adapty.io/docs/fr/fetch-paywalls-and-products-unity.md - https://adapty.io/docs/fr/present-remote-config-paywalls-unity.md - https://adapty.io/docs/fr/unity-making-purchases.md - https://adapty.io/docs/fr/unity-restore-purchase.md ``` :::tip[Checkpoint] - **Attendu :** Votre paywall personnalisé affiche les produits récupérés depuis Adapty. Appuyer sur un produit déclenche la boîte de dialogue d'achat sandbox. - **Point d'attention :** Tableau de produits vide → vérifiez que le paywall a des produits assignés dans le tableau de bord et que le placement a une audience. ::: **Guides :** - [Présentation du mode observateur](observer-vs-full-mode) - [Implémenter le mode observateur](implement-observer-mode-unity) - [Signaler les transactions en mode observateur](report-transactions-observer-mode-unity) À envoyer à votre LLM : ``` Read these Adapty docs before writing code: - https://adapty.io/docs/fr/observer-vs-full-mode.md - https://adapty.io/docs/fr/implement-observer-mode-unity.md - https://adapty.io/docs/fr/report-transactions-observer-mode-unity.md ``` :::tip[Checkpoint] - **Attendu :** Après un achat sandbox via votre flow d'achat existant, la transaction apparaît dans le **Event Feed** du tableau de bord Adapty. - **Point d'attention :** Aucun événement → vérifiez que vous signalez bien les transactions à Adapty et que les notifications serveur sont configurées pour les deux stores. ::: ### Vérifier le statut de l'abonnement \{#check-subscription-status\} Après un achat, vérifiez dans le profil utilisateur la présence d'un niveau d'accès actif pour contrôler l'accès au contenu premium. **Guide :** [Vérifier le statut de l'abonnement](unity-check-subscription-status) À envoyer à votre LLM : ``` Read these Adapty docs before writing code: - https://adapty.io/docs/fr/unity-check-subscription-status.md ``` :::tip[Checkpoint] - **Attendu :** Après un achat sandbox, `profile.AccessLevels["premium"]?.IsActive` retourne `true`. - **Point d'attention :** `AccessLevels` vide après l'achat → vérifiez que le produit a un niveau d'accès assigné dans le tableau de bord. ::: ### Identifier les utilisateurs \{#identify-users\} Associez les comptes utilisateurs de votre application aux profils Adapty pour que les achats persistent sur tous les appareils. :::important Ignorez cette étape si votre application ne requiert pas d'authentification. ::: **Guide :** [Identifier les utilisateurs](unity-quickstart-identify) À envoyer à votre LLM : ``` Read these Adapty docs before writing code: - https://adapty.io/docs/fr/unity-quickstart-identify.md ``` :::tip[Checkpoint] - **Attendu :** Après avoir appelé `Adapty.Identify("your-user-id")`, la section **Profiles** du tableau de bord affiche votre ID utilisateur personnalisé. - **Point d'attention :** Appelez `Identify` après l'activation mais avant de récupérer les paywalls pour éviter une attribution de profil anonyme. ::: ### Se préparer pour la mise en production \{#prepare-for-release\} Une fois votre intégration fonctionnelle en sandbox, parcourez la checklist de mise en production pour vous assurer que tout est prêt. **Guide :** [Checklist de mise en production](release-checklist) À envoyer à votre LLM : ``` Read these Adapty docs before releasing: - https://adapty.io/docs/fr/release-checklist.md ``` :::tip[Checkpoint] - **Attendu :** Tous les éléments de la checklist confirmés : connexions aux stores, notifications serveur, flow d'achat, vérifications des niveaux d'accès et exigences de confidentialité. - **Point d'attention :** Notifications serveur manquantes → configurez les App Store Server Notifications dans **App settings → iOS SDK** et les Google Play Real-Time Developer Notifications dans **App settings → Android SDK**. ::: ## Fichiers d'index de documentation en texte brut \{#plain-text-doc-index-files\} Si vous avez besoin de donner à votre LLM un contexte plus large que des pages individuelles, nous hébergeons des fichiers d'index qui listent ou regroupent toute la documentation Adapty : - [`llms.txt`](https://adapty.io/docs/fr/llms.txt) : Liste toutes les pages avec des liens `.md`. Un [standard émergent](https://llmstxt.org/) pour rendre les sites accessibles aux LLM. Notez que pour certains agents IA (ex. ChatGPT), vous devrez télécharger `llms.txt` et le joindre à la conversation en tant que fichier. - [`llms-full.txt`](https://adapty.io/docs/fr/llms-full.txt) : L'intégralité de la documentation Adapty regroupée en un seul fichier. Très volumineux — à utiliser uniquement si vous avez besoin de la vue d'ensemble complète. - [`unity-llms.txt`](https://adapty.io/docs/fr/unity-llms.txt) et [`unity-llms-full.txt`](https://adapty.io/docs/fr/unity-llms-full.txt) spécifiques à Unity : Des sous-ensembles par plateforme qui économisent des tokens par rapport au site complet. --- # File: unity-paywalls --- --- title: "Flows et paywalls - Unity" description: "Affichez et gérez les flows et paywalls créés avec l'Adapty Flow Builder ou le Paywall Builder dans votre application Unity." --- ## Afficher les paywalls \{#display-paywalls\} ### Adapty Flow Builder & Paywall Builder :::tip Pour démarrer rapidement avec les paywalls Adapty Paywall Builder, consultez notre [guide de démarrage rapide](unity-quickstart-paywalls). ::: ### Implémenter les paywalls manuellement \{#implement-paywalls-manually\} Pour plus de guides sur l'implémentation des paywalls et la gestion des achats manuellement, consultez la [catégorie](unity-implement-paywalls-manually). ## Fonctionnalités utiles \{#useful-features\} --- # File: unity-get-pb-paywalls --- --- title: "Récupérer les flows et paywalls - Unity" description: "Récupérez les flows et paywalls depuis Adapty dans votre application Unity." --- Après avoir [conçu votre flow ou votre paywall dans le Paywall Builder](adapty-paywall-builder), vous pouvez l'afficher dans votre application mobile. La première étape consiste à récupérer le flow ou le paywall associé au placement ainsi que sa configuration d'affichage, comme décrit ci-dessous. :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. :::
Avant de commencer à afficher des flows dans votre application mobile (cliquez pour développer) 1. [Créez vos produits](create-product) dans l'Adapty Dashboard. 2. [Créez un flow/paywall et intégrez-y des produits](create-paywall) dans l'Adapty Dashboard. 3. [Créez des placements et intégrez-y votre flow/paywall](create-placement) dans l'Adapty Dashboard. 4. Installez le [SDK Adapty](sdk-installation-unity) dans votre application mobile.
## Récupérer un flow/paywall \{#fetch-flowpaywall\} Si vous avez conçu un flow ou un paywall avec le Flow Builder ou le Paywall Builder, vous n'avez pas à vous soucier de son rendu dans le code de votre application mobile pour l'afficher à l'utilisateur. Un tel flow ou paywall contient à la fois ce qui doit être affiché et la manière dont cela doit l'être. Vous devez néanmoins récupérer son ID via le placement, sa configuration de vue, puis le présenter dans votre application mobile. Pour des performances optimales, il est essentiel de récupérer le flow ou le paywall ainsi que sa [configuration de vue](unity-get-pb-paywalls#fetch-the-view-configuration) le plus tôt possible, afin de laisser suffisamment de temps aux images pour se télécharger avant de les afficher à l'utilisateur. Pour obtenir un flow ou un paywall, utilisez la méthode `GetFlow` : ```csharp showLineNumbers Adapty.GetFlow( "YOUR_PLACEMENT_ID", AdaptyPlacementFetchPolicy.Default, TimeSpan.FromSeconds(5), (flow, error) => { if (error != null) { // handle the error return; } // flow - the requested flow/paywall } ); ``` Paramètres : | Paramètre | Présence | Description | |---------|--------|-----------| | **placementId** | requis | L'identifiant du [Placement](placements) souhaité. C'est la valeur que vous avez indiquée lors de la création d'un placement dans l'Adapty Dashboard. | | **fetchPolicy** | défaut : `AdaptyPlacementFetchPolicy.Default` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option, car elle garantit que vos utilisateurs reçoivent toujours les données les plus récentes.

Cependant, si vous pensez que vos utilisateurs ont une connexion internet instable, envisagez d'utiliser `AdaptyPlacementFetchPolicy.ReturnCacheDataElseLoad` pour renvoyer les données en cache si elles existent. Dans ce cas, les utilisateurs n'obtiendront peut-être pas les toutes dernières données, mais les temps de chargement seront plus rapides, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, ce qui permet de l'utiliser en toute sécurité pendant la session pour éviter les requêtes réseau.

Notez que le cache reste intact après le redémarrage de l'application et n'est effacé que lors de la réinstallation ou d'un nettoyage manuel.

Le SDK Adapty stocke les flows et les paywalls localement en deux couches : le cache mis à jour régulièrement décrit ci-dessus et les [paywalls de secours](fallback-paywalls). Nous utilisons également un CDN pour les récupérer plus rapidement et un serveur de secours indépendant en cas d'indisponibilité du CDN. Ce système est conçu pour garantir que vous obtenez toujours la dernière version tout en assurant la fiabilité, même lorsque la connexion internet est limitée.

| | **loadTimeout** | défaut : 5 sec |

Cette valeur limite le délai d'expiration de cette méthode. Si le délai est dépassé, les données en cache ou le fallback local sont renvoyés.

Notez que dans de rares cas, cette méthode peut expirer légèrement après le délai spécifié dans `loadTimeout`, car l'opération peut impliquer différentes requêtes en interne.

| | Paramètre | Description | | :-------- | :---------- | | Flow | Un objet `AdaptyFlow` contenant le placement, les identifiants (`InstanceIdentity`, `VariationId`), le nom, les variantes de paywall (`Paywalls` — une liste d'`AdaptyFlowPaywall`) et les Remote Configs (`RemoteConfigs` — une liste avec une entrée par locale). Pour récupérer les produits réels en vue d'un préchargement, d'une UI personnalisée ou de vérifications programmatiques, appelez `GetPaywallProducts(flow)`. | ## Récupérer la configuration de la vue \{#fetch-the-view-configuration\} Après avoir récupéré le flow ou le paywall, chargez sa configuration de vue et créez la vue en une seule étape avec la méthode `CreateFlowView`. Il n'y a pas d'indicateur distinct à vérifier : si le placement a été conçu dans le **Flow Builder** (un flow) ou le **Paywall Builder** (un paywall), `CreateFlowView` retourne la vue prête à être affichée. Si le placement est un paywall personnalisé sans interface Builder, `CreateFlowView` retourne une erreur — [gérez-la comme un paywall Remote Config](present-remote-config-paywalls-unity). :::important Assurez-vous d'activer le bouton **Show on device** dans le Flow Builder. Si cette option n'est pas activée, la configuration de la vue ne sera pas disponible pour être récupérée. ::: ```csharp showLineNumbers var parameters = new AdaptyUICreateFlowViewParameters() .SetPreloadProducts(true) .SetLoadTimeout(TimeSpan.FromSeconds(5)); AdaptyUI.CreateFlowView(flow, parameters, (view, error) => { if (error != null) { // the flow has no view configured, or view creation failed return; } // use view }); ``` | Paramètre | Présence | Description | | :--------------------------- | :------------- | :----------------------------------------------------------- | | **flow** | requis | Un objet `AdaptyFlow` obtenu via `Adapty.GetFlow`. | | **Locale** | optionnel | L'identifiant de la [localisation du Builder](add-paywall-locale-in-adapty-paywall-builder) à utiliser pour afficher le flow ou le paywall, par exemple `en` ou `pt-br`. Un flow est localisé au moment de la création de sa vue, c'est donc le seul endroit où choisir sa localisation. Le SDK ne lit pas la locale de l'appareil : si vous omettez ce paramètre, le flow s'affiche en `en`, ou dans sa locale par défaut si le flow ne possède pas de localisation `en`. Le code doit correspondre exactement à un code de localisation du flow. Voir [Utiliser les localisations et les codes de locale](unity-localizations-and-locale-codes). | | **LoadTimeout** | optionnel | Cette valeur limite le délai d'attente de cette méthode. Si le délai est atteint, les données en cache ou le fallback local sont renvoyés. Notez que dans de rares cas, cette méthode peut expirer légèrement après la valeur indiquée dans `LoadTimeout`, car l'opération peut s'appuyer sur plusieurs requêtes en coulisses. | | **PreloadProducts** | optionnel | Définissez à `true` pour précharger les produits et améliorer les performances. Lorsque cette option est activée, les produits sont chargés à l'avance, ce qui réduit le temps nécessaire à l'affichage du flow ou du paywall. | | **ProductPurchaseParameters** | optionnel | Android uniquement (ignoré sur iOS). Un dictionnaire associant `AdaptyProductIdentifier` à `AdaptyPurchaseParameters`. Utilisez ce paramètre pour configurer des options d'achat spécifiques, comme les offres personnalisées ou les paramètres de mise à jour d'abonnement pour des produits individuels dans le flow ou le paywall. | | **EnableSafeAreaPaddings** | optionnel | Android uniquement (ignoré sur iOS). Lorsque `true`, la vue du flow applique les marges de zone sécurisée. Valeur par défaut : `true`. La valeur par défaut convient à la plupart des cas. | :::note Si vous utilisez plusieurs langues, découvrez comment ajouter une [localisation dans le Builder](add-paywall-locale-in-adapty-paywall-builder). ::: Une fois chargé, [présentez le flow ou le paywall](unity-present-paywalls). ## Obtenez un flow ou un paywall pour l'audience par défaut afin d'accélérer la récupération \{#get-a-flow-or-paywall-for-a-default-audience-to-fetch-it-faster\} En général, les flows et les paywalls sont récupérés quasi instantanément, vous n'avez donc pas à vous soucier d'optimiser ce processus. Cependant, si vous avez de nombreuses audiences et placements et que vos utilisateurs ont une connexion internet faible, la récupération d'un flow ou d'un paywall peut prendre plus de temps que souhaité. Dans ce cas, vous pouvez afficher un flow ou un paywall par défaut pour garantir une expérience utilisateur fluide plutôt que de ne rien afficher. Pour y remédier, vous pouvez utiliser la méthode `GetFlowForDefaultAudience`, qui récupère le flow ou le paywall du placement spécifié pour l'audience **All Users**. Il est cependant essentiel de comprendre que l'approche recommandée est de récupérer le flow ou le paywall via la méthode `GetFlow`, comme expliqué dans la section [Récupérer un flow/paywall](#fetch-flowpaywall) ci-dessus. :::warning Pourquoi nous recommandons d'utiliser `GetFlow` La méthode `GetFlowForDefaultAudience` présente plusieurs inconvénients majeurs : - **Problèmes potentiels de compatibilité ascendante** : si vous devez afficher des flows différents selon les versions de l'application (version actuelle et versions futures), vous pourriez rencontrer des difficultés. Vous devrez soit concevoir des flows compatibles avec la version actuelle (héritée), soit accepter que les utilisateurs de cette version puissent rencontrer des problèmes avec des flows qui ne s'affichent pas correctement. - **Perte de ciblage** : tous les utilisateurs verront le même flow conçu pour l'audience **All Users**, ce qui signifie que vous perdez le ciblage personnalisé (notamment par pays, attribution marketing ou attributs personnalisés). Si vous acceptez ces inconvénients pour bénéficier d'une récupération plus rapide du flow ou du paywall, utilisez la méthode `GetFlowForDefaultAudience` comme suit. Sinon, utilisez `GetFlow` décrit [ci-dessus](#fetch-flowpaywall). ::: ```csharp showLineNumbers Adapty.GetFlowForDefaultAudience( "YOUR_PLACEMENT_ID", AdaptyPlacementFetchPolicy.Default, (flow, error) => { if (error != null) { // handle the error return; } // flow - the requested flow } ); ``` | Paramètre | Présence | Description | |---------|--------|-----------| | **placementId** | obligatoire | L'identifiant du [Placement](placements). C'est la valeur que vous avez indiquée lors de la création d'un placement dans votre Adapty Dashboard. | | **fetchPolicy** | par défaut : `AdaptyPlacementFetchPolicy.Default` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option, car elle garantit que vos utilisateurs disposent toujours des données les plus récentes.

Cependant, si vous pensez que vos utilisateurs ont une connexion internet instable, envisagez d'utiliser `AdaptyPlacementFetchPolicy.ReturnCacheDataElseLoad` pour renvoyer les données en cache si elles existent. Dans ce cas, les utilisateurs n'auront peut-être pas les toutes dernières données, mais les temps de chargement seront plus rapides, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, il est donc sans risque de l'utiliser pendant la session pour éviter des requêtes réseau.

Notez que le cache est conservé après le redémarrage de l'application et n'est effacé que lors de la désinstallation de celle-ci ou par un nettoyage manuel.

| ## Personnaliser les ressources \{#customize-assets\} Pour personnaliser les images et vidéos dans votre flow ou paywall, implémentez des ressources personnalisées. Les images et vidéos hero ont des IDs prédéfinis : `hero_image` et `hero_video`. Dans un bundle de ressources personnalisées, vous ciblez ces éléments par leurs IDs et personnalisez leur comportement. Pour les autres images et vidéos, vous devez [définir un ID personnalisé](custom-media) dans l'Adapty Dashboard. Par exemple, vous pouvez : - Afficher une image ou vidéo différente à certains utilisateurs. - Afficher une image de prévisualisation locale pendant le chargement d'une image principale distante. - Afficher une image de prévisualisation avant de lancer une vidéo. Voici un exemple montrant comment fournir des ressources personnalisées via un dictionnaire simple : ```csharp showLineNumbers var customAssets = new Dictionary { { "custom_image", AdaptyCustomAsset.LocalImageFile("custom_assets/images/custom_image.png") }, { "hero_video", AdaptyCustomAsset.LocalVideoFile("custom_assets/videos/custom_video.mp4") } }; var parameters = new AdaptyUICreateFlowViewParameters() .SetCustomAssets(customAssets) .SetLoadTimeout(TimeSpan.FromSeconds(3)); AdaptyUI.CreateFlowView(flow, parameters, (view, error) => { // handle the result }); ``` :::note Si une ressource est introuvable ou ne parvient pas à se charger, le flow ou le paywall reviendra à son apparence par défaut telle que configurée dans le Builder. ::: ## Configurer des minuteries définies par le développeur \{#set-up-developer-defined-timers\} Pour utiliser des minuteries personnalisées dans votre application Unity, passez un dictionnaire d'identifiants de minuteries et leurs dates de fin à la méthode `SetCustomTimers`. Voici un exemple : ```csharp showLineNumbers var customTimers = new Dictionary { { "CUSTOM_TIMER_6H", DateTime.Now.AddHours(6) }, { "CUSTOM_TIMER_NY", new DateTime(2026, 1, 1) } }; var parameters = new AdaptyUICreateFlowViewParameters() .SetCustomTimers(customTimers) .SetLoadTimeout(TimeSpan.FromSeconds(3)); AdaptyUI.CreateFlowView(flow, parameters, (view, error) => { // handle the result }); ``` Dans cet exemple, `CUSTOM_TIMER_NY` et `CUSTOM_TIMER_6H` sont les **Timer ID**s des minuteries définies par le développeur que vous configurez dans l'Adapty Dashboard. Le résolveur de minuterie garantit que votre application met dynamiquement à jour chaque minuterie avec la valeur correcte. Par exemple : - `CUSTOM_TIMER_NY` : le temps restant jusqu'à la fin de la minuterie, par exemple le jour du Nouvel An. - `CUSTOM_TIMER_6H` : le temps restant dans une période de 6 heures qui a démarré lorsque l'utilisateur a ouvert le flow ou le paywall.
Après avoir [conçu la partie visuelle de votre paywall](adapty-paywall-builder) avec le nouveau Paywall Builder dans l'Adapty Dashboard, vous pouvez l'afficher dans votre application mobile. La première étape consiste à récupérer le paywall associé au placement et sa configuration d'affichage, comme décrit ci-dessous. :::warning Le nouveau Paywall Builder fonctionne avec le SDK Unity version 3.3.0 ou supérieure. ::: Veuillez noter que ce sujet concerne les paywalls personnalisés avec le Paywall Builder. Si vous implémentez vos paywalls manuellement, reportez-vous à la rubrique [Récupérer les paywalls et les produits pour les paywalls Remote Config dans votre application mobile](fetch-paywalls-and-products-unity). :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. :::
Avant de commencer à afficher les paywalls dans votre application mobile (cliquez pour développer) 1. [Créez vos produits](create-product) dans l'Adapty Dashboard. 2. [Créez un paywall et intégrez-y les produits](create-paywall) dans l'Adapty Dashboard. 3. [Créez des placements et intégrez-y votre paywall](create-placement) dans l'Adapty Dashboard. 4. Installez le [SDK Adapty](sdk-installation-unity) dans votre application mobile.
## Récupérer un paywall créé avec le Paywall Builder \{#fetch-paywall-designed-with-paywall-builder\} Si vous avez [conçu un paywall avec le Paywall Builder](adapty-paywall-builder), vous n'avez pas à vous soucier de son rendu dans le code de votre application mobile pour l'afficher à l'utilisateur. Un tel paywall contient à la fois ce qui doit être affiché et la manière dont cela doit l'être. Vous devez néanmoins récupérer son identifiant via le placement, sa configuration d'affichage, puis le présenter dans votre application mobile. Pour garantir des performances optimales, il est essentiel de récupérer le paywall et sa [configuration de vue](unity-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder) le plus tôt possible, afin de laisser suffisamment de temps aux images de se télécharger avant de les présenter à l'utilisateur. Pour obtenir un paywall, utilisez la méthode `GetPaywall` : ```csharp showLineNumbers Adapty.GetPaywall("YOUR_PLACEMENT_ID", "en", (paywall, error) => { if(error != null) { // handle the error return; } // paywall - the resulting object }); ``` Paramètres : | Paramètre | Présence | Description | |---------|--------|-----------| | **placementId** | requis | L'identifiant du [Placement](placements) souhaité. Il s'agit de la valeur que vous avez spécifiée lors de la création d'un placement dans l'Adapty Dashboard. | | **locale** |

optionnel

défaut : `en`

|

L'identifiant de la [localisation du paywall](add-paywall-locale-in-adapty-paywall-builder). Ce paramètre doit être un code de langue composé d'un ou deux sous-tags séparés par le caractère moins (**-**). Le premier sous-tag désigne la langue, le second la région.

Exemple : `en` signifie l'anglais, `pt-br` représente le portugais brésilien.

Consultez [Localisations et codes de langue](localizations-and-locale-codes) pour plus d'informations sur les codes de langue et nos recommandations d'utilisation.

| | **fetchPolicy** | défaut : `.reloadRevalidatingCacheData` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option, car elle garantit que vos utilisateurs obtiennent toujours les données les plus récentes.

Toutefois, si vous pensez que vos utilisateurs sont confrontés à une connexion internet instable, envisagez d'utiliser `.returnCacheDataElseLoad` pour renvoyer les données en cache lorsqu'elles existent. Dans ce cas, les utilisateurs ne recevront peut-être pas les toutes dernières données, mais les temps de chargement seront plus rapides, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, il est donc sûr de l'utiliser pendant la session afin d'éviter des requêtes réseau.

Notez que le cache est conservé lors du redémarrage de l'application et n'est effacé que lors d'une réinstallation ou d'un nettoyage manuel.

Le SDK Adapty stocke les paywalls localement sur deux couches : le cache mis à jour régulièrement décrit ci-dessus et les [paywalls de secours](fallback-paywalls). Nous utilisons également un CDN pour récupérer les paywalls plus rapidement, ainsi qu'un serveur de secours indépendant en cas d'inaccessibilité du CDN. Ce système est conçu pour vous garantir toujours la dernière version de vos paywalls, tout en assurant la fiabilité même lorsque la connexion internet est limitée.

| | **loadTimeout** | défaut : 5 sec |

Cette valeur limite le délai d'expiration de cette méthode. Si le délai est atteint, les données en cache ou le fallback local sont renvoyés.

Notez que dans de rares cas, cette méthode peut expirer légèrement après le délai spécifié dans `loadTimeout`, car l'opération peut regrouper différentes requêtes en coulisses.

| Paramètres de réponse : | Paramètre | Description | | :-------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | | Paywall | Un objet [`AdaptyPaywall`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html) contenant une liste d'identifiants de produits, l'identifiant du paywall, la Remote Config, et plusieurs autres propriétés. | ## Récupérer la configuration d'affichage d'un paywall créé avec Paywall Builder \{#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder\} :::important Assurez-vous d'activer le bouton **Show on device** dans le Paywall Builder. Si cette option n'est pas activée, la configuration d'affichage ne sera pas disponible pour la récupération. ::: Après avoir récupéré le paywall, vérifiez s'il inclut une `ViewConfiguration`, ce qui indique qu'il a été créé avec Paywall Builder. Cela vous guidera sur la façon d'afficher le paywall. Si la `ViewConfiguration` est présente, traitez-le comme un paywall Paywall Builder ; sinon, [gérez-le comme un paywall Remote Config](present-remote-config-paywalls-unity). Dans le SDK Unity, appelez directement la méthode `CreatePaywallView` sans récupérer manuellement la configuration de la vue au préalable. :::warning Le résultat de la méthode `CreatePaywallView` ne peut être utilisé qu'une seule fois. Si vous devez l'utiliser à nouveau, appelez de nouveau la méthode `CreatePaywallView`. L'appeler deux fois sans recréer peut entraîner l'erreur `AdaptyUIError.viewAlreadyPresented`. ::: ```csharp showLineNumbers var parameters = new AdaptyUICreatePaywallViewParameters() .SetPreloadProducts(preloadProducts) .SetLoadTimeout(new TimeSpan(0, 0, 3)); AdaptyUI.CreatePaywallView(paywall, parameters, (view, error) => { // handle the result }); ``` Paramètres : | Paramètre | Présence | Description | | :------------------ | :------------- | :----------------------------------------------------------- | | **paywall** | obligatoire | Un objet `AdaptyPaywall` permettant d'obtenir un contrôleur pour le paywall souhaité. | | **loadTimeout** | défaut : 5 sec | Cette valeur limite le délai d'attente de cette méthode. Si le délai est dépassé, les données en cache ou le fallback local seront retournés. Notez que dans de rares cas, cette méthode peut expirer légèrement après la valeur spécifiée dans `loadTimeout`, car l'opération peut impliquer différentes requêtes en interne. | | **PreloadProducts** | optionnel | Fournissez un tableau d'`AdaptyPaywallProducts` pour optimiser le moment d'affichage des produits à l'écran. Si `nil` est passé, AdaptyUI récupérera automatiquement les produits nécessaires. | | **CustomTags** | optionnel | Définissez un dictionnaire de tags personnalisés et leurs valeurs résolues. Les tags personnalisés servent de balises dans le contenu du paywall, remplacées dynamiquement par des chaînes spécifiques pour un contenu personnalisé. Consultez la rubrique Tags personnalisés dans le Paywall Builder pour plus de détails. | | **CustomTimers** | optionnel | Définissez un dictionnaire de minuteries personnalisées et leurs dates de fin. Les minuteries personnalisées permettent d'afficher des comptes à rebours dans votre paywall. | :::note Si vous utilisez plusieurs langues, découvrez comment ajouter une [localisation Paywall Builder](add-paywall-locale-in-adapty-paywall-builder) et comment utiliser correctement les codes de langue [ici](localizations-and-locale-codes). ::: Une fois que vous avez la vue, [affichez le paywall](unity-present-paywalls). ## Personnaliser les assets \{#customize-assets\} Pour personnaliser les images et vidéos de votre paywall, implémentez des assets personnalisés. Les images et vidéos hero ont des IDs prédéfinis : `hero_image` et `hero_video`. Dans un bundle d'assets personnalisé, vous ciblez ces éléments par leurs IDs et personnalisez leur comportement. Pour les autres images et vidéos, vous devez [définir un ID personnalisé](custom-media) dans l'Adapty Dashboard. Par exemple, vous pouvez : - Afficher une image ou vidéo différente à certains utilisateurs. - Afficher une image de prévisualisation locale pendant le chargement d'une image principale distante. - Afficher une image de prévisualisation avant de lancer une vidéo. :::important Pour utiliser cette fonctionnalité, mettez à jour le SDK Unity d'Adapty vers la version 3.8.0 ou supérieure. ::: Voici un exemple de la façon dont vous pouvez fournir des ressources personnalisées via un simple dictionnaire : ```csharp showLineNumbers var customAssets = new Dictionary { { "custom_image", AdaptyCustomAsset.LocalImageFile("custom_assets/images/custom_image.png") }, { "hero_video", AdaptyCustomAsset.LocalVideoFile("custom_assets/videos/custom_video.mp4") } }; var parameters = new AdaptyUICreatePaywallViewParameters() .SetCustomAssets(customAssets) .SetLoadTimeout(new TimeSpan(0, 0, 3)); AdaptyUI.CreatePaywallView(paywall, parameters, (view, error) => { // handle the result }); ``` :::note Si un asset est introuvable, le paywall reviendra à son apparence par défaut. ::: ## Configurer des minuteries définies par le développeur \{#set-up-developer-defined-timers\} Pour utiliser des minuteries personnalisées dans votre application Unity, vous pouvez passer un dictionnaire d'identifiants de minuteries et leurs dates de fin directement à la méthode `SetCustomTimers`. Voici un exemple : ```csharp showLineNumbers var customTimers = new Dictionary { { "CUSTOM_TIMER_6H", DateTime.Now.AddHours(6) }, { "CUSTOM_TIMER_NY", new DateTime(2025, 1, 1) } }; var parameters = new AdaptyUICreatePaywallViewParameters() .SetCustomTimers(customTimers) .SetLoadTimeout(new TimeSpan(0, 0, 3)); AdaptyUI.CreatePaywallView(paywall, parameters, (view, error) => { // handle the result }); ``` Dans cet exemple, `CUSTOM_TIMER_NY` et `CUSTOM_TIMER_6H` sont les **Timer ID**s des minuteries définies par le développeur que vous avez configurées dans l'Adapty Dashboard. Le résolveur de minuterie garantit que votre application met dynamiquement à jour chaque minuterie avec la valeur correcte. Par exemple : - `CUSTOM_TIMER_NY` : le temps restant jusqu'à la fin de la minuterie, par exemple le Jour de l'An. - `CUSTOM_TIMER_6H` : le temps restant dans une période de 6 heures qui a démarré lorsque l'utilisateur a ouvert le paywall. ## Accélérer la récupération des paywalls avec le paywall d'audience par défaut \{#speed-up-paywall-fetching-with-default-audience-paywall\} En règle générale, les paywalls sont récupérés presque instantanément, vous n'avez donc pas à vous soucier d'optimiser ce processus. Cependant, si vous avez de nombreuses audiences et paywalls, et que vos utilisateurs disposent d'une connexion internet faible, la récupération d'un paywall peut prendre plus de temps que souhaité. Dans ce cas, vous pouvez afficher un paywall par défaut pour garantir une expérience utilisateur fluide plutôt que de ne rien afficher du tout. Pour y remédier, vous pouvez utiliser la méthode `GetPaywallForDefaultAudience`, qui récupère le paywall du placement spécifié pour l'audience **All Users**. Il est cependant essentiel de comprendre que l'approche recommandée consiste à récupérer le paywall via la méthode `getPaywall`, comme décrit dans la section [Récupérer le paywall](#fetch-paywall-designed-with-paywall-builder) ci-dessus. :::warning Privilégiez `GetPaywall` plutôt que `GetPaywallForDefaultAudience`, car cette dernière présente des limitations importantes : - **Problèmes de compatibilité** : peut créer des difficultés lors de la prise en charge de plusieurs versions de l'application, nécessitant soit des designs rétrocompatibles, soit d'accepter que les anciennes versions s'affichent incorrectement. - **Pas de personnalisation** : affiche uniquement le contenu pour l'audience « Tous les utilisateurs », sans ciblage basé sur le pays, l'attribution ou des attributs personnalisés. Si la rapidité de récupération compense ces inconvénients pour votre cas d'usage, utilisez `GetPaywallForDefaultAudience` comme indiqué ci-dessous. Sinon, utilisez `GetPaywall` comme décrit [ci-dessus](#fetch-paywall-designed-with-paywall-builder). ::: ```csharp showLineNumbers Adapty.GetPaywallForDefaultAudience("YOUR_PLACEMENT_ID", "en", (paywall, error) => { if(error != null) { // handle the error return; } // paywall - the resulting object }); ``` Paramètres : | Paramètre | Présence | Description | |---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **placementId** | requis | L'identifiant du [Placement](placements) souhaité. Il s'agit de la valeur que vous avez spécifiée lors de la création d'un placement dans l'Adapty Dashboard. | | **locale** |

optionnel

par défaut : `en`

|

L'identifiant de la localisation du paywall. Ce paramètre doit être un code de langue composé d'un ou deux sous-tags séparés par le caractère moins (**-**). Le premier sous-tag désigne la langue, le second désigne la région.

Exemple : `en` signifie l'anglais, `pt-br` représente le portugais brésilien.

| | **fetchPolicy** | par défaut : `.reloadRevalidatingCacheData` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option, car elle garantit que vos utilisateurs reçoivent toujours les données les plus récentes.

Toutefois, si vous pensez que vos utilisateurs ont une connexion internet instable, envisagez d'utiliser `.returnCacheDataElseLoad` pour renvoyer les données en cache si elles existent. Dans ce cas, les utilisateurs pourraient ne pas obtenir les toutes dernières données, mais ils bénéficieront de temps de chargement plus rapides, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, il est donc sans risque de l'utiliser pendant la session pour éviter les requêtes réseau.

Notez que le cache reste intact après un redémarrage de l'application et n'est effacé que lors d'une réinstallation ou d'un nettoyage manuel.

Le SDK Adapty stocke les paywalls localement sur deux couches : le cache mis à jour régulièrement décrit ci-dessus et les paywalls de secours. Nous utilisons également un CDN pour récupérer les paywalls plus rapidement, ainsi qu'un serveur de secours indépendant en cas d'inaccessibilité du CDN. Ce système est conçu pour garantir que vous disposez toujours de la dernière version de vos paywalls, tout en assurant la fiabilité même lorsque la connexion internet est limitée.

|
--- # File: unity-present-paywalls --- --- title: "Afficher les paywalls" description: "Découvrez comment afficher les paywalls dans votre application Unity avec le SDK Adapty." --- Si vous avez personnalisé un paywall avec le Paywall Builder, vous n'avez pas à vous soucier de son rendu dans le code de votre application mobile pour l'afficher à l'utilisateur. Un tel paywall contient à la fois ce qui doit être affiché et la manière dont cela doit l'être. :::warning Ce guide couvre le **nouveau Paywall Builder**, qui nécessite le SDK Adapty 3.3.0 ou une version ultérieure. Pour afficher des paywalls avec Remote Config, consultez [Afficher les paywalls conçus avec Remote Config](present-remote-config-paywalls). ::: Pour afficher un paywall, utilisez la méthode `view.Present()` sur le `view` créé par la méthode [`CreatePaywallView`](unity-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder). Chaque `view` ne peut être utilisé qu'une seule fois. Si vous devez afficher le paywall à nouveau, appelez `CreatePaywallView` une nouvelle fois pour créer une nouvelle instance de `view`. :::warning Réutiliser le même `view` sans le recréer peut entraîner une erreur `AdaptyUIError.viewAlreadyPresented`. ::: ```csharp showLineNumbers title="Unity" view.Present((error) => { // handle the error }); ``` :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. ::: ## Afficher une boîte de dialogue \{#show-dialog\} Utilisez cette méthode à la place des boîtes de dialogue natives lorsqu'un paywall est affiché sur Android. Sur Android, les alertes classiques apparaissent derrière le paywall, ce qui les rend invisibles pour les utilisateurs. Cette méthode garantit un affichage correct de la boîte de dialogue au-dessus du paywall sur toutes les plateformes. ```csharp showLineNumbers title="Unity" var dialog = new AdaptyUIDialogConfiguration() .SetTitle("Close paywall?") .SetContent("You will lose access to exclusive offers.") .SetDefaultActionTitle("Stay") .SetSecondaryActionTitle("Close"); AdaptyUI.ShowDialog(view, dialog, (action, error) => { if (error == null) { if (action == AdaptyUIDialogActionType.Secondary) { // User confirmed - close the paywall view.Dismiss(); } // If primary - do nothing, user stays } }); ``` ## Configurer le style de présentation iOS \{#configure-ios-presentation-style\} Configurez la façon dont le paywall est présenté sur iOS en passant le paramètre `iosPresentationStyle` à la méthode `Present()`. Ce paramètre accepte les valeurs `AdaptyUIIOSPresentationStyle.FullScreen` (par défaut) ou `AdaptyUIIOSPresentationStyle.PageSheet`. ```csharp showLineNumbers title="Unity" view.Present(AdaptyUIIOSPresentationStyle.PageSheet, (error) => { // handle the error }); ``` --- # File: unity-handle-paywall-actions --- --- title: "Répondre aux actions de flow - Unity" description: "Gérez les actions de boutons des flows et des paywalls dans votre application Unity." --- Si vous créez des flows ou des paywalls avec le Flow Builder ou le Paywall Builder d'Adapty, il est essentiel de configurer correctement les boutons : 1. Ajoutez un [bouton dans le builder](paywall-buttons) et attribuez-lui une action existante ou créez un identifiant d'action personnalisé. 2. Écrivez le code dans votre application pour gérer chaque action assignée. Ce guide explique comment gérer les actions personnalisées et les actions existantes dans votre code. :::warning **Seuls les achats et les restaurations sont gérés automatiquement.** Toutes les autres actions de bouton, comme fermer les flows ou ouvrir des liens, nécessitent une implémentation appropriée dans le code de l'application. ::: ## Configurer l'écouteur d'événements des flows \{#set-up-the-flows-events-listener\} Pour gérer les actions des flows, implémentez l'interface `IAdaptyFlowsEventsListener` et enregistrez-la avec `Adapty.SetFlowsEventsListener()`. Cela doit être fait tôt dans le cycle de vie de votre application, généralement dans votre scène principale ou lors de l'initialisation de l'app. ```csharp showLineNumbers title="Unity" using AdaptySDK; public class FlowsListener : MonoBehaviour, IAdaptyFlowsEventsListener { void Start() { Adapty.SetFlowsEventsListener(this); } // implement all IAdaptyFlowsEventsListener methods here } ``` `IAdaptyFlowsEventsListener` est une interface C#, donc implémentez toutes ses méthodes — consultez [Gérer les événements de flow et de paywall](unity-handling-events) pour la liste complète. Les exemples ci-dessous montrent uniquement la méthode `FlowViewDidPerformAction`. Toutes les actions de bouton arrivent dans le callback `FlowViewDidPerformAction(view, action)` sous forme d'objet `AdaptyUIUserAction` avec un `Type` parmi `Close`, `SystemBack`, `OpenUrl` ou `Custom`, ainsi qu'une `Value` optionnelle (l'URL ou l'identifiant de l'action personnalisée). ## Fermer les flows et les paywalls \{#close-flows-and-paywalls\} Pour ajouter un bouton permettant de fermer votre flow ou paywall : 1. Dans le builder, ajoutez un bouton et assignez-lui l'action **Close**. 2. Dans le code de votre application, implémentez un gestionnaire pour l'action `Close` qui ferme le flow. :::info Une vue fermée est détruite et ne peut plus être affichée. Pour afficher le flow à nouveau, appelez `CreateFlowView` une nouvelle fois. ::: ```csharp showLineNumbers title="Unity" public void FlowViewDidPerformAction( AdaptyUIFlowView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Close: view.Dismiss(null); break; default: // handle other events break; } } ``` ## Gérer le bouton retour système Android \{#handle-the-android-system-back-button\} Appuyer sur le bouton retour système Android (ou utiliser le geste de retour) émet une action de type `SystemBack`. Cela ne ferme pas le flow en soi — le flow reste ouvert, et l'utilisateur le quitte via un chemin que vous définissez, comme un bouton **Close** ou une action `on_device_back` dans le builder. Si vous souhaitez que le bouton retour système ferme le flow, gérez l'action vous-même : ```csharp showLineNumbers title="Unity" public void FlowViewDidPerformAction( AdaptyUIFlowView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Close: case AdaptyUIUserActionType.SystemBack: view.Dismiss(null); break; default: // handle other events break; } } ``` ## Ouvrir des URL depuis des flows et des paywalls :::tip Si vous souhaitez ajouter un groupe de liens (par exemple, les conditions d'utilisation et la restauration des achats), ajoutez un élément **Link** dans le builder et gérez-le de la même façon que les boutons avec l'action **Open URL**. ::: Pour ajouter un bouton qui ouvre un lien depuis votre flow ou paywall (par exemple, **Terms of use** ou **Privacy policy**) : 1. Dans le builder, ajoutez un bouton, assignez-lui l'action **Open URL** et saisissez l'URL à ouvrir. 2. Dans le code de votre application, implémentez un gestionnaire pour l'action `OpenUrl` qui ouvre l'URL reçue. Utilisez la méthode `AdaptyUI.OpenUrl` pour ouvrir l'URL nativement, en respectant l'option de navigateur externe ou intégré (`action.OpenIn`) configurée dans le builder : ```csharp showLineNumbers title="Unity" public void FlowViewDidPerformAction( AdaptyUIFlowView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.OpenUrl: var urlString = action.Value; if (!string.IsNullOrWhiteSpace(urlString)) { AdaptyUI.OpenUrl( urlString, action.OpenIn ?? AdaptyWebPresentation.ExternalBrowser, (error) => { // handle the error } ); } break; default: // handle other events break; } } ``` ## Se connecter à l'application \{#log-into-the-app\} Pour ajouter un bouton qui connecte les utilisateurs à votre application : 1. Dans le builder, ajoutez un bouton et assignez-lui l'action **Custom** avec l'ID `login`. 2. Dans le code de votre application, implémentez un gestionnaire pour l'action personnalisée `login` qui identifie votre utilisateur. ```csharp showLineNumbers title="Unity" public void FlowViewDidPerformAction( AdaptyUIFlowView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Custom: if (action.Value == "login") { // Navigate to login scene SceneManager.LoadScene("LoginScene"); } break; default: // handle other events break; } } ``` ## Gérer les actions personnalisées \{#handle-custom-actions\} Pour ajouter un bouton qui gère d'autres actions : 1. Dans le builder, ajoutez un bouton, assignez-lui l'action **Custom** et donnez-lui un identifiant. 2. Dans le code de votre application, implémentez un gestionnaire pour l'identifiant d'action que vous avez créé. Par exemple, si vous avez d'autres offres d'abonnement ou achats uniques, vous pouvez ajouter un bouton qui affichera un autre flow ou paywall : ```csharp showLineNumbers title="Unity" public void FlowViewDidPerformAction( AdaptyUIFlowView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Custom: if (action.Value == "openNewFlow") { // Display another flow or paywall ShowAlternativeFlow(); } break; default: // handle other events break; } } private void ShowAlternativeFlow() { // Implement your logic to show an alternative flow } ``` Si vous créez des paywalls avec le Paywall Builder d'Adapty, il est essentiel de configurer correctement les boutons : 1. Ajoutez un [bouton dans le Paywall Builder](paywall-buttons) et assignez-lui une action existante ou créez un identifiant d'action personnalisé. 2. Écrivez le code dans votre application pour gérer chaque action assignée. Ce guide explique comment gérer les actions personnalisées et les actions existantes dans votre code. :::warning **Seuls les achats et les restaurations sont gérés automatiquement.** Toutes les autres actions de bouton, comme la fermeture des paywalls ou l'ouverture de liens, nécessitent une implémentation des réponses appropriées dans le code de l'application. ::: ## Fermer les paywalls \{#close-paywalls\} Pour ajouter un bouton permettant de fermer votre paywall : 1. Dans le Paywall Builder, ajoutez un bouton et assignez-lui l'action **Close**. 2. Dans le code de votre application, implémentez un gestionnaire pour l'action `close` qui ferme le paywall. ```csharp showLineNumbers title="Unity" public void PaywallViewDidPerformAction( AdaptyUIPaywallView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Close: view.Dismiss(null); break; default: // handle other events break; } } ``` ## Ouvrir des URL depuis les paywalls \{#open-urls-from-paywalls\} :::tip Si vous souhaitez ajouter un groupe de liens (par exemple, conditions d'utilisation et restauration des achats), ajoutez un élément **Link** dans le Paywall Builder et traitez-le de la même manière que les boutons avec l'action **Open URL**. ::: Pour ajouter un bouton qui ouvre un lien depuis votre paywall (par exemple, **Terms of use** ou **Privacy policy**) : 1. Dans le Paywall Builder, ajoutez un bouton, assignez-lui l'action **Open URL** et saisissez l'URL à ouvrir. 2. Dans le code de votre application, implémentez un gestionnaire pour l'action `openUrl` qui ouvre l'URL reçue dans un navigateur. ```csharp showLineNumbers title="Unity" public void PaywallViewDidPerformAction( AdaptyUIPaywallView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.OpenUrl: var urlString = action.Value; if(!string.IsNullOrWhiteSpace(urlString)) { Application.OpenURL(urlString); } break; default: // handle other events break; } } ``` ## Se connecter à l'application \{#log-into-the-app\} Pour ajouter un bouton permettant aux utilisateurs de se connecter à votre application : 1. Dans le Paywall Builder, ajoutez un bouton et assignez-lui l'action **Custom** avec l'ID `login`. 2. Dans le code de votre application, implémentez un gestionnaire pour l'action personnalisée `login` qui identifie votre utilisateur. ```csharp showLineNumbers title="Unity" public void PaywallViewDidPerformAction( AdaptyUIPaywallView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Custom: if (action.Value == "login") { // Navigate to login scene SceneManager.LoadScene("LoginScene"); } break; default: // handle other events break; } } ``` ## Gérer les actions personnalisées \{#handle-custom-actions\} Pour ajouter un bouton qui gère d'autres actions : 1. Dans le Paywall Builder, ajoutez un bouton, attribuez-lui l'action **Custom** et un identifiant. 2. Dans le code de votre application, implémentez un gestionnaire pour l'identifiant d'action que vous avez créé. Par exemple, si vous proposez un autre ensemble d'offres d'abonnement ou d'achats uniques, vous pouvez ajouter un bouton qui affichera un autre paywall : ```csharp showLineNumbers title="Unity" public void PaywallViewDidPerformAction( AdaptyUIPaywallView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Custom: if (action.Value == "openNewPaywall") { // Display another paywall ShowAlternativePaywall(); } break; default: // handle other events break; } } private void ShowAlternativePaywall() { // Implement your logic to show alternative paywall } ``` --- # File: unity-handling-events --- --- title: "Gérer les événements de flow et de paywall - Unity" description: "Gérez les événements de flow et de paywall dans votre application Unity." --- :::important Ce guide couvre la gestion des événements pour les achats, les restaurations, la sélection de produits et le rendu des flows. Vous devez également implémenter la gestion des boutons (fermeture du flow, ouverture de liens, etc.). Consultez notre [guide sur la gestion des actions de flow](unity-handle-paywall-actions) pour plus de détails. ::: Les flows et paywalls configurés avec le [Flow Builder](adapty-flow-builder) ou le [Paywall Builder](adapty-paywall-builder) n'ont pas besoin de code supplémentaire pour effectuer et restaurer des achats. Cependant, ils génèrent certains événements auxquels votre application peut réagir. Ces événements comprennent les pressions sur des boutons (boutons de fermeture, URLs, sélections de produits, etc.) ainsi que des notifications sur les actions liées aux achats. Découvrez ci-dessous comment réagir à ces événements. :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. ::: ## Gestion des événements \{#handling-events\} Pour contrôler ou surveiller les processus qui se déroulent sur l'écran du flow dans votre application mobile, implémentez l'interface `IAdaptyFlowsEventsListener` et enregistrez-la avec `Adapty.SetFlowsEventsListener()` : ```csharp showLineNumbers title="Unity" using UnityEngine; using AdaptySDK; public class FlowEventsHandler : MonoBehaviour, IAdaptyFlowsEventsListener { void Start() { Adapty.SetFlowsEventsListener(this); } // Implement all interface methods below } ``` :::note Ces méthodes sont l'endroit où vous ajoutez votre logique personnalisée pour répondre aux événements du flow. Le SDK n'applique aucun comportement par défaut : un achat réussi ou une erreur ne ferme pas la vue automatiquement — appelez `view.Dismiss(...)` vous-même au moment opportun. ::: ### Événements générés par l'utilisateur \{#user-generated-events\} #### Flow apparu \{#flow-appeared\} Invoqué lorsque la vue du flow s'affiche à l'écran. :::note Sur iOS, également invoqué lorsqu'un utilisateur appuie sur le [bouton de paywall web](web-paywall#step-2a-add-a-web-purchase-button) dans un flow, et qu'un paywall web s'ouvre dans un navigateur intégré. ::: ```csharp showLineNumbers title="Unity" public void FlowViewDidAppear(AdaptyUIFlowView view) { } ``` #### Flow disparu \{#flow-disappeared\} Invoqué lorsque la vue du flow est fermée depuis l'écran. :::note Sur iOS, également invoqué lorsqu'un [paywall web](web-paywall#step-2a-add-a-web-purchase-button) ouvert depuis un flow dans un navigateur intégré disparaît de l'écran. ::: ```csharp showLineNumbers title="Unity" public void FlowViewDidDisappear(AdaptyUIFlowView view) { } ``` #### Sélection de produit \{#product-selection\} Invoqué lorsqu'un produit est sélectionné pour achat (par l'utilisateur ou par le système). ```csharp showLineNumbers title="Unity" public void FlowViewDidSelectProduct( AdaptyUIFlowView view, string productId ) { } ```
Exemple d'événement (cliquer pour développer) ```javascript { "productId": "premium_monthly" } ```
#### Achat démarré \{#started-purchase\} Invoqué lorsqu'un utilisateur lance le processus d'achat. ```csharp showLineNumbers title="Unity" public void FlowViewDidStartPurchase( AdaptyUIFlowView view, AdaptyPaywallProduct product ) { } ``` :::note En [mode Observer](unity-present-flows-in-observer-mode), les achats démarrés depuis un flow sont transmis à votre `IAdaptyUIObserverModeResolver` à la place. :::
Exemple d'événement (Cliquer pour développer) ```javascript { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } ```
#### Achat réussi, annulé ou en attente \{#successful-canceled-or-pending-purchase\} Si l'achat réussit, que l'utilisateur annule son achat, ou que l'achat est en attente, cette méthode sera invoquée. Les annulations de l'utilisateur et les paiements en attente (par exemple, approbation parentale requise) déclenchent cette méthode, et non `FlowViewDidFailPurchase`. Le flow reste ouvert après l'achat jusqu'à ce que vous le fermiez vous-même, alors appelez `view.Dismiss(...)` dès que l'utilisateur obtient l'accès : ```csharp showLineNumbers title="Unity" public void FlowViewDidFinishPurchase( AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyPurchaseResult purchasedResult ) { switch (purchasedResult.Type) { case AdaptyPurchaseResultType.Success: // Check if user has access to premium features if (purchasedResult.Profile != null && purchasedResult.Profile.AccessLevels.TryGetValue("premium", out var premium) && premium.IsActive) { view.Dismiss(null); } break; case AdaptyPurchaseResultType.Pending: // Handle pending purchase (e.g., user will pay offline with cash) break; case AdaptyPurchaseResultType.UserCancelled: // Handle user cancellation break; default: break; } } ```
Exemples d'événements (cliquez pour développer) ```javascript // Successful purchase { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "purchaseResult": { "type": "Success", "profile": { "accessLevels": { "premium": { "id": "premium", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } } } } } // Cancelled purchase { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "purchaseResult": { "type": "UserCancelled" } } // Pending purchase { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "purchaseResult": { "type": "Pending" } } ```
Nous recommandons de fermer l'écran du flow en cas d'achat réussi. #### Échec d'achat \{#failed-purchase\} Si un achat échoue en raison d'une erreur, cette méthode sera appelée. Cela inclut les erreurs StoreKit/Google Play Billing (restrictions de paiement, produits invalides, échecs réseau), les échecs de vérification de transaction et les erreurs système. Notez que les annulations par l'utilisateur déclenchent `FlowViewDidFinishPurchase` avec un résultat annulé, et les paiements en attente ne déclenchent pas cette méthode. ```csharp showLineNumbers title="Unity" public void FlowViewDidFailPurchase( AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyError error ) { } ```
Exemple d'événement (Cliquez pour développer) ```javascript { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "error": { "code": "purchase_failed", "message": "Purchase failed due to insufficient funds", "details": { "underlyingError": "Insufficient funds in account" } } } ```
#### Restauration démarrée \{#started-restore\} Déclenché lorsqu'un utilisateur lance le processus de restauration : ```csharp showLineNumbers title="Unity" public void FlowViewDidStartRestore(AdaptyUIFlowView view) { } ``` #### Restauration réussie \{#successful-restore\} Appelé lorsque la restauration des achats réussit. Le flow reste ouvert après la restauration jusqu'à ce que vous le fermiez : ```csharp showLineNumbers title="Unity" public void FlowViewDidFinishRestore( AdaptyUIFlowView view, AdaptyProfile profile ) { // Check if user has access to premium features if (profile.AccessLevels.TryGetValue("premium", out var premium) && premium.IsActive) { view.Dismiss(null); } } ```
Exemple d'événement (cliquer pour développer) ```javascript { "profile": { "accessLevels": { "premium": { "id": "premium", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } }, "subscriptions": [ { "vendorProductId": "premium_monthly", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } ] } } ```
Nous recommandons de fermer l'écran si l'utilisateur possède le `accessLevel` requis. Consultez la rubrique [Statut de l'abonnement](unity-listen-subscription-changes) pour savoir comment le vérifier. #### Échec de la restauration \{#failed-restore\} Invoqué lorsque la restauration des achats échoue : ```csharp showLineNumbers title="Unity" public void FlowViewDidFailRestore( AdaptyUIFlowView view, AdaptyError error ) { } ```
Exemple d'événement (Cliquez pour développer) ```javascript { "error": { "code": "restore_failed", "message": "Purchase restoration failed", "details": { "underlyingError": "No previous purchases found" } } } ```
#### Navigation de paiement web terminée \{#finished-web-payment-navigation\} Après une tentative d'ouverture d'un [paywall web](web-paywall) pour un achat (qu'elle ait réussi ou échoué), cette méthode sera invoquée : ```csharp showLineNumbers title="Unity" public void FlowViewDidFinishWebPaymentNavigation( AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyError error ) { } ``` **Paramètres :** - `product` : Le produit pour lequel le paywall web a été ouvert (ou tenté), ou `null` - `error` : `null` si le paywall web s'est ouvert avec succès, ou un `AdaptyError` en cas d'échec
Exemples d'événements (Cliquez pour développer) ```javascript // Successful navigation { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "error": null } // Failed navigation { "product": null, "error": { "code": "wrong_param", "message": "Current method is not available for this product", "details": { "underlyingError": "Product not configured for web purchases" } } } ```
### Récupération et rendu des données \{#data-fetching-and-rendering\} #### Erreurs de chargement des produits \{#product-loading-errors\} Déclenché quand le chargement des produits échoue et fournit une `AdaptyError`. Si vous n'avez pas passé le tableau de produits lors de l'initialisation, AdaptyUI récupérera lui-même les objets nécessaires auprès du serveur. Cette opération peut échouer, et AdaptyUI signalera l'erreur en appelant cette méthode : ```csharp showLineNumbers title="Unity" public void FlowViewDidFailLoadingProducts( AdaptyUIFlowView view, AdaptyError error ) { } ```
Exemple d'événement (Cliquer pour agrandir) ```javascript { "error": { "code": "products_loading_failed", "message": "Failed to load products from the server", "details": { "underlyingError": "Network timeout" } } } ```
#### Erreurs de rendu et d'exécution \{#rendering-and-runtime-errors\} Si une erreur survient lors du rendu de l'interface, ou qu'une autre erreur d'exécution non liée à un achat se produit, elle sera signalée par cette méthode. La vue n'est pas fermée automatiquement — appelez `view.Dismiss(...)` vous-même si nécessaire : ```csharp showLineNumbers title="Unity" public void FlowViewDidReceiveError( AdaptyUIFlowView view, AdaptyError error ) { } ```
Exemple d'événement (Cliquez pour développer) ```javascript { "error": { "code": "rendering_failed", "message": "Failed to render flow interface", "details": { "underlyingError": "Invalid flow configuration" } } } ```
En situation normale, ces erreurs ne devraient pas se produire. Si vous en rencontrez une, merci de nous en informer. #### Événements analytiques \{#analytics-events\} `FlowViewDidReceiveAnalyticEvent` est réservé aux événements analytiques personnalisés provenant d'un flow. Les flows n'émettent pas encore ces événements vers votre code, donc laissez le corps de la méthode vide — `IAdaptyFlowsEventsListener` est une interface C#, la méthode doit tout de même être présente : ```csharp showLineNumbers title="Unity" public void FlowViewDidReceiveAnalyticEvent( AdaptyUIFlowView view, string name, IDictionary @params ) { } ``` ### Gérer les requêtes système \{#handle-system-requests\} Le `IAdaptyUISystemRequestsHandler` (enregistré via `Adapty.SetSystemRequestsHandler(...)`) est réservé aux requêtes système provenant d'un flow : invites de permission OS (comme les notifications push ou l'accès à la caméra) et demandes d'évaluation de l'application. Les flows ne déclenchent pas encore ces requêtes, vous n'avez donc pas besoin d'enregistrer un handler. ### Navigation \{#navigation\} #### Bouton retour système Android \{#android-system-back-button\} Le bouton retour système Android (ou le geste de retour) est transmis à `FlowViewDidPerformAction` sous forme d'action `SystemBack` et ne ferme pas le flow par lui-même — l'utilisateur quitte le flow via un chemin que vous définissez, comme un bouton **Close** ou une action `on_device_back` dans le builder. Si vous souhaitez que le bouton retour système ferme le flow, gérez l'action vous-même : ```csharp showLineNumbers title="Unity" public void FlowViewDidPerformAction( AdaptyUIFlowView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Close: case AdaptyUIUserActionType.SystemBack: view.Dismiss(null); break; default: // handle other events break; } } ``` Consultez le [guide sur la gestion des actions de flow](unity-handle-paywall-actions) pour la liste complète des actions.
:::important Ce guide couvre la gestion des événements liés aux achats, aux restaurations, à la sélection de produits et au rendu des paywalls. Vous devez également implémenter la gestion des boutons (fermeture du paywall, ouverture de liens, etc.). Consultez notre [guide sur la gestion des actions de boutons](unity-handle-paywall-actions) pour plus de détails. ::: Les paywalls configurés avec le [Paywall Builder](adapty-paywall-builder) n'ont pas besoin de code supplémentaire pour effectuer et restaurer des achats. Cependant, ils génèrent des événements auxquels votre application peut réagir. Ces événements incluent les appuis sur des boutons (boutons de fermeture, URL, sélections de produits, etc.) ainsi que des notifications sur les actions liées aux achats effectuées sur le paywall. Découvrez ci-dessous comment réagir à ces événements. :::warning Ce guide s'adresse uniquement aux paywalls du **nouveau Paywall Builder**, qui nécessitent le SDK Adapty v3.3.0 ou ultérieur. ::: :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. ::: ## Gestion des événements \{#handling-events\} Pour contrôler ou surveiller les processus qui se déroulent sur l'écran du paywall dans votre application mobile, implémentez l'interface `AdaptyPaywallsEventsListener` : ```csharp showLineNumbers title="Unity" using UnityEngine; using AdaptySDK; public class PaywallEventsHandler : MonoBehaviour, AdaptyPaywallsEventsListener { void Start() { Adapty.SetPaywallsEventsListener(this); } // Implement all required interface methods below } ``` ### Événements générés par l'utilisateur \{#user-generated-events\} #### Paywall apparu \{#paywall-appeared\} Déclenché lorsque la vue du paywall s'affiche à l'écran. :::note Sur iOS, également déclenché lorsqu'un utilisateur appuie sur le [bouton de paywall web](web-paywall#step-2a-add-a-web-purchase-button) à l'intérieur d'un paywall, et qu'un paywall web s'ouvre dans un navigateur intégré à l'application. ::: ```csharp showLineNumbers title="Unity" public void PaywallViewDidAppear(AdaptyUIPaywallView view) { } ``` #### Paywall disparu \{#paywall-disappeared\} Déclenché lorsque la vue du paywall est fermée et disparaît de l'écran. :::note Sur iOS, également invoqué lorsqu'un [web paywall](web-paywall#step-2a-add-a-web-purchase-button) ouvert depuis un paywall dans un navigateur intégré disparaît de l'écran. ::: ```csharp showLineNumbers title="Unity" public void PaywallViewDidDisappear(AdaptyUIPaywallView view) { } ``` #### Sélection de produit \{#product-selection\} Invoqué lorsqu'un produit est sélectionné pour achat (par l'utilisateur ou par le système). ```csharp showLineNumbers title="Unity" public void PaywallViewDidSelectProduct( AdaptyUIPaywallView view, string productId ) { } ```
Exemple d'événement (Cliquer pour développer) ```javascript { "productId": "premium_monthly" } ```
#### Achat démarré \{#started-purchase\} Invoqué lorsqu'un utilisateur lance le processus d'achat. ```csharp showLineNumbers title="Unity" public void PaywallViewDidStartPurchase( AdaptyUIPaywallView view, AdaptyPaywallProduct product ) { } ```
Exemple d'événement (Cliquez pour développer) ```javascript { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } ```
#### Achat réussi, annulé ou en attente \{#successful-canceled-or-pending-purchase\} Si l'achat réussit, si l'utilisateur l'annule, ou si l'achat est en attente, cette méthode sera invoquée. Les annulations par l'utilisateur et les paiements en attente (par exemple, approbation parentale requise) déclenchent cette méthode, et non `PaywallViewDidFailPurchase`. ```csharp showLineNumbers title="Unity" public void PaywallViewDidFinishPurchase( AdaptyUIPaywallView view, AdaptyPaywallProduct product, AdaptyPurchaseResult purchasedResult ) { } ```
Exemples d'événements (cliquez pour développer) ```javascript // Successful purchase { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "purchaseResult": { "type": "Success", "profile": { "accessLevels": { "premium": { "id": "premium", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } } } } } // Cancelled purchase { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "purchaseResult": { "type": "UserCancelled" } } // Pending purchase { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "purchaseResult": { "type": "Pending" } } ```
Nous vous recommandons de fermer l'écran dans ce cas. #### Échec d'achat \{#failed-purchase\} Si un achat échoue en raison d'une erreur, cette méthode sera invoquée. Cela inclut les erreurs StoreKit/Google Play Billing (restrictions de paiement, produits invalides, échecs réseau), les échecs de vérification des transactions et les erreurs système. Notez que les annulations de l'utilisateur déclenchent `PaywallViewDidFinishPurchase` avec un résultat annulé, et les paiements en attente ne déclenchent pas cette méthode. ```csharp showLineNumbers title="Unity" public void PaywallViewDidFailPurchase( AdaptyUIPaywallView view, AdaptyPaywallProduct product, AdaptyError error ) { } ```
Exemple d'événement (Cliquez pour développer) ```javascript { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "error": { "code": "purchase_failed", "message": "Purchase failed due to insufficient funds", "details": { "underlyingError": "Insufficient funds in account" } } } ```
#### Restauration démarrée \{#started-restore\} Déclenché lorsqu'un utilisateur lance le processus de restauration : ```csharp showLineNumbers title="Unity" public void PaywallViewDidStartRestore(AdaptyUIPaywallView view) { } ``` #### Restauration réussie \{#successful-restore\} Invoqué lorsque la restauration des achats réussit : ```csharp showLineNumbers title="Unity" public void PaywallViewDidFinishRestore( AdaptyUIPaywallView view, AdaptyProfile profile ) { } ```
Exemple d'événement (Cliquez pour développer) ```javascript { "profile": { "accessLevels": { "premium": { "id": "premium", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } }, "subscriptions": [ { "vendorProductId": "premium_monthly", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } ] } } ```
Nous vous recommandons de fermer l'écran si l'utilisateur possède le `accessLevel` requis. Consultez la rubrique [Statut de l'abonnement](unity-listen-subscription-changes) pour savoir comment le vérifier. #### Échec de la restauration \{#failed-restore\} Déclenché en cas d'échec de la restauration des achats : ```csharp showLineNumbers title="Unity" public void PaywallViewDidFailRestore( AdaptyUIPaywallView view, AdaptyError error ) { } ```
Exemple d'événement (cliquer pour développer) ```javascript { "error": { "code": "restore_failed", "message": "Purchase restoration failed", "details": { "underlyingError": "No previous purchases found" } } } ```
#### Navigation web de paiement terminée \{#finished-web-payment-navigation\} Après avoir tenté d'ouvrir un [paywall web](web-paywall) pour un achat (qu'il ait réussi ou échoué), cette méthode sera invoquée : ```csharp showLineNumbers title="Unity" public void PaywallViewDidFinishWebPaymentNavigation( AdaptyUIPaywallView view, AdaptyPaywallProduct product, AdaptyError error ) { } ``` **Paramètres :** - `product` : Le produit pour lequel le paywall web a été ouvert (ou tenté) - `error` : `null` si le paywall web s'est ouvert avec succès, ou une `AdaptyError` en cas d'échec
Exemples d'événements (Cliquez pour développer) ```javascript // Successful navigation { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "error": null } // Failed navigation { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "error": { "code": "wrong_param", "message": "Current method is not available for this product", "details": { "underlyingError": "Product not configured for web purchases" } } } ```
### Récupération et rendu des données \{#data-fetching-and-rendering\} #### Erreurs de chargement des produits \{#product-loading-errors\} Déclenché quand le chargement des produits échoue et fournit une `AdaptyError`. Si vous n'avez pas transmis le tableau de produits lors de l'initialisation, AdaptyUI récupèrera lui-même les objets nécessaires depuis le serveur. Cette opération peut échouer, et AdaptyUI signalera l'erreur en invoquant cette méthode : ```csharp showLineNumbers title="Unity" public void PaywallViewDidFailLoadingProducts( AdaptyUIPaywallView view, AdaptyError error ) { } ```
Exemple d'événement (Cliquez pour développer) ```javascript { "error": { "code": "products_loading_failed", "message": "Failed to load products from the server", "details": { "underlyingError": "Network timeout" } } } ```
#### Erreurs de rendu \{#rendering-errors\} Invoqué lorsqu'une erreur survient pendant le rendu de l'interface et fournit `AdaptyError` : ```csharp showLineNumbers title="Unity" public void PaywallViewDidFailRendering( AdaptyUIPaywallView view, AdaptyError error ) { } ```
Exemple d'événement (Cliquez pour développer) ```javascript { "error": { "code": "rendering_failed", "message": "Failed to render paywall interface", "details": { "underlyingError": "Invalid paywall configuration" } } } ```
Dans une situation normale, de telles erreurs ne devraient pas se produire, donc si vous en rencontrez une, veuillez nous en informer.
--- # File: unity-web-paywalls --- --- title: "Implémenter des paywalls web dans le SDK Unity" description: "Configurez un paywall web pour être payé sans les frais et audits de l'App Store." --- :::important Avant de commencer, assurez-vous d'avoir [configuré votre paywall web dans le tableau de bord](web-paywall) et d'avoir installé le SDK Adapty version 3.14 ou ultérieure. ::: ## Paywalls web ouverts \{#open-web-paywalls\} Si vous travaillez avec un paywall que vous avez développé vous-même, vous devez gérer les paywalls web via la méthode du SDK. La méthode `Adapty.OpenWebPaywall` : 1. Génère une URL unique permettant à Adapty de relier un paywall spécifique affiché à un utilisateur donné à la page web vers laquelle il est redirigé. 2. Détecte quand vos utilisateurs reviennent dans l'application, puis appelle `Adapty.GetProfile` à intervalles courts pour déterminer si les droits d'accès du profil ont été mis à jour. Ainsi, si le paiement a réussi et que les droits d'accès ont été mis à jour, l'abonnement s'active dans l'application presque immédiatement. ```csharp showLineNumbers title="Unity" Adapty.OpenWebPaywall( product, AdaptyWebPresentation.ExternalBrowser, (error) => { if (error != null) { Debug.LogError($"Failed to open web paywall: {error.Message}"); } else { Debug.Log("Web paywall opened successfully"); } } ); ``` :::note Il existe deux versions de la méthode `OpenWebPaywall` : 1. `OpenWebPaywall(product)` qui génère des URLs à partir du paywall et y ajoute les données du produit. 2. `OpenWebPaywall(paywall)` qui génère des URLs à partir du paywall sans ajouter les données du produit. Utilisez-la lorsque vos produits dans le paywall Adapty diffèrent de ceux du paywall web. Dans le SDK v4, l'argument `paywall` prend un `AdaptyFlowPaywall` — l'une des variations de paywall dans `flow.Paywalls`. Consultez le [guide de migration](migration-to-unity-sdk-v4). ::: #### Gérer les erreurs \{#handle-errors\} | Code d'erreur | Description | Action recommandée | |-----------|--------------------------------------------------------|---------------------------------------------------------------------------| | `AdaptyErrorCode.WrongParam` | Le paywall ou le produit ne dispose pas d'une URL d'achat web configurée, ou l'ouverture de l'URL dans le navigateur a échoué | Consultez le message d'erreur pour plus de détails. Vérifiez la configuration du paywall/produit dans l'Adapty Dashboard, ou vérifiez les paramètres de l'appareil. | | `AdaptyErrorCode.DecodingFailed` | Échec de l'encodage correct des paramètres dans l'URL | Vérifiez que les paramètres d'URL sont valides et correctement formatés | :::note Vérifiez la propriété `Message` de l'erreur pour obtenir des détails sur ce qui s'est mal passé, car `WrongParam` peut indiquer plusieurs problèmes (URL d'achat manquante, échec de l'ouverture du navigateur, etc.). ::: ## Ouvrir les paywalls web dans un navigateur intégré \{#open-web-paywalls-in-an-in-app-browser\} :::important L'ouverture des paywalls web dans un navigateur intégré est prise en charge à partir du SDK Adapty v3.15. ::: Par défaut, les paywalls web s'ouvrent dans le navigateur externe, ce qui fait quitter l'application à l'utilisateur. Pour offrir une expérience fluide, vous pouvez ouvrir les paywalls web dans un navigateur intégré. La page d'achat web s'affiche alors directement dans votre application, permettant aux utilisateurs de finaliser leurs transactions sans changer d'app. Pour activer cette option, passez `AdaptyWebPresentation.InAppBrowser` à la méthode `OpenWebPaywall` : ```csharp showLineNumbers title="Unity" Adapty.OpenWebPaywall( product, AdaptyWebPresentation.InAppBrowser, // default — ExternalBrowser (error) => { if (error != null) { Debug.LogError($"Failed to open web paywall: {error.Message}"); } else { Debug.Log("Web paywall opened successfully"); } } ); ``` --- # File: unity-use-fallback-paywalls --- --- title: "Unity - Use fallback paywalls" description: "Handle cases when users are offline or Adapty servers aren't available" --- :::warning Les paywalls de secours sont pris en charge par le SDK Unity v2.11 et versions ultérieures. ::: To maintain a fluid user experience, it is important to set up [fallbacks](/fallback-paywalls) for your flows, [paywalls](paywalls), and [onboardings](onboardings). This precaution extends the application's capabilities in case of partial or complete loss of internet connection. * **If the application cannot access Adapty servers:** It will be able to display a fallback flow or paywall, and access the local onboarding configuration. * **If the application cannot access the internet:** It will be able to display a fallback flow or paywall. Onboardings include remote content and require an internet connection to function. :::important Before you follow the steps in this guide, [download](/local-fallback-paywalls) the fallback configuration files from Adapty. ::: ## Configuration \{#configuration\} 1. Ajoutez les fichiers de configuration de secours dans le répertoire commun `Assets/StreamingAssets` de votre projet. 2. Appelez la méthode `.SetFallback` **avant** de récupérer le flow, le paywall ou l'onboarding cible. ```csharp using UnityEngine; using AdaptySDK; #if UNITY_IOS string fileName = "ios_fallback.json"; #elif UNITY_ANDROID string fileName = "android_fallback.json"; #else // Optional: handle Editor or other platforms string fileName = "fallback.json"; #endif Adapty.SetFallback(fileName, (error) => { if (error != null) { Debug.LogError($"Failed to set fallback: {error}"); return; } // Fallback set successfully }); ``` :::important `SetFallback` doit être exécuté avant que le SDK récupère le flow, le paywall ou l'onboarding cible. ::: Paramètres : | Paramètre | Description | |:-------------|:-----------------------------------------------------| | **fileName** | La chaîne contenant le nom du fichier de configuration de secours. | --- # File: unity-localizations-and-locale-codes --- --- title: "Utiliser les localisations et les codes de langue dans le SDK Unity" description: "Découvrez comment localiser les paywalls dans votre application Unity avec le SDK Adapty." --- ## Pourquoi c'est important \{#why-this-is-important\} Les codes de langue entrent en jeu lorsqu'Adapty sélectionne la localisation pour un flow ou un onboarding, et lorsque vous lisez un Remote Config pour un paywall personnalisé. Les codes de langue sont complexes et peuvent varier d'une plateforme à l'autre. C'est pourquoi Adapty s'appuie sur un standard interne unique pour toutes les plateformes qu'il prend en charge. Comprendre ce standard vous permet de prédire quelle localisation sera reçue par un utilisateur. ## Standard des codes de langue chez Adapty \{#locale-code-standard-at-adapty\} Pour les codes de langue, Adapty utilise une version légèrement modifiée du [standard BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) : chaque code est composé de sous-balises en minuscules, séparées par des tirets. Quelques exemples : `en` (anglais), `pt-br` (portugais (Brésil)), `zh` (chinois simplifié), `zh-hant` (chinois traditionnel). ## Correspondance des codes de langue \{#locale-code-matching\} Dans le SDK v4, les flows et les onboardings font correspondre les codes de langue différemment : les flows sont localisés par le SDK sur l'appareil, les onboardings par le serveur Adapty. ### Flows et paywalls Paywall Builder Un paywall conçu dans le Paywall Builder est livré sous forme de flow dans le SDK v4, donc la règle ci-dessous couvre les deux. La correspondance est exacte. Le SDK compare le code que vous transmettez avec les codes de localisation du flow caractère par caractère : il ne modifie pas la casse, ne remplace pas les underscores (`_`) par des tirets (`-`), et ne se replie pas sur le sous-tag de langue. Pour un flow avec une localisation `pt-br`, seul `pt-br` correspond : `pt-BR`, `pt_BR` et `pt-PT` ne correspondent pas. Lorsque le code ne correspond à aucune localisation, le flow s'affiche silencieusement dans sa [locale par défaut](add-paywall-locale-in-adapty-paywall-builder#set-the-default-locale) — le SDK ne retourne pas d'erreur et ne journalise pas d'avertissement. Lorsque le code correspond, Adapty fusionne la localisation avec la localisation par défaut : les chaînes et ressources que la localisation correspondante ne définit pas sont héritées de la localisation par défaut. Omettre le code de langue ne revient pas à demander la localisation par défaut du flow : le SDK substitue un `en` fixe. Un flow dont la langue par défaut est `de` s'affiche quand même en `en` s'il dispose d'une localisation `en`, et ne revient à `de` qu'en l'absence de celle-ci. :::warning Passez le code de langue exactement tel qu'il est configuré dans le tableau de bord — sous-balises en minuscules séparées par des tirets. Ne passez pas directement un identifiant de locale système : `CultureInfo.CurrentCulture.Name` retourne `pt-BR`, ce qui entraîne un repli vers la localisation par défaut. Convertissez la valeur dans votre application avant de la transmettre. ::: ### Onboardings Les onboardings sont localisés côté serveur, et les règles du serveur acceptent d'autres formats. Lorsque vous passez un `Locale` à [`GetOnboarding`](unity-get-onboardings) : 1. La chaîne locale est convertie en minuscules et tous les underscores (`_`) sont remplacés par des tirets (`-`) 2. Adapty recherche la localisation dont le code correspond exactement 3. Si aucune correspondance n'est trouvée, Adapty extrait la sous-chaîne avant le premier tiret (`pt` pour `pt-br`) et recherche la localisation correspondante 4. Si aucune correspondance n'est trouvée non plus, Adapty retourne le contenu dans la langue par défaut de l'onboarding Cette approche permet à `pt_BR`, `pt-BR` et `pt-br` de tous correspondre à la même localisation d'onboarding. ## Implémentation des localisations \{#implementing-localizations\} Avec le SDK v4, vous ne transmettez pas de code de langue lors de la récupération d'un flow — le flow est localisé au moment de la création de sa vue. - **Paywalls Flow Builder et Paywall Builder** : le SDK ne lit pas les paramètres régionaux de l'appareil, résolvez-les dans votre application et [transmettez-les lors de la création de la vue](#choose-the-localization-of-a-flow). Le code de locale est facultatif — omettez-le et le flow s'affiche en `en`, ou dans sa locale par défaut si le flow ne possède pas de localisation `en`. - **Paywalls personnalisés (Remote Config)** : `GetFlow` retourne toutes les localisations configurées dans `flow.RemoteConfigs`. Chaque entrée est un `AdaptyRemoteConfig` avec un code `Locale` et un `Dictionary` de valeurs. Sélectionnez l'entrée correspondant à l'utilisateur, avec votre propre fallback : ```csharp showLineNumbers using System.Linq; using AdaptySDK; Adapty.GetFlow("YOUR_PLACEMENT_ID", (flow, error) => { if (error != null) { // handle the error return; } var config = flow.RemoteConfigs.FirstOrDefault(c => c.Locale == "en") ?? flow.RemoteConfigs.FirstOrDefault(); // read your values from config?.Dictionary }); ``` Adapty stocke ces codes `Locale` dans le format décrit dans [Standard de code de locale chez Adapty](#locale-code-standard-at-adapty). Le SDK ne fait pas correspondre les Remote Configs à une locale, c'est donc à votre application de déterminer quelle entrée appliquer. ### Choisir la localisation d'un flow \{#choose-the-localization-of-a-flow\} Pour afficher un flow ou un paywall avec une localisation spécifique, passez le code de langue à `SetLocale` lors de la création de la vue : ```csharp showLineNumbers var parameters = new AdaptyUICreateFlowViewParameters() .SetLocale("pt-br"); AdaptyUI.CreateFlowView(flow, parameters, (view, error) => { if (error != null) { // handle the error return; } // view.Locale — the localization the view was built with }); ``` La vue rapporte la localisation avec laquelle elle a été effectivement construite dans `view.Locale` : celle que vous avez demandée si cette localisation existe, ou la localisation par défaut du flow dans le cas contraire. ## Pourquoi c'est important \{#why-this-is-important\} Les codes de langue entrent en jeu dans plusieurs scénarios — par exemple, quand vous cherchez à récupérer le bon paywall selon la localisation actuelle de votre application. Les codes de langue sont complexes et peuvent varier d'une plateforme à l'autre. Nous nous appuyons donc sur une norme interne pour toutes les plateformes que nous supportons. Cependant, étant donné cette complexité, il est essentiel que vous compreniez exactement ce que vous envoyez à notre serveur pour obtenir la bonne localisation, et ce qui se passe ensuite — afin de toujours recevoir ce que vous attendez. ## Standard des codes de langue chez Adapty \{#locale-code-standard-at-adapty\} Pour les codes de langue, Adapty utilise une version légèrement modifiée du [standard BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) : chaque code est composé de sous-balises en minuscules, séparées par des tirets. Quelques exemples : `en` (anglais), `pt-br` (portugais (Brésil)), `zh` (chinois simplifié), `zh-hant` (chinois traditionnel). ## Correspondance des codes de langue \{#locale-code-matching\} Lorsqu'Adapty reçoit un appel du SDK côté client avec le code de langue et commence à chercher la localisation correspondante d'un paywall, voici ce qui se passe : 1. La chaîne de langue reçue est convertie en minuscules et tous les underscores (`_`) sont remplacés par des tirets (`-`) 2. Nous cherchons ensuite la localisation dont le code de langue correspond exactement 3. Si aucune correspondance n'est trouvée, nous extrayons la sous-chaîne avant le premier tiret (`pt` pour `pt-br`) et cherchons la localisation correspondante 4. Si aucune correspondance n'est encore trouvée, nous renvoyons le contenu dans la langue par défaut du paywall Ainsi, un appareil iOS ayant envoyé `'pt_BR'`, un appareil Android ayant envoyé `pt-BR`, et un autre appareil ayant envoyé `pt-br` obtiendront le même résultat. ## Mise en œuvre des localisations : approche recommandée \{#implementing-localizations-recommended-way\} Si vous vous posez des questions sur les localisations, vous utilisez probablement déjà des fichiers de chaînes localisées dans votre projet. Dans ce cas, nous vous recommandons d'ajouter une paire clé-valeur avec le code de locale Adapty correspondant dans chacun de vos fichiers pour les localisations concernées. Ensuite, récupérez la valeur de cette clé lors de l'appel de notre SDK, comme ceci : ```csharp showLineNumbers // 1. Modify your localization files (e.g., using Unity's Localization package) /* en.json */ { "adapty_paywalls_locale": "en" } /* es.json */ { "adapty_paywalls_locale": "es" } /* pt-BR.json */ { "adapty_paywalls_locale": "pt-br" } // 2. Extract and use the locale code using UnityEngine; using UnityEngine.Localization; using UnityEngine.Localization.Settings; using AdaptySDK; public class PaywallManager : MonoBehaviour { public async void FetchPaywall() { // Get the current locale from Unity's Localization system var locale = LocalizationSettings.SelectedLocale; var localeCode = GetAdaptyLocaleCode(locale); // Pass locale code to Adapty.GetPaywall or Adapty.GetPaywallForDefaultAudience method Adapty.GetPaywall("placement_id", localeCode, (paywall, error) => { if (error != null) { // handle the error return; } // Use the paywall }); } private string GetAdaptyLocaleCode(Locale locale) { // Convert Unity locale to Adapty format var localeIdentifier = locale.Identifier.Code; return localeIdentifier.ToLower().Replace('_', '-'); } } ``` De cette façon, vous pouvez vous assurer de contrôler entièrement quelle localisation sera récupérée pour chaque utilisateur de votre application. ## Implémenter les localisations : l'autre approche \{#implementing-localizations-the-other-way\} Vous pouvez obtenir des résultats similaires (mais pas identiques) sans définir explicitement les codes de locale pour chaque localisation. Il s'agit d'extraire un code de locale depuis d'autres objets fournis par votre plateforme, comme ceci : ```csharp showLineNumbers using UnityEngine; using System.Globalization; using AdaptySDK; public class PaywallManager : MonoBehaviour { public void FetchPaywall() { var localeCode = GetSystemLocaleCode(); // Pass locale code to Adapty.GetPaywall or Adapty.GetPaywallForDefaultAudience method Adapty.GetPaywall("placement_id", localeCode, (paywall, error) => { if (error != null) { // handle the error return; } // Use the paywall }); } private string GetSystemLocaleCode() { // Get the system's current culture var culture = CultureInfo.CurrentCulture; var languageCode = culture.TwoLetterISOLanguageName; var regionCode = culture.Name.Contains('-') ? culture.Name.Split('-')[1] : null; if (!string.IsNullOrEmpty(regionCode)) { return $"{languageCode}-{regionCode.ToLower()}"; } return languageCode; } } ``` Notez que nous déconseillons cette approche pour plusieurs raisons : 1. Sur iOS, les langues préférées et la locale actuelle ne sont pas identiques. Si vous souhaitez que la localisation soit sélectionnée correctement, vous devrez soit vous appuyer sur la logique d'Apple, qui fonctionne telle quelle si vous utilisez l'approche recommandée avec des fichiers de chaînes localisées, soit la recréer vous-même. 2. Il est difficile de prédire ce que le serveur d'Adapty recevra exactement. Par exemple, sur iOS, il est possible d'obtenir une locale comme `ar_OM@numbers='latn'` sur un appareil et de l'envoyer à notre serveur. Pour cet appel, vous obtiendrez non pas la localisation `ar-om` que vous recherchiez, mais plutôt `ar`, ce qui est probablement inattendu. Should you decide to use this approach anyway — make sure you've covered all the relevant use cases. --- # File: unity-present-flows-in-observer-mode --- --- title: "Présenter des flows en mode Observer - Unity" description: "Présentez des flows et des paywalls créés avec le Paywall Builder en mode Observer dans votre application Unity tout en gérant les achats avec votre propre code." --- Si vous avez personnalisé un flow ou un paywall avec le builder, vous n'avez pas à vous soucier de son rendu dans le code de votre application mobile pour l'afficher à l'utilisateur. Un tel flow ou paywall contient à la fois ce qui doit être affiché et comment il doit l'être. :::warning Cette section concerne uniquement le [mode Observateur](observer-vs-full-mode). Si vous ne travaillez pas en mode Observateur, consultez la rubrique [Afficher les flows et paywalls](unity-present-paywalls). ::: :::info Cette fonctionnalité nécessite le SDK Adapty Unity 4.0 (bêta) ou version ultérieure — elle n'était auparavant disponible que dans les SDK natifs iOS et Android. Consultez le [guide de migration](migration-to-unity-sdk-v4) pour effectuer la mise à jour. :::
Avant de commencer à afficher des flows (Cliquez pour développer) 1. Configurez l'intégration initiale d'Adapty [avec l'App Store](initial_ios) et [avec Google Play](initial-android). 2. Installez et configurez le SDK Adapty. Assurez-vous d'appeler `SetObserverMode(true)` sur le builder de configuration. Consultez le [guide d'installation du SDK Unity](sdk-installation-unity#activate-adapty-module-of-adapty-sdk). 3. [Créez des produits](create-product) dans l'Adapty Dashboard. 4. [Configurez des flows ou des paywalls dans les builders](create-paywall) et assignez-leur des produits. 5. [Créez des placements et assignez-leur vos flows ou paywalls](create-placement). 6. [Récupérez les flows et leur configuration](unity-get-pb-paywalls) dans le code de votre application mobile.
En mode Observer, le SDK n'effectue pas les achats à votre place. Lorsqu'un utilisateur appuie sur le bouton d'achat ou de restauration dans un flow ou une paywall rendu par Adapty, le SDK appelle votre `IAdaptyUIObserverModeResolver` à la place — effectuez l'achat ou la restauration avec votre propre code à cet endroit. 1. Implémentez l'interface `IAdaptyUIObserverModeResolver` : ```csharp showLineNumbers using System; using AdaptySDK; public class MyObserverModeResolver : IAdaptyUIObserverModeResolver { public void FlowViewDidInitiatePurchase( AdaptyUIFlowView view, AdaptyPaywallProduct product, Action onStartPurchase, Action onFinishPurchase ) { onStartPurchase(); // the view shows its loading indicator // make the purchase with your own code, // then report the transaction to Adapty and call: onFinishPurchase(); // the view hides the loading indicator } public void FlowViewDidInitiateRestore( AdaptyUIFlowView view, Action onStartRestore, Action onFinishRestore ) { onStartRestore(); // restore purchases with your own code, then: onFinishRestore(); } } ``` Le méthode `FlowViewDidInitiatePurchase` vous informe que l'utilisateur a lancé un achat, et `FlowViewDidInitiateRestore` — que l'utilisateur a lancé une restauration. Déclenchez votre flow d'achat ou de restauration personnalisé en réponse. N'oubliez pas non plus d'invoquer les callbacks suivants pour notifier AdaptyUI de l'avancement de l'achat ou de la restauration. Cela est nécessaire pour un comportement correct du flow, comme l'affichage du chargement, entre autres : | Callback | Description | | :----------------- | :--------------------------------------------------------------------------------------------- | | onStartPurchase() | Ce callback doit être invoqué pour notifier AdaptyUI que l'achat a démarré. | | onFinishPurchase() | Ce callback doit être invoqué pour notifier AdaptyUI que l'achat est terminé. | | onStartRestore() | Ce callback doit être invoqué pour notifier AdaptyUI que la restauration a démarré. | | onFinishRestore() | Ce callback doit être invoqué pour notifier AdaptyUI que la restauration est terminée. | Le flow reste ouvert pendant que votre code s'exécute — fermez-le vous-même après un achat ou une restauration réussie. 2. Enregistrez le resolver avant d'afficher n'importe quel écran : ```csharp showLineNumbers Adapty.SetObserverModeResolver(new MyObserverModeResolver()); ``` Sans resolver enregistré, le flow n'a aucun moyen de transmettre l'achat à votre code, et rien ne se passe quand l'utilisateur appuie sur le bouton d'achat. 3. Créez et présentez le flow comme d'habitude : [récupérez le flow et créez sa vue](unity-get-pb-paywalls), puis [présentez-le](unity-present-paywalls). Aucun paramètre supplémentaire n'est nécessaire — une fois le resolver enregistré, chaque flow ou paywall rendu par Adapty achemine les achats et les restaurations via celui-ci. :::warning N'oubliez pas de [signaler la transaction et de l'associer au paywall](report-transactions-observer-mode-unity). Sinon, Adapty ne reconnaîtra pas la transaction et ne pourra pas déterminer le paywall source de l'achat. ::: --- # File: unity-troubleshoot-paywall-builder --- --- title: "Résoudre les problèmes du Paywall Builder dans le SDK Unity" description: "Résoudre les problèmes du Paywall Builder dans le SDK Unity" --- Ce guide vous aide à résoudre les problèmes courants lors de l'utilisation de paywalls conçus dans le Paywall Builder d'Adapty avec le SDK Unity. ## La récupération de la configuration d'un paywall échoue \{#getting-a-paywall-configuration-fails\} **Problème** : La méthode `CreateView` ne parvient pas à récupérer la configuration du paywall. **Raison** : Le paywall n'est pas activé pour l'affichage sur l'appareil dans le Paywall Builder. **Solution** : Activez le bouton **Show on device** dans le Paywall Builder. ## Le nombre d'affichages du paywall est trop élevé \{#the-paywall-view-number-is-too-big\} **Problème** : Le nombre d'affichages du paywall est deux fois plus élevé que prévu. **Raison** : Vous appelez peut-être `LogShowFlow` (SDK v4+) / `LogShowPaywall` dans votre code, ce qui duplique le compteur d'affichages si vous utilisez le Paywall Builder ou le Flow Builder. Pour les flows et les paywalls créés avec ces outils, l'analyse est suivie automatiquement et vous n'avez pas besoin d'utiliser cette méthode. **Solution** : Vérifiez que vous n'appelez pas `LogShowFlow` (SDK v4+) / `LogShowPaywall` dans votre code si vous utilisez le Paywall Builder ou le Flow Builder. ## Autres problèmes \{#other-issues\} **Problème** : Vous rencontrez d'autres problèmes liés au Paywall Builder qui ne sont pas couverts ci-dessus. **Solution** : Mettez à jour le SDK vers la dernière version en utilisant les [guides de migration](unity-sdk-migration-guides) si nécessaire. De nombreux problèmes sont résolus dans les versions plus récentes du SDK. --- # File: unity-implement-paywalls-manually --- --- title: "Implémenter les paywalls manuellement dans le SDK Unity" description: "Découvrez comment implémenter les paywalls manuellement dans votre application Unity avec le SDK Adapty." --- ## Accepter les achats \{#accept-purchases\} Si vous travaillez avec des paywalls que vous avez implémentés vous-même, vous pouvez déléguer la gestion des achats à Adapty en utilisant la méthode `makePurchase`. Adapty prendra alors en charge tous les scénarios utilisateur, et vous n'aurez qu'à gérer les résultats des achats. :::important `makePurchase` fonctionne avec les produits créés dans l'Adapty Dashboard. Assurez-vous de configurer les produits et les moyens de les récupérer dans le tableau de bord en suivant le [guide de démarrage rapide](quickstart). ::: ## Mode observateur \{#observer-mode\} Si vous souhaitez implémenter votre propre logique de gestion des achats from scratch, tout en bénéficiant des analyses avancées d'Adapty, vous pouvez utiliser le mode observateur. :::important Consultez les limitations du mode observateur [ici](observer-vs-full-mode). ::: --- # File: unity-quickstart-manual --- --- title: "Activer les achats dans votre paywall personnalisé avec le SDK Unity" description: "Intégrez le SDK Adapty dans vos paywalls Unity personnalisés pour activer les achats intégrés." --- Ce guide explique comment intégrer Adapty dans vos paywalls personnalisés. Gardez le contrôle total sur l'implémentation du paywall, tandis que le SDK Adapty récupère les produits, gère les nouveaux achats et restaure les achats précédents. Ce guide utilise les APIs du SDK Adapty Unity v4 (bêta) — si vous utilisez la v3, consultez le [guide de migration](migration-to-unity-sdk-v4) pour les noms de méthodes correspondants. :::important **Ce guide est destiné aux développeurs qui implémentent des paywalls personnalisés.** Si vous souhaitez la solution la plus simple pour activer les achats, utilisez l'[Adapty Flow Builder](unity-quickstart-paywalls). Avec Flow Builder, vous créez des flows dans un éditeur visuel sans code, Adapty gère toute la logique d'achat automatiquement, et vous pouvez tester différents designs sans republier votre application. ::: ## Avant de commencer \{#before-you-start\} ### Configurer les produits \{#set-up-products\} Pour activer les achats intégrés, vous devez comprendre trois concepts clés : - [**Produits**](product) – tout ce que les utilisateurs peuvent acheter (abonnements, consommables, accès à vie) - [**Paywalls**](paywalls) – des configurations qui définissent quels produits proposer. Dans Adapty, les paywalls sont le seul moyen de récupérer des produits, mais cette conception vous permet de modifier les produits, les prix et les offres sans toucher au code de votre application. Dans le SDK v4, les variantes de paywall d'un placement sont portées par un objet **flow** — vous récupérez un flow et interrogez ses produits. - [**Placements**](placements) – où et quand vous affichez les paywalls dans votre application (comme `main`, `onboarding`, `settings`). Vous configurez les paywalls pour les placements dans le tableau de bord, puis vous les demandez par identifiant de placement dans votre code. Cela facilite la mise en place de tests A/B et l'affichage de paywalls différents selon les utilisateurs. Assurez-vous de bien comprendre ces concepts, même si vous utilisez un paywall personnalisé. Ce sont simplement votre façon de gérer les produits que vous vendez dans votre application. Pour mettre en place votre paywall personnalisé, vous devez créer un **paywall** et l'ajouter à un **placement**. Cette configuration vous permet de récupérer vos produits. Pour savoir ce que vous devez faire dans le tableau de bord, suivez le guide de démarrage rapide [ici](quickstart). ### Gérer les utilisateurs \{#manage-users\} Vous pouvez travailler avec ou sans authentification backend de votre côté. Cependant, le SDK gère différemment les utilisateurs anonymes et identifiés. Lisez le [guide de démarrage rapide sur l'identification](unity-quickstart-identify) pour comprendre les spécificités et vous assurer que vous gérez correctement vos utilisateurs. ## Étape 1. Récupérer les produits \{#step-1-get-products\} Pour récupérer les produits de votre paywall personnalisé, vous devez : 1. Obtenir l'objet `flow` en passant l'ID du [placement](placements) à la méthode `GetFlow`. 2. Récupérer le tableau de produits pour ce flow à l'aide de la méthode `GetPaywallProducts`. ```csharp showLineNumbers using AdaptySDK; void LoadPaywall() { Adapty.GetFlow("YOUR_PLACEMENT_ID", (flow, error) => { if (error != null) { // Handle the error return; } Adapty.GetPaywallProducts(flow, (products, productsError) => { if (productsError != null) { // Handle the error return; } // Use products to build your custom paywall UI }); }); } ``` ## Étape 2. Accepter les achats \{#step-2-accept-purchases\} Lorsqu'un utilisateur appuie sur un produit dans votre paywall personnalisé, appelez la méthode `MakePurchase` avec le produit sélectionné. Cette méthode gère le processus d'achat et retourne le profil mis à jour. ```csharp showLineNumbers using AdaptySDK; void PurchaseProduct(AdaptyPaywallProduct product) { Adapty.MakePurchase(product, (result, error) => { if (error != null) { // Handle the error return; } switch (result.Type) { case AdaptyPurchaseResultType.Success: var profile = result.Profile; // Purchase successful, profile updated break; case AdaptyPurchaseResultType.UserCancelled: // User canceled the purchase break; case AdaptyPurchaseResultType.Pending: // Purchase is pending (e.g., user will pay offline with cash) break; } }); } ``` ## Étape 3. Restaurer les achats \{#step-3-restore-purchases\} Les stores exigent que toutes les applications proposant des abonnements offrent un moyen aux utilisateurs de restaurer leurs achats. Appelez la méthode `RestorePurchases` lorsque l'utilisateur appuie sur le bouton de restauration. Cela synchronisera son historique d'achats avec Adapty et renverra le profil mis à jour. ```csharp showLineNumbers using AdaptySDK; void RestorePurchases() { Adapty.RestorePurchases((profile, error) => { if (error != null) { // Handle the error return; } // Restore successful, profile updated }); } ``` ## Étape 4. Vérifier le statut de l'abonnement \{#step-4-check-the-subscription-status\} Après un achat ou une restauration, vérifiez le [niveau d'accès](access-level) de l'utilisateur pour décider d'afficher le paywall ou de débloquer les fonctionnalités payantes. Les méthodes `MakePurchase` et `RestorePurchases` retournent déjà le profil mis à jour ; chaque fois que vous avez besoin du statut actuel ailleurs dans l'application, utilisez la méthode `GetProfile` : ```csharp showLineNumbers using AdaptySDK; void CheckPremiumAccess() { Adapty.GetProfile((profile, error) => { if (error != null) { // Handle the error return; } var hasPremiumAccess = profile.AccessLevels.TryGetValue("premium", out var premium) && premium.IsActive; // Grant access to paid features if hasPremiumAccess is true }); } ``` Pour d'autres façons de vérifier et de surveiller le statut de l'abonnement, notamment en écoutant les mises à jour en temps réel, consultez [Vérifier le statut de l'abonnement](unity-check-subscription-status). ## Prochaines étapes \{#next-steps\} :::tip Des questions ou des problèmes ? Consultez notre [forum d'assistance](https://adapty.featurebase.app/) où vous trouverez des réponses aux questions fréquentes ou pourrez poser les vôtres. Notre équipe et notre communauté sont là pour vous aider ! ::: Votre paywall est prêt à être affiché dans l'application. Testez vos achats dans le [sandbox App Store](test-purchases-in-sandbox) ou dans [Google Play Store](testing-on-android) pour vous assurer que vous pouvez effectuer un achat test depuis le paywall. --- # File: fetch-paywalls-and-products-unity --- --- title: "Récupérer les paywalls et produits pour les paywalls Remote Config dans le SDK Unity" description: "Récupérez les paywalls et produits dans le SDK Unity d'Adapty pour optimiser la monétisation des utilisateurs." --- Avant de présenter la configuration distante et les paywalls personnalisés, vous devez récupérer les informations les concernant. Notez que ce sujet traite de Remote Config et des paywalls personnalisés. Pour obtenir des instructions sur la récupération des flows ou des paywalls personnalisés dans le **Flow Builder** ou le **Paywall Builder**, consultez [Récupérer les flows et paywalls](unity-get-pb-paywalls). :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. :::
Avant de commencer à récupérer les flows et les produits dans votre application mobile (cliquez pour développer) 1. [Créez vos produits](create-product) dans l'Adapty Dashboard. 2. [Créez un flow ou un paywall et intégrez-y les produits](create-paywall) dans l'Adapty Dashboard. 3. [Créez des placements et intégrez votre flow ou paywall dans le placement](create-placement) dans l'Adapty Dashboard. 4. [Installez le SDK Adapty](sdk-installation-unity) dans votre application mobile.
## Récupérer les informations d'un flow \{#fetch-flow-information\} Dans Adapty, un [produit](product) est une combinaison de produits provenant de l'App Store et de Google Play. Ces produits multi-plateformes sont intégrés dans des flows et des paywalls, ce qui vous permet de les présenter dans des placements spécifiques de votre application mobile. Pour afficher les produits, vous devez obtenir un `AdaptyFlow` depuis l'un de vos [placements](placements) à l'aide de la méthode `GetFlow`. :::important **N'encodez pas les identifiants de produits en dur.** Le seul identifiant à coder en dur est l'identifiant du placement. Les flows sont configurés à distance, donc le nombre de produits et les offres disponibles peuvent changer à tout moment. Votre application doit gérer ces changements dynamiquement — si un flow retourne deux produits aujourd'hui et trois demain, affichez-les tous sans modifier le code. ::: ```csharp showLineNumbers Adapty.GetFlow( "YOUR_PLACEMENT_ID", AdaptyPlacementFetchPolicy.Default, TimeSpan.FromSeconds(5), (flow, error) => { if (error != null) { // handle the error return; } // flow - the requested flow } ); ``` | Paramètre | Présence | Description | |---------|--------|-----------| | **placementId** | requis | L'identifiant du [Placement](placements). C'est la valeur que vous avez spécifiée lors de la création d'un placement dans votre Adapty Dashboard. | | **fetchPolicy** | par défaut : `AdaptyPlacementFetchPolicy.Default` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option, car elle garantit que vos utilisateurs reçoivent toujours les données les plus récentes.

Cependant, si vous pensez que vos utilisateurs ont une connexion internet instable, envisagez d'utiliser `AdaptyPlacementFetchPolicy.ReturnCacheDataElseLoad` pour renvoyer les données en cache si elles existent. Dans ce cas, les utilisateurs risquent de ne pas obtenir les toutes dernières données, mais ils bénéficieront de temps de chargement plus rapides, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, il est donc sans risque de l'utiliser pendant la session pour éviter les requêtes réseau.

Notez que le cache reste intact après le redémarrage de l'application et n'est effacé que lors d'une réinstallation ou d'un nettoyage manuel.

Le SDK Adapty stocke les flows et les paywalls sur deux couches : le cache mis à jour régulièrement décrit ci-dessus et les [paywalls de secours](unity-use-fallback-paywalls). Nous utilisons également un CDN pour récupérer les flows et les paywalls plus rapidement, ainsi qu'un serveur de secours indépendant en cas d'inaccessibilité du CDN. Ce système est conçu pour vous garantir en permanence la dernière version de vos flows et paywalls, tout en assurant la fiabilité même lorsque la connexion internet est limitée.

| | **loadTimeout** | par défaut : 5 sec |

Cette valeur limite le délai d'expiration de cette méthode. Si le délai est atteint, les données en cache ou le fallback local sont renvoyés.

Notez que dans de rares cas, cette méthode peut expirer légèrement après la valeur spécifiée dans `loadTimeout`, car l'opération peut comprendre plusieurs requêtes en coulisses.

| Ne codez pas les identifiants de produit en dur ! Puisque les flows sont configurés à distance, les produits disponibles, leur nombre et les offres spéciales (comme les essais gratuits) peuvent changer au fil du temps. Assurez-vous que votre code gère bien ces scénarios. Par exemple, si vous récupérez initialement 2 produits, votre application doit afficher ces 2 produits. Mais si vous en récupérez ensuite 3, votre application doit tous les afficher sans nécessiter de modification du code. La seule chose à coder en dur est l'identifiant du placement. Paramètres de réponse : | Paramètre | Description | | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | | Flow | Un objet `AdaptyFlow` contenant : l'identifiant du flow, les variantes de paywall (`Paywalls` — chacune avec ses propres identifiants de produits), une liste `RemoteConfigs` (une entrée par locale configurée), et plusieurs autres propriétés. Pour récupérer les produits du flow, appelez `GetPaywallProducts(flow)`. | :::note Dans la v4, `GetFlow` n'a pas de paramètre `locale`. Lorsque vous affichez un flow avec `CreateFlowView`, la localisation est résolue automatiquement. Pour les paywalls personnalisés, toutes les localisations disponibles sont retournées ensemble dans `flow.RemoteConfigs` — choisissez la locale correspondant à l'appareil de l'utilisateur ou au paramètre de votre application. Consultez [Localisations et codes de langue](unity-localizations-and-locale-codes) pour plus de détails. ::: ## Récupérer les produits \{#fetch-products\} Une fois que vous avez le flow, vous pouvez récupérer le tableau de produits qui lui correspond : ```csharp showLineNumbers Adapty.GetPaywallProducts(flow, (products, error) => { if (error != null) { // handle the error return; } // products - the requested products array }); ``` Paramètres de la réponse : | Paramètre | Description | | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Products | Liste d'objets `AdaptyPaywallProduct` contenant : identifiant du produit, nom du produit, prix, devise, durée de l'abonnement et plusieurs autres propriétés. | Lors de la mise en œuvre de votre propre design de flow, vous aurez probablement besoin d'accéder à ces propriétés depuis l'objet `AdaptyPaywallProduct`. Les propriétés les plus couramment utilisées sont illustrées ci-dessous. | Propriété | Description | |-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Title** | Pour afficher le titre du produit, utilisez `product.LocalizedTitle`. La localisation se base sur le pays du store sélectionné par l'utilisateur, et non sur la locale de l'appareil. | | **Price** | Pour afficher une version localisée du prix, utilisez `product.Price.LocalizedString`. Cette localisation se base sur les informations de locale de l'appareil. Vous pouvez également accéder au prix sous forme numérique via `product.Price.Amount` — la valeur est fournie dans la devise locale. Pour obtenir le symbole de devise associé, utilisez `product.Price.CurrencySymbol`. | | **Subscription Period** | Pour afficher la période (ex. : semaine, mois, année, etc.), utilisez `product.Subscription?.LocalizedPeriod`. Cette localisation se base sur la locale de l'appareil. Pour récupérer la période d'abonnement par programmation, utilisez `product.Subscription?.Period`. Vous pouvez ensuite accéder à l'enum `Unit` pour obtenir la durée (c'est-à-dire `AdaptySubscriptionPeriodUnit.Day`, `AdaptySubscriptionPeriodUnit.Week`, `AdaptySubscriptionPeriodUnit.Month`, `AdaptySubscriptionPeriodUnit.Year`, ou `AdaptySubscriptionPeriodUnit.Unknown`). La valeur `NumberOfUnits` vous donne le nombre d'unités de période. Par exemple, pour un abonnement trimestriel, vous verrez `AdaptySubscriptionPeriodUnit.Month` dans la propriété `Unit`, et `3` dans la propriété `NumberOfUnits`. | | **Introductory Offer** | Pour afficher un badge ou tout autre indicateur signalant qu'un abonnement contient une offre de lancement, consultez la propriété `product.Subscription?.Offer?.Phases`. Il s'agit d'une liste pouvant contenir jusqu'à deux phases de remise : la phase d'essai gratuit et la phase de prix de lancement. Chaque objet de phase expose les propriétés suivantes :
• `PaymentMode` : un enum avec les valeurs `AdaptyPaymentMode.FreeTrial`, `AdaptyPaymentMode.PayAsYouGo`, `AdaptyPaymentMode.PayUpFront` et `AdaptyPaymentMode.Unknown`. Les essais gratuits correspondent au type `AdaptyPaymentMode.FreeTrial`.
• `Price` : un objet `AdaptyPrice` contenant le prix remisé — utilisez `Price.Amount` pour la valeur numérique et `Price.LocalizedString` pour l'afficher. Pour les essais gratuits, vérifiez que `Price.Amount` vaut `0`.
• `LocalizedNumberOfPeriods` : une chaîne localisée selon la locale de l'appareil décrivant la durée de l'offre. Par exemple, un essai de trois jours affiche `"3 days"` dans ce champ.
• `SubscriptionPeriod` : vous pouvez également obtenir les détails individuels de la période de l'offre avec cette propriété. Son fonctionnement est identique à ce qui est décrit dans la section précédente.
• `LocalizedSubscriptionPeriod` : une période d'abonnement formatée pour la locale de l'utilisateur. | ## Accélérer la récupération des flows avec le flow d'audience par défaut \{#speed-up-flow-fetching-with-default-audience-flow\} En général, les flows sont récupérés presque instantanément, vous n'avez donc pas à vous en préoccuper. Toutefois, si vous avez de nombreuses audiences et placements, et que vos utilisateurs disposent d'une connexion internet faible, la récupération d'un flow peut prendre plus de temps que souhaité. Dans ce cas, vous pouvez afficher un flow par défaut pour garantir une expérience fluide plutôt que de ne rien afficher du tout. Pour remédier à cela, vous pouvez utiliser la méthode `GetFlowForDefaultAudience`, qui récupère le flow du placement spécifié pour l'audience **All Users**. Il est toutefois essentiel de comprendre que l'approche recommandée est de récupérer le flow via la méthode `GetFlow`, comme décrit dans la section [Récupérer les informations du flow](fetch-paywalls-and-products-unity#fetch-flow-information) ci-dessus. :::warning Pourquoi nous recommandons d'utiliser `GetFlow` La méthode `GetFlowForDefaultAudience` présente quelques inconvénients majeurs : - **Problèmes potentiels de compatibilité ascendante** : Si vous devez afficher des flows différents selon les versions de l'application (actuelle et future), vous risquez de rencontrer des difficultés. Vous devrez soit concevoir des flows compatibles avec la version actuelle (héritée), soit accepter que les utilisateurs de cette version puissent avoir des problèmes avec des flows non rendus. - **Perte de ciblage** : Tous les utilisateurs verront le même flow conçu pour l'audience **All Users**, ce qui signifie que vous perdez le ciblage personnalisé (notamment selon les pays, l'attribution marketing ou vos propres attributs personnalisés). Si vous acceptez ces inconvénients pour bénéficier d'une récupération plus rapide du flow, utilisez la méthode `GetFlowForDefaultAudience` comme suit. Sinon, restez sur `GetFlow` décrite [ci-dessus](fetch-paywalls-and-products-unity#fetch-flow-information). ::: ```csharp showLineNumbers Adapty.GetFlowForDefaultAudience( "YOUR_PLACEMENT_ID", AdaptyPlacementFetchPolicy.Default, (flow, error) => { if (error != null) { // handle the error return; } // flow - the requested flow } ); ``` | Paramètre | Présence | Description | |---------|--------|-----------| | **placementId** | requis | L'identifiant du [Placement](placements). C'est la valeur que vous avez indiquée lors de la création d'un placement dans votre Adapty Dashboard. | | **fetchPolicy** | par défaut : `AdaptyPlacementFetchPolicy.Default` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option, car elle garantit que vos utilisateurs reçoivent toujours les données les plus récentes.

Cependant, si vous pensez que vos utilisateurs ont une connexion internet instable, envisagez d'utiliser `AdaptyPlacementFetchPolicy.ReturnCacheDataElseLoad` pour renvoyer les données en cache lorsqu'elles existent. Dans ce cas, les utilisateurs ne disposeront peut-être pas des toutes dernières données, mais les temps de chargement seront plus rapides, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, il est donc sûr de l'utiliser pendant la session pour éviter les requêtes réseau.

Notez que le cache reste intact lors du redémarrage de l'application et n'est effacé que lors de la réinstallation de l'application ou via un nettoyage manuel.

|
Avant de présenter le Remote Config et les paywalls personnalisés, vous devez récupérer les informations les concernant. Notez que ce sujet concerne le Remote Config et les paywalls personnalisés. Pour obtenir des instructions sur la récupération des paywalls pour les paywalls personnalisés avec le Paywall Builder, consultez [Récupérer les paywalls du Paywall Builder et leur configuration](unity-get-pb-paywalls). :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. :::
Avant de commencer à récupérer les paywalls et les produits dans votre application mobile (cliquez pour développer) 1. [Créez vos produits](create-product) dans l'Adapty Dashboard. 2. [Créez un paywall et intégrez les produits dans votre paywall](create-paywall) dans l'Adapty Dashboard. 3. [Créez des placements et intégrez votre paywall dans le placement](create-placement) dans l'Adapty Dashboard. 4. [Installez le SDK Adapty](sdk-installation-unity) dans votre application mobile.
## Récupérer les informations d'un paywall \{#fetch-paywall-information\} Dans Adapty, un [produit](product) est une combinaison de produits issus de l'App Store et de Google Play. Ces produits multiplateformes sont intégrés dans des paywalls, ce qui vous permet de les afficher dans des placements spécifiques de votre application mobile. Pour afficher les produits, vous devez obtenir un [Paywall](paywalls) depuis l'un de vos [placements](placements) avec la méthode `getPaywall`. :::important **N'inscrivez pas les ID produit en dur dans le code.** Le seul ID à coder en dur est l'ID du placement. Les paywalls sont configurés à distance, donc le nombre de produits et les offres disponibles peuvent changer à tout moment. Votre application doit gérer ces changements dynamiquement — si un paywall renvoie deux produits aujourd'hui et trois demain, affichez-les tous sans modifier le code. ::: ```csharp showLineNumbers Adapty.GetPaywall("YOUR_PLACEMENT_ID", "en", (paywall, error) => { if(error != null) { // handle the error return; } // paywall - the resulting object }); ``` | Paramètre | Présence | Description | |---------|--------|-----------| | **placementId** | obligatoire | L'identifiant du [Placement](placements). C'est la valeur que vous avez indiquée lors de la création d'un placement dans votre Adapty Dashboard. | | **locale** |

optionnel

par défaut : `en`

|

L'identifiant de la [localisation du paywall](add-remote-config-locale). Ce paramètre doit être un code de langue composé d'un ou plusieurs sous-tags séparés par le caractère moins (**-**). Le premier sous-tag correspond à la langue, le second à la région.

Exemple : `en` désigne l'anglais, `pt-br` représente le portugais brésilien.

Consultez [Localisations et codes de langue](unity-localizations-and-locale-codes) pour en savoir plus sur les codes de langue et notre approche recommandée.

| | **fetchPolicy** | par défaut : `.reloadRevalidatingCacheData` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option, car elle garantit que vos utilisateurs reçoivent toujours les données les plus récentes.

Toutefois, si vous pensez que vos utilisateurs ont une connexion instable, envisagez d'utiliser `.returnCacheDataElseLoad` pour renvoyer les données en cache si elles existent. Dans ce cas, les utilisateurs ne bénéficieront peut-être pas des toutes dernières données, mais les temps de chargement seront plus rapides, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, il est donc sûr de l'utiliser pendant la session pour éviter les requêtes réseau.

Notez que le cache est conservé lors du redémarrage de l'application et n'est effacé que lors d'une réinstallation ou d'un nettoyage manuel.

Le SDK Adapty stocke les paywalls sur deux couches : le cache mis à jour régulièrement décrit ci-dessus et les [paywalls de secours](unity-use-fallback-paywalls). Nous utilisons également un CDN pour récupérer les paywalls plus rapidement, ainsi qu'un serveur de secours indépendant en cas d'indisponibilité du CDN. Ce système est conçu pour garantir que vous obtenez toujours la dernière version de vos paywalls, tout en assurant la fiabilité même lorsque la connexion internet est limitée.

| | **loadTimeout** | par défaut : 5 sec |

Cette valeur limite le délai d'attente de cette méthode. Si le délai est dépassé, les données en cache ou le fallback local sont renvoyés.

Notez que dans de rares cas, cette méthode peut expirer légèrement après le délai indiqué dans `loadTimeout`, car l'opération peut comprendre différentes requêtes en arrière-plan.

| N'écrivez pas les identifiants de produits en dur ! Puisque les paywalls sont configurés à distance, les produits disponibles, leur nombre et les offres spéciales (comme les essais gratuits) peuvent changer à tout moment. Assurez-vous que votre code gère ces scénarios. Par exemple, si vous récupérez initialement 2 produits, votre application doit afficher ces 2 produits. Mais si vous en récupérez ensuite 3, votre application doit tous les afficher sans nécessiter de modifications du code. La seule chose à écrire en dur est l'identifiant du placement. Paramètres de réponse : | Paramètre | Description | | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | | Paywall | Un objet [`AdaptyPaywall`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html) contenant : une liste d'identifiants de produits, l'identifiant du paywall, le Remote Config, et plusieurs autres propriétés. | ## Récupérer les produits \{#fetch-products\} Une fois que vous avez le paywall, vous pouvez récupérer le tableau de produits qui lui correspond : ```csharp showLineNumbers Adapty.GetPaywallProducts(paywall, (products, error) => { if(error != null) { // handle the error return; } // products - the requested products array }); ``` Paramètres de réponse : | Paramètre | Description | | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Products | Liste d'objets [`AdaptyPaywallProduct`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall_product.html) contenant : l'identifiant du produit, le nom du produit, le prix, la devise, la durée de l'abonnement, ainsi que d'autres propriétés. | Lors de l'implémentation de votre propre design de paywall, vous aurez probablement besoin d'accéder à ces propriétés depuis l'objet [`AdaptyPaywallProduct`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall_product.html). Les propriétés les plus couramment utilisées sont illustrées ci-dessous, mais consultez le document lié pour obtenir des informations complètes sur toutes les propriétés disponibles. | Propriété | Description | |-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Title** | Pour afficher le titre du produit, utilisez `product.LocalizedTitle`. La localisation est basée sur le pays du store sélectionné par l'utilisateur et non sur la langue de l'appareil. | | **Price** | Pour afficher le prix dans une version localisée, utilisez `product.Price.LocalizedString`. Cette localisation est basée sur les informations de langue de l'appareil. Vous pouvez également accéder au prix sous forme numérique via `product.Price.Amount`. La valeur sera fournie dans la devise locale. Pour obtenir le symbole de devise associé, utilisez `product.Price.CurrencySymbol`. | | **Subscription Period** | Pour afficher la période (ex. : semaine, mois, année, etc.), utilisez `product.Subscription?.LocalizedPeriod`. Cette localisation est basée sur la langue de l'appareil. Pour récupérer la période d'abonnement par programmation, utilisez `product.Subscription?.Period`. Vous pouvez ensuite accéder à l'enum `Unit` pour obtenir la durée (c'est-à-dire `AdaptySubscriptionPeriodUnit.Day`, `AdaptySubscriptionPeriodUnit.Week`, `AdaptySubscriptionPeriodUnit.Month`, `AdaptySubscriptionPeriodUnit.Year` ou `AdaptySubscriptionPeriodUnit.Unknown`). La valeur `NumberOfUnits` indique le nombre d'unités de période. Par exemple, pour un abonnement trimestriel, vous obtiendrez `AdaptySubscriptionPeriodUnit.Month` dans la propriété Unit et `3` dans la propriété NumberOfUnits. | | **Introductory Offer** | Pour afficher un badge ou un autre indicateur signalant qu'un abonnement contient une offre de lancement, consultez la propriété `product.Subscription?.Offer?.Phases`. Il s'agit d'une liste pouvant contenir jusqu'à deux phases de remise : la phase d'essai gratuit et la phase de prix de lancement. Chaque objet de phase contient les propriétés utiles suivantes :
• `PaymentMode` : un enum avec les valeurs `AdaptyPaymentMode.FreeTrial`, `AdaptyPaymentMode.PayAsYouGo`, `AdaptyPaymentMode.PayUpFront` et `AdaptyPaymentMode.Unknown`. Les essais gratuits correspondent au type `AdaptyPaymentMode.FreeTrial`.
• `Price` : un objet `AdaptyPrice` avec le prix réduit — utilisez `Price.Amount` pour la valeur numérique et `Price.LocalizedString` pour l'afficher. Pour les essais gratuits, vérifiez que `Price.Amount` vaut `0`.
• `LocalizedNumberOfPeriods` : une chaîne localisée selon la langue de l'appareil, décrivant la durée de l'offre. Par exemple, une offre d'essai de trois jours affiche `"3 days"` dans ce champ.
• `SubscriptionPeriod` : vous pouvez également obtenir les détails individuels de la période de l'offre avec cette propriété. Elle fonctionne de la même manière pour les offres que la section précédente le décrit.
• `LocalizedSubscriptionPeriod` : une période d'abonnement formatée pour la remise, selon la langue de l'utilisateur. | ## Accélérer la récupération des paywalls avec le paywall d'audience par défaut \{#speed-up-paywall-fetching-with-default-audience-paywall\} En général, les paywalls sont récupérés presque instantanément, vous n'avez donc pas à vous soucier d'optimiser ce processus. Cependant, si vous avez de nombreuses audiences et paywalls et que vos utilisateurs disposent d'une connexion internet faible, la récupération d'un paywall peut prendre plus de temps que souhaité. Dans ce cas, vous pouvez afficher un paywall par défaut pour garantir une expérience utilisateur fluide plutôt que de ne rien afficher du tout. Pour y remédier, vous pouvez utiliser la méthode `GetPaywallForDefaultAudience`, qui récupère le paywall du placement spécifié pour l'audience **All Users**. Cependant, il est essentiel de comprendre que l'approche recommandée consiste à récupérer le paywall via la méthode `getPaywall`, comme décrit dans la section [Récupérer le paywall](#fetch-paywall-information) ci-dessus. :::warning Préférez `GetPaywall` à `GetPaywallForDefaultAudience`, car cette dernière présente des limitations importantes : - **Problèmes de compatibilité** : peut créer des difficultés lors de la prise en charge de plusieurs versions de l'application, nécessitant soit des designs rétrocompatibles, soit d'accepter que les versions plus anciennes s'affichent incorrectement. - **Aucune personnalisation** : affiche uniquement le contenu pour l'audience « Tous les utilisateurs », sans ciblage basé sur le pays, l'attribution ou les attributs personnalisés. Si la rapidité de récupération l'emporte sur ces inconvénients pour votre cas d'usage, utilisez `GetPaywallForDefaultAudience` comme indiqué ci-dessous. Sinon, utilisez `GetPaywall` comme décrit [ci-dessus](#fetch-paywall-information). ::: ```csharp showLineNumbers Adapty.GetPaywallForDefaultAudience("YOUR_PLACEMENT_ID", "en", (paywall, error) => { if(error != null) { // handle the error return; } // paywall - the resulting object }); ``` Paramètres : | Paramètre | Présence | Description | |---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **placementId** | requis | L'identifiant du [Placement](placements) souhaité. Il s'agit de la valeur que vous avez indiquée lors de la création d'un placement dans l'Adapty Dashboard. | | **locale** |

optionnel

par défaut : `en`

|

L'identifiant de la localisation du paywall. Ce paramètre doit être un code de langue composé d'un ou deux sous-tags séparés par le caractère moins (**-**). Le premier sous-tag désigne la langue, le second désigne la région.

Exemple : `en` signifie anglais, `pt-br` représente le portugais brésilien.

| | **fetchPolicy** | par défaut : `.reloadRevalidatingCacheData` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option, car elle garantit que vos utilisateurs reçoivent toujours les données les plus récentes.

Toutefois, si vous pensez que vos utilisateurs ont une connexion instable, envisagez d'utiliser `.returnCacheDataElseLoad` pour renvoyer les données en cache si elles existent. Dans ce cas, les utilisateurs ne disposeront peut-être pas des toutes dernières données, mais les temps de chargement seront plus rapides, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, il est donc sûr de l'utiliser en cours de session pour éviter les requêtes réseau.

Notez que le cache reste intact après un redémarrage de l'application et n'est effacé que lors d'une réinstallation ou d'un nettoyage manuel.

Le SDK Adapty stocke les paywalls localement en deux couches : le cache mis à jour régulièrement décrit ci-dessus et les paywalls de secours. Nous utilisons également un CDN pour récupérer les paywalls plus rapidement, ainsi qu'un serveur de secours indépendant en cas d'inaccessibilité du CDN. Ce système est conçu pour vous garantir toujours la dernière version de vos paywalls, tout en assurant la fiabilité même lorsque la connexion internet est limitée.

|
--- # File: present-remote-config-paywalls-unity --- --- title: "Afficher un paywall conçu avec Remote Config dans le SDK Unity" description: "Découvrez comment afficher des paywalls Remote Config dans le SDK Adapty Unity pour personnaliser l'expérience utilisateur." --- Si vous avez personnalisé un paywall avec Remote Config, vous devrez implémenter le rendu dans le code de votre application mobile pour l'afficher à vos utilisateurs. Comme Remote Config offre une flexibilité adaptée à vos besoins, c'est vous qui décidez de ce qui est inclus et de l'apparence de votre paywall. Adapty fournit une méthode pour récupérer la configuration distante, vous laissant toute liberté pour afficher votre paywall personnalisé. ## Récupérer le Remote Config d'un flow et l'afficher \{#get-flow-remote-config-and-present-it\} Dans la v4, un flow comporte une entrée `AdaptyRemoteConfig` par locale configurée dans la liste `RemoteConfigs`. Sélectionnez la locale correspondant à la préférence de l'utilisateur, puis lisez les valeurs dont vous avez besoin. ```csharp showLineNumbers using System.Linq; using AdaptySDK; Adapty.GetFlow("YOUR_PLACEMENT_ID", (flow, error) => { if (error != null) { // handle the error return; } var config = flow.RemoteConfigs.FirstOrDefault(c => c.Locale == "en") ?? flow.RemoteConfigs.FirstOrDefault(); var headerText = config?.Dictionary?["header_text"] as string; // Or access raw JSON data var jsonData = config?.Data; }); ``` À ce stade, une fois que vous avez reçu toutes les valeurs nécessaires, il est temps de les afficher et de les assembler en une page visuellement attrayante. Assurez-vous que le design s'adapte aux différents écrans et orientations des téléphones mobiles, offrant une expérience fluide et conviviale sur tous les appareils. :::warning Veillez à [enregistrer l'événement d'affichage du paywall](present-remote-config-paywalls-unity#track-paywall-view-events) comme décrit ci-dessous, afin de permettre à Adapty Analytics de collecter des informations pour les entonnoirs et les tests A/B. ::: Une fois le paywall affiché, passez à la configuration du flux d'achat. Lorsque l'utilisateur effectue un achat, appelez simplement `.MakePurchase()` avec le produit de votre flow. Pour plus de détails sur la méthode `.MakePurchase()`, consultez [Effectuer des achats](unity-making-purchases). Nous vous recommandons de [créer un paywall de secours](unity-use-fallback-paywalls). Ce paywall de secours s'affichera à l'utilisateur en l'absence de connexion internet ou de cache disponible, garantissant une expérience fluide même dans ces situations. ## Suivre les événements d'affichage des paywalls \{#track-paywall-view-events\} Adapty vous aide à mesurer la performance de vos flows et paywalls. Les données sur les achats sont collectées automatiquement, mais l'enregistrement des vues requiert votre intervention, car vous seul savez quand un utilisateur voit un flow. Pour enregistrer un événement de vue, appelez simplement `.LogShowFlow(flow)` — cela sera reflété dans vos métriques dans les entonnoirs et les tests A/B. :::important Il n'est pas nécessaire d'appeler `.LogShowFlow(flow)` si vous affichez des flows ou des paywalls rendus par le [Flow Builder](adapty-flow-builder) ou le [Paywall Builder](adapty-paywall-builder). Adapty suit les vues automatiquement dans ces cas. ::: ```csharp showLineNumbers Adapty.LogShowFlow(flow, (error) => { // handle the error }); ``` Paramètres de la requête : | Paramètre | Présence | Description | | :-------- | :------- |:-----------------------------------------------------------------| | **flow** | required | Un objet `AdaptyFlow` obtenu via `Adapty.GetFlow`. | Si vous avez personnalisé un paywall avec Remote Config, vous devrez implémenter le rendu dans le code de votre application mobile pour l'afficher aux utilisateurs. Remote Config offrant une flexibilité adaptée à vos besoins, c'est vous qui décidez de ce qui est inclus et de l'apparence de votre paywall. Nous fournissons une méthode pour récupérer la configuration distante, vous laissant ainsi toute liberté pour afficher votre paywall personnalisé configuré via Remote Config. ## Récupérer le Remote Config d'un paywall et l'afficher \{#get-paywall-remote-config-and-present-it\} Pour obtenir le Remote Config d'un paywall, accédez à la propriété `remoteConfig` et extrayez les valeurs dont vous avez besoin. ```csharp showLineNumbers Adapty.GetPaywall("YOUR_PLACEMENT_ID", (paywall, error) => { if (error != null) { // handle the error return; } // Access remote config dictionary var dictionary = paywall.RemoteConfig?.Dictionary; var headerText = dictionary?["header_text"] as string; // Or access raw JSON data var jsonData = paywall.RemoteConfig?.Data; }); ``` À ce stade, une fois que vous avez reçu toutes les valeurs nécessaires, il est temps d'afficher et d'assembler ces données dans une page visuellement attrayante. Assurez-vous que le design s'adapte aux différentes tailles d'écrans et orientations des mobiles, pour offrir une expérience fluide et agréable sur tous les appareils. :::warning Veillez à [enregistrer l'événement d'affichage du paywall](present-remote-config-paywalls-unity#track-paywall-view-events-1) comme décrit ci-dessous, afin que les analytics Adapty puissent collecter les données nécessaires aux entonnoirs et aux tests A/B. ::: Une fois le paywall affiché, passez à la configuration du flux d'achat. Lorsqu'un utilisateur effectue un achat, appelez simplement `.MakePurchase()` avec le produit de votre paywall. Pour plus de détails sur la méthode `.MakePurchase()`, consultez [Effectuer des achats](unity-making-purchases). Nous recommandons de [créer un paywall de secours](unity-use-fallback-paywalls). Ce paywall de secours s'affichera à l'utilisateur en l'absence de connexion internet ou de cache disponible, garantissant une expérience fluide même dans ces situations. ## Suivre les événements d'affichage de paywall \{#track-paywall-view-events\} Adapty vous aide à mesurer les performances de vos paywalls. Bien que les données d'achats soient collectées automatiquement, l'enregistrement des affichages de paywall nécessite votre intervention, car vous seul savez quand un client voit un paywall. Pour enregistrer un événement d'affichage de paywall, appelez simplement `.LogShowPaywall(paywall)` : cela sera reflété dans vos métriques de paywall dans les entonnoirs et les tests A/B. :::important Il n'est pas nécessaire d'appeler `.LogShowPaywall(paywall)` si vous affichez des paywalls créés dans le [Paywall Builder](adapty-paywall-builder). ::: ```csharp showLineNumbers Adapty.LogShowPaywall(paywall, (error) => { // handle the error }); ``` Paramètres de la requête : | Paramètre | Présence | Description | | :---------- | :------- |:------------------------------------------------------------------| | **paywall** | requis | Un objet [`AdaptyPaywall`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html). | --- # File: unity-making-purchases --- --- title: "Effectuer des achats dans une application mobile avec le SDK Unity" description: "Guide sur la gestion des achats intégrés et des abonnements avec Adapty." --- Afficher des paywalls dans votre application mobile est une étape essentielle pour offrir aux utilisateurs l'accès à des contenus ou services premium. Cependant, afficher ces paywalls suffit à gérer les achats uniquement si vous utilisez le [Paywall Builder](adapty-paywall-builder) pour les personnaliser. Si vous n'utilisez pas le Paywall Builder, vous devez utiliser une méthode dédiée appelée `.makePurchase()` pour finaliser un achat et débloquer le contenu souhaité. Cette méthode constitue le point d'entrée permettant aux utilisateurs d'interagir avec les paywalls et de procéder à leurs transactions. Si votre paywall comporte une offre promotionnelle active pour le produit qu'un utilisateur souhaite acheter, Adapty l'appliquera automatiquement au moment de l'achat. :::warning Notez que l'offre de lancement ne sera appliquée automatiquement que si vous utilisez des paywalls configurés avec le Paywall Builder. Dans les autres cas, vous devrez [vérifier l'éligibilité de l'utilisateur à une offre de lancement sur iOS](fetch-paywalls-and-products#check-intro-offer-eligibility-on-ios). Sauter cette étape risque d'entraîner le rejet de votre application lors de sa mise en ligne. De plus, cela pourrait conduire à facturer le plein tarif à des utilisateurs pourtant éligibles à une offre de lancement. ::: Assurez-vous d'avoir [effectué la configuration initiale](quickstart) sans sauter la moindre étape. Sans elle, nous ne pouvons pas valider les achats. ## Effectuer un achat \{#make-purchase\} :::note **Vous utilisez le [Paywall Builder](adapty-paywall-builder) ?** Les achats sont traités automatiquement — vous pouvez ignorer cette étape. **Vous cherchez un guide pas à pas ?** Consultez le [guide de démarrage rapide](unity-implement-paywalls-manually) pour des instructions d'implémentation complètes avec tout le contexte nécessaire. ::: ```csharp showLineNumbers using AdaptySDK; void MakePurchase(AdaptyPaywallProduct product) { Adapty.MakePurchase(product, (result, error) => { switch (result.Type) { case AdaptyPurchaseResultType.Pending: // handle pending purchase break; case AdaptyPurchaseResultType.UserCancelled: // handle purchase cancellation break; case AdaptyPurchaseResultType.Success: var profile = result.Profile; // handle successfull purchase break; default: break; } }); } ``` Paramètres de la requête : | Paramètre | Présence | Description | | :---------- | :------- |:------------------------------------------------------------------------------------------------------| | **Product** | requis | Un objet [`AdaptyPaywallProduct`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall_product.html) récupéré depuis le paywall. | Paramètres de la réponse : | Paramètre | Description | |---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Profile** |

Si la requête a réussi, la réponse contient cet objet. Un objet [AdaptyProfile](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_profile.html) fournit des informations complètes sur les niveaux d'accès, les abonnements et les achats uniques d'un utilisateur dans l'application.

Vérifiez le statut du niveau d'accès pour déterminer si l'utilisateur dispose de l'accès requis à l'application.

| :::warning **Remarque :** si vous utilisez encore StoreKit en version inférieure à v2.0 et le SDK Adapty en version inférieure à v2.9.0, vous devez fournir le [secret partagé de l'App Store Apple](app-store-connection-configuration#step-5-enter-app-store-shared-secret) à la place. Cette méthode est actuellement dépréciée par Apple. ::: ## Changer d'abonnement lors d'un achat \{#change-subscription-when-making-a-purchase\} Lorsqu'un utilisateur choisit un nouvel abonnement plutôt que de renouveler celui en cours, le fonctionnement dépend du store : - Sur l'App Store, l'abonnement est automatiquement mis à jour au sein du groupe d'abonnements. Si un utilisateur souscrit à un abonnement d'un groupe alors qu'il en a déjà un d'un autre groupe, les deux abonnements seront actifs en même temps. - Sur Google Play, l'abonnement n'est pas mis à jour automatiquement. Vous devrez gérer le changement dans le code de votre application mobile comme décrit ci-dessous. Pour remplacer un abonnement par un autre sur Android, appelez la méthode `.makePurchase()` avec le paramètre supplémentaire suivant : ```csharp showLineNumbers // Create subscription update parameters var subscriptionUpdateParams = new AdaptySubscriptionUpdateParameters( "old_product_id", // Product ID of the current subscription AdaptySubscriptionUpdateReplacementMode.WithTimeProration ); Adapty.MakePurchase(product, subscriptionUpdateParams, (profile, error) => { if(error != null) { // Handle the error return; } // successful cross-grade }); ``` Paramètre de requête supplémentaire : | Paramètre | Présence | Description | | :--------------------------- | :------- |:-------------------------------------------------------------------------------------------------------| | **subscriptionUpdateParams** | requis | un objet [`AdaptySubscriptionUpdateParameters`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_subscription_update_parameters.html). | Vous pouvez en apprendre davantage sur les abonnements et les modes de remplacement dans la documentation Google pour les développeurs : - [À propos des modes de remplacement](https://developer.android.com/google/play/billing/subscriptions#replacement-modes) - [Recommandations de Google pour les modes de remplacement](https://developer.android.com/google/play/billing/subscriptions#replacement-recommendations) - Mode de remplacement [`CHARGE_PRORATED_PRICE`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#CHARGE_PRORATED_PRICE()). Remarque : cette méthode est disponible uniquement pour les mises à niveau d'abonnement. Les rétrogradations ne sont pas prises en charge. - Mode de remplacement [`DEFERRED`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#DEFERRED()). Remarque : le changement d'abonnement effectif n'aura lieu qu'à la fin de la période de facturation en cours. ## Utiliser des codes d'offre sur iOS \{#redeem-offer-codes-in-ios\}
À propos des codes d'offre Les codes d'offre vous permettent d'accorder des réductions ou des périodes d'essai gratuites à des utilisateurs spécifiques. Contrairement aux offres classiques appliquées automatiquement, les codes d'offre sont distribués en dehors de l'application — par e-mail, réseaux sociaux ou supports imprimés. Les utilisateurs les activent en saisissant le code dans l'App Store, en suivant une URL de validation ou via une boîte de dialogue intégrée à l'application. Pour configurer des codes d'offre, ouvrez un abonnement dans App Store Connect et accédez à sa section **Offer Codes**. Vous pouvez créer [trois types](https://developer.apple.com/help/app-store-connect/manage-subscriptions/set-up-subscription-offer-codes) de codes d'offre : - **Free** — l'abonnement est gratuit pendant une durée définie, puis le renouvellement suivant se fait au plein tarif. - **Pay as you go** — l'utilisateur paie un tarif réduit à chaque cycle de facturation pendant une durée définie, puis l'abonnement se renouvelle au plein tarif. - **Pay up front** — l'utilisateur paie un prix unique réduit pour toute la durée de l'offre, puis l'abonnement se renouvelle au plein tarif. Vous n'avez pas besoin d'ajouter les codes d'offre à Adapty. Apple marque chaque transaction pendant la période d'offre avec la catégorie du code d'offre. Cela inclut la première activation et tous les renouvellements à tarif réduit qui suivent. Adapty détecte ce marquage et enregistre chaque transaction avec la catégorie d'offre `offer_code`. Une fois la période d'offre terminée et l'abonnement renouvelé au plein tarif, le marquage disparaît. Vous pouvez filtrer les analyses par le type d'offre **Offer Code** dans l'[Adapty Dashboard](controls-filters-grouping-compare-proceeds). #### Résolution des écarts de revenus \{#revenue-discrepancy-troubleshooting\} Si vous constatez qu'une transaction avec code d'offre apparaît dans Adapty au prix plein du produit plutôt qu'au prix réduit de l'offre, vérifiez les points suivants dans App Store Connect : - Le code d'offre dispose bien d'une tarification correcte configurée pour toutes les régions où les utilisateurs peuvent l'activer. - Le prix de l'offre est défini pour le pays ou la région spécifique de l'utilisateur. Apple envoie le prix régional dans la transaction. Si aucun prix régional n'est configuré pour l'offre, Apple peut envoyer le prix plein du produit à la place. Vous pouvez filtrer et vérifier les transactions avec code d'offre dans l'[Adapty Dashboard](controls-filters-grouping-compare-proceeds) à l'aide des filtres de type d'offre **Offer Code** et **Offer Discount Type**. #### Anciens codes promo (obsolètes) \{#legacy-promo-codes-deprecated\} :::warning Apple a supprimé les codes promo pour les achats intégrés en mars 2026. Les codes d'offre les remplacent avec davantage de fonctionnalités : éligibilité configurable, dates d'expiration et jusqu'à 1 million de codes par trimestre. Si vous utilisiez auparavant des codes promo pour les achats intégrés, passez aux codes d'offre dans App Store Connect. ::: Les anciens codes promo (limités à 100 par application et par version) donnaient un accès gratuit à un abonnement. Contrairement aux codes d'offre, Apple n'incluait pas les informations de réduction dans les transactions avec code promo — il envoyait le prix plein du produit dans le reçu. En conséquence, Adapty enregistrait ces transactions au prix plein, ce qui entraînait des écarts de revenus entre les analyses Adapty et App Store Connect. Si vous constatez des transactions historiques au prix plein qui auraient dû être gratuites, elles proviennent probablement d'anciens codes promo. Ces codes étant désormais obsolètes, passez aux codes d'offre pour un suivi précis des revenus.
Pour afficher la feuille de saisie de code dans votre application : ```csharp showLineNumbers Adapty.PresentCodeRedemptionSheet((error) => { // handle the error }); ``` :::danger D'après nos observations, la feuille de rachat de code d'offre peut ne pas fonctionner de manière fiable dans certaines applications. Nous recommandons de rediriger l'utilisateur directement vers l'App Store. Pour ce faire, ouvrez une URL au format suivant : `https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}` ::: ## Gérer les plans prépayés (Android) \{#manage-prepaid-plans-android\} Si les utilisateurs de votre application peuvent acheter des [plans prépayés](https://developer.android.com/google/play/billing/subscriptions#prepaid-plans) (par exemple, souscrire à un abonnement non renouvelable pour plusieurs mois), vous pouvez activer les [transactions en attente](https://developer.android.com/google/play/billing/subscriptions#pending) pour les plans prépayés. ```csharp showLineNumbers title="Unity" using UnityEngine; using AdaptySDK; var builder = new AdaptyConfiguration.Builder("YOUR_API_KEY") .SetGoogleEnablePendingPrepaidPlans(true); Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); ``` --- # File: unity-restore-purchase --- --- title: "Restaurer les achats dans une application mobile avec le SDK Unity" description: "Découvrez comment restaurer les achats dans Adapty pour garantir une expérience utilisateur fluide." --- La restauration des achats sur iOS et Android permet aux utilisateurs de récupérer l'accès à des contenus précédemment achetés — abonnements ou achats intégrés — sans être débités à nouveau. Cette fonctionnalité est particulièrement utile pour les utilisateurs qui ont désinstallé et réinstallé l'application, ou qui ont changé d'appareil et souhaitent retrouver leurs achats sans repayer. :::note Dans les paywalls créés avec le [Paywall Builder](adapty-paywall-builder), les achats sont restaurés automatiquement, sans code supplémentaire de votre part. Si c'est votre cas, vous pouvez ignorer cette étape. ::: Pour restaurer un achat sans utiliser le [Paywall Builder](adapty-paywall-builder) pour personnaliser le paywall, appelez la méthode `.restorePurchases()` : ```csharp showLineNumbers Adapty.RestorePurchases((profile, error) => { if (error != null) { // handle the error return; } var accessLevel = profile.AccessLevels["YOUR_ACCESS_LEVEL"]; if (accessLevel != null && accessLevel.IsActive) { // restore access } }); ``` Paramètres de réponse : | Paramètre | Description | |---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Profile** |

Un objet [`AdaptyProfile`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_profile.html). Ce modèle contient des informations sur les niveaux d'accès, les abonnements et les achats uniques.

Vérifiez le **statut du niveau d'accès** pour déterminer si l'utilisateur a accès à l'application.

| :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. ::: --- # File: implement-observer-mode-unity --- --- title: "Implémenter le mode Observateur dans le SDK Unity" description: "Implémentez le mode observateur dans Adapty pour suivre les événements d'abonnement utilisateur dans le SDK Unity." --- Si vous disposez déjà de votre propre infrastructure d'achat et n'êtes pas prêt à passer entièrement à Adapty, vous pouvez explorer le [mode Observateur](observer-vs-full-mode). Dans sa forme de base, le mode Observateur offre des analyses avancées et une intégration transparente avec les systèmes d'attribution et d'analyse. Si cela correspond à vos besoins, il vous suffit de : 1. L'activer lors de la configuration du SDK en définissant le paramètre `observerMode` sur `true`. Suivez les instructions de configuration pour [Unity](sdk-installation-unity#activate-adapty-module-of-adapty-sdk). 2. [Signaler les transactions](report-transactions-observer-mode-unity) depuis votre infrastructure d'achat existante à Adapty. :::tip Dans la version 4 du SDK, vous pouvez également présenter des flows et des paywalls rendus par Adapty en mode Observer : lorsqu'un utilisateur appuie sur le bouton d'achat ou de restauration, le SDK transmet l'action à votre code afin que vous puissiez effectuer l'achat ou la restauration vous-même. Voir [Présenter des flows en mode Observer](unity-present-flows-in-observer-mode). ::: ### Configuration du mode Observateur \{#observer-mode-setup\} Activez le mode Observateur si vous gérez vous-même les achats et le statut des abonnements, et que vous utilisez Adapty uniquement pour l'envoi d'événements d'abonnement et l'analytique. :::important En mode Observateur, le SDK Adapty ne clôture aucune transaction — assurez-vous de les gérer vous-même. ::: :::note Dans le SDK 4.0, les interfaces de listener suivent la convention C# avec le préfixe I : implémentez `IAdaptyEventListener` plutôt que `AdaptyEventListener`. Les méthodes restent inchangées. Consultez le [guide de migration](migration-to-unity-sdk-v4). ::: ```csharp showLineNumbers title="C#" using UnityEngine; using AdaptySDK; public class AdaptyListener : MonoBehaviour, AdaptyEventListener { void Start() { DontDestroyOnLoad(this.gameObject); Adapty.SetEventListener(this); var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") .SetObserverMode(true); // Enable observer mode Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); } public void OnLoadLatestProfile(AdaptyProfile profile) { } public void OnInstallationDetailsSuccess(AdaptyInstallationDetails details) { } public void OnInstallationDetailsFail(AdaptyError error) { } } ``` | Paramètre | Description | |--------------|---------------------------------------------------------------------------------------------------------------------| | observerMode | Une valeur booléenne qui contrôle le [mode Observateur](observer-vs-full-mode). La valeur par défaut est `false`. | ## Utiliser les paywalls Adapty en mode Observer \{#using-adapty-paywalls-in-observer-mode\} Si vous souhaitez également utiliser les paywalls et les fonctionnalités de test A/B d'Adapty, c'est possible — mais cela nécessite une configuration supplémentaire en mode Observer. Voici ce que vous devrez faire en plus des étapes ci-dessus : 1. Affichez les paywalls normalement pour les [paywalls avec Remote Config](present-remote-config-paywalls-unity). 3. [Associez les paywalls](report-transactions-observer-mode-unity) aux transactions d'achat. --- # File: report-transactions-observer-mode-unity --- --- title: "Signaler les transactions en Observer Mode dans le SDK Unity" description: "Signalez les transactions d'achat en Observer Mode Adapty pour obtenir des informations utilisateurs et suivre les revenus dans le SDK Unity." --- En Observer Mode, le SDK Adapty ne peut pas suivre automatiquement les achats effectués via votre système d'achat existant. Vous devez signaler les transactions depuis votre app store. Il est crucial de le configurer **avant** de publier votre application pour éviter des erreurs dans les analyses. Utilisez `reportTransaction` pour signaler explicitement chaque transaction afin qu'Adapty la reconnaisse. :::warning **Ne sautez pas le signalement des transactions !** Si vous n'appelez pas `ReportTransaction`, Adapty ne reconnaîtra pas la transaction, elle n'apparaîtra pas dans les analyses et ne sera pas envoyée aux intégrations. ::: Si vous utilisez des paywalls Adapty, incluez le `variationId` lors du signalement d'une transaction. Cela lie l'achat au paywall qui l'a déclenché, garantissant ainsi des analyses de paywall précises. ```csharp showLineNumbers Adapty.ReportTransaction( "YOUR_TRANSACTION_ID", "PAYWALL_VARIATION_ID", // optional (error) => { // handle the error }); ``` Paramètres : | Paramètre | Présence | Description | | ------------- | -------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | transactionId | requis |
  • Pour iOS : identifiant de la transaction.
  • Pour Android : identifiant de type String `purchase.getOrderId` de l'achat, où l'achat est une instance de la classe [Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase) de la bibliothèque de facturation.
| | variationId | optionnel | L'identifiant de type String de la variante. Vous pouvez l'obtenir via la propriété `variationId` de l'objet [AdaptyPaywall](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html). |
En Observer Mode, le SDK Adapty ne peut pas suivre automatiquement les achats effectués via votre système d'achat existant. Vous devez signaler les transactions depuis votre app store ou les restaurer. Il est crucial de le configurer **avant** de publier votre application pour éviter des erreurs dans les analyses. Utilisez `reportTransaction` sur les deux plateformes pour signaler explicitement chaque transaction, et utilisez `restorePurchases` sur Android comme étape supplémentaire pour vous assurer qu'Adapty la reconnaisse. :::warning **Ne sautez pas le signalement des transactions et la restauration des achats !** Si vous n'appelez pas ces méthodes, Adapty ne reconnaîtra pas la transaction, elle n'apparaîtra pas dans les analyses et ne sera pas envoyée aux intégrations. ::: Si vous utilisez des paywalls Adapty, incluez le `PAYWALL_VARIATION_ID` lors du signalement d'une transaction. Cela lie l'achat au paywall qui l'a déclenché, garantissant ainsi des analyses de paywall précises. ```csharp showLineNumbers // every time when calling transasction.finish() #if UNITY_ANDROID && !UNITY_EDITOR Adapty.RestorePurchases((profile, error) => { // handle the error }); #endif Adapty.ReportTransaction( "YOUR_TRANSACTION_ID", "PAYWALL_VARIATION_ID", // optional (error) => { // handle the error }); ``` Paramètres : | Paramètre | Présence | Description | | ------------- | -------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | transactionId | requis |
  • Pour iOS, StoreKit 1 : un objet [SKPaymentTransaction](https://developer.apple.com/documentation/storekit/skpaymenttransaction).
  • Pour iOS, StoreKit 2 : un objet [Transaction](https://developer.apple.com/documentation/storekit/transaction).
  • Pour Android : identifiant de type String (`purchase.getOrderId`) de l'achat, où l'achat est une instance de la classe [Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase) de la bibliothèque de facturation.
| | variationId | optionnel | L'identifiant de type String de la variante. Vous pouvez l'obtenir via la propriété `variationId` de l'objet [AdaptyPaywall](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html). |
**Signalement des transactions** - Les versions jusqu'à 3.1.x écoutent automatiquement les transactions dans l'App Store, le signalement manuel n'est donc pas nécessaire. - La version 3.2 ne prend pas en charge l'Observer Mode. **Signalement des transactions** Utilisez `restorePurchases` pour signaler une transaction à Adapty en Observer Mode, comme expliqué sur la page [Restaurer les achats dans le code mobile](unity-restore-purchase). :::warning **Ne sautez pas le signalement des transactions !** Si vous n'appelez pas `restorePurchases`, Adapty ne reconnaîtra pas la transaction, elle n'apparaîtra pas dans les analyses et ne sera pas envoyée aux intégrations. ::: **Association des paywalls aux transactions** Le SDK Adapty ne peut pas déterminer la source des achats, car c'est vous qui les traitez. Par conséquent, si vous souhaitez utiliser des paywalls et/ou des tests A/B en Observer Mode, vous devez associer la transaction provenant de votre app store au paywall correspondant dans le code de votre application mobile. Il est important de bien configurer cela avant de publier votre application, sinon cela entraînera des erreurs dans les analyses. ```csharp Adapty.SetVariationForTransaction("", "", (error) => { if(error != null) { // handle the error return; } // successful binding }); ``` | Paramètre | Présence | Description | | ------------------------------------------------------ | -------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | transactionId | requis |

Pour iOS, StoreKit 1 : un objet [SKPaymentTransaction](https://developer.apple.com/documentation/storekit/skpaymenttransaction).

Pour iOS, StoreKit 2 : un objet [Transaction](https://developer.apple.com/documentation/storekit/transaction).

Pour Android : identifiant de type String (purchase.getOrderId de l'achat, où l'achat est une instance de la classe [Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase) de la bibliothèque de facturation.

| | variationId | requis | L'identifiant de type String de la variante. Vous pouvez l'obtenir via la propriété `variationId` de l'objet [AdaptyPaywall](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html). |
--- # File: unity-troubleshoot-purchases --- --- title: "Troubleshoot purchases in Unity SDK" description: "Troubleshoot purchases in Unity SDK" --- Ce guide vous aide à résoudre les problèmes courants lors de l'implémentation manuelle des achats dans le SDK Unity. ## makePurchase est appelé avec succès, mais le profil n'est pas mis à jour \{#makepurchase-is-called-successfully-but-the-profile-is-not-being-updated\} **Problème** : La méthode `makePurchase` se termine avec succès, mais le profil de l'utilisateur et le statut de l'abonnement ne sont pas mis à jour dans Adapty. **Cause** : Cela indique généralement une configuration incomplète du Google Play Store. **Solution** : Assurez-vous d'avoir effectué toutes les [étapes de configuration Google Play](initial-android). ## makePurchase est appelé deux fois \{#makepurchase-is-invoked-twice\} **Problème** : La méthode `makePurchase` est appelée plusieurs fois pour le même achat. **Cause** : Cela se produit généralement lorsque le flow d'achat est déclenché plusieurs fois en raison de problèmes de gestion de l'état de l'interface ou d'interactions rapides de l'utilisateur. **Solution** : Assurez-vous d'avoir effectué toutes les [étapes de configuration Google Play](initial-android). ## AdaptyError.cantMakePayments en mode observateur \{#adaptyelrorcantmakepayments-in-observer-mode\} **Problème** : Vous obtenez `AdaptyError.cantMakePayments` en utilisant `makePurchase` en mode observateur. **Cause** : En mode observateur, vous devez gérer les achats de votre côté et ne pas utiliser la méthode `makePurchase` d'Adapty. **Solution** : Si vous utilisez `makePurchase` pour les achats, désactivez le mode observateur. Vous devez soit utiliser `makePurchase`, soit gérer les achats de votre côté en mode observateur. Consultez [Implémenter le mode observateur](implement-observer-mode-unity) pour plus de détails. ## Erreur Adapty : (code : 103, message : Play Market request failed on purchases updated: responseCode=3, debugMessage=Billing Unavailable, detail: null) \{#adapty-error-code-103-message-play-market-request-failed-on-purchases-updated-responsecode3-debugmessagebilling-unavailable-detail-null\} **Problème** : Vous recevez une erreur de facturation indisponible depuis le Google Play Store. **Cause** : Cette erreur n'est pas liée à Adapty. Il s'agit d'une erreur de la bibliothèque Google Play Billing indiquant que la facturation n'est pas disponible sur l'appareil. **Solution** : Cette erreur n'est pas liée à Adapty. Vous pouvez en savoir plus dans la documentation du Play Store : [Handle BillingResult response codes](https://developer.android.com/google/play/billing/errors#billing_unavailable_error_code_3) | Play Billing | Android Developers. ## makePurchasesCompletionHandlers introuvable \{#not-found-makepurchasescompletionhandlers\} **Problème** : Vous rencontrez des problèmes avec `makePurchasesCompletionHandlers` qui est introuvable. **Cause** : Cela est généralement lié à des problèmes de test en sandbox. **Solution** : Créez un nouvel utilisateur sandbox et réessayez. Cela résout souvent les problèmes de gestionnaire de complétion d'achat liés au sandbox. ## Autres problèmes \{#other-issues\} **Problème** : Vous rencontrez d'autres problèmes liés aux achats qui ne sont pas couverts ci-dessus. **Solution** : Migrez le SDK vers la dernière version à l'aide des [guides de migration](unity-sdk-migration-guides) si nécessaire. De nombreux problèmes sont résolus dans les versions plus récentes du SDK. --- # File: unity-user --- --- title: "Utilisateurs et accès dans Unity SDK" description: "Apprenez à gérer les utilisateurs et les niveaux d'accès dans votre application Unity avec le SDK Adapty." --- --- # File: unity-identifying-users --- --- title: "Identifier les utilisateurs dans le SDK Unity" description: "Découvrez comment identifier les utilisateurs dans votre application Unity avec le SDK Adapty." --- Adapty crée un identifiant de profil interne pour chaque utilisateur. Cependant, si vous disposez de votre propre système d'authentification, vous pouvez définir votre propre Customer User ID. Vous pouvez retrouver les utilisateurs par leur Customer User ID dans la section [Profiles](profiles-crm) et l'utiliser dans l'[API côté serveur](getting-started-with-server-side-api), qui sera envoyée à toutes les intégrations. ### Définir le Customer User ID lors de la configuration \{#setting-customer-user-id-on-configuration\} Si vous disposez d'un identifiant utilisateur lors de la configuration, passez-le simplement en tant que paramètre `customerUserId` à la méthode `.activate()` : ```csharp showLineNumbers using UnityEngine; using AdaptySDK; var builder = new AdaptyConfiguration.Builder("YOUR_API_KEY") .SetCustomerUserId("YOUR_USER_ID"); Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); ``` :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. ::: ### Définir le Customer User ID après la configuration \{#setting-customer-user-id-after-configuration\} Si vous n'avez pas d'identifiant utilisateur lors de la configuration du SDK, vous pouvez le définir ultérieurement à tout moment avec la méthode `.identify()`. Les cas les plus courants d'utilisation de cette méthode sont après l'inscription ou la connexion, lorsque l'utilisateur passe du statut d'utilisateur anonyme à celui d'utilisateur authentifié. ```csharp showLineNumbers Adapty.Identify("YOUR_USER_ID", (error) => { if(error == null) { // successful identify } }); ``` Paramètres de la requête : - **Customer User ID** (obligatoire) : un identifiant utilisateur de type chaîne de caractères. :::warning Resoumission des données utilisateur importantes Dans certains cas, par exemple lorsqu'un utilisateur se reconnecte à son compte, les serveurs d'Adapty possèdent déjà des informations sur cet utilisateur. Dans ces situations, le SDK Adapty basculera automatiquement vers le nouvel utilisateur. Si vous avez transmis des données à l'utilisateur anonyme, telles que des attributs personnalisés ou des attributions provenant de réseaux tiers, vous devez soumettre à nouveau ces données pour l'utilisateur identifié. Il est également important de noter que vous devez redemander tous les paywalls et produits après avoir identifié l'utilisateur, car les données du nouvel utilisateur peuvent être différentes. ::: ### Déconnexion et reconnexion \{#logging-out-and-logging-in\} Vous pouvez déconnecter l'utilisateur à tout moment en appelant la méthode `.logout()` : ```csharp showLineNumbers Adapty.Logout((error) => { if(error == null) { // successful logout } }); ``` Vous pouvez ensuite reconnecter l'utilisateur à l'aide de la méthode `.identify()`. ## Assigner un `appAccountToken` (iOS) \{#assign-appaccounttoken-ios\} [`appAccountToken`](https://developer.apple.com/documentation/storekit/product/purchaseoption/appaccounttoken(_:)) est un **UUID** qui vous permet de relier les transactions de l'App Store à l'identité interne de vos utilisateurs. StoreKit associe ce token à chaque transaction, afin que votre backend puisse faire correspondre les données de l'App Store à vos utilisateurs. Utilisez un UUID stable généré par utilisateur et réutilisez-le pour le même compte sur tous les appareils. Cela garantit que les achats et les notifications de l'App Store restent correctement associés. Vous pouvez définir le token de deux manières : lors de l'activation du SDK ou lors de l'identification de l'utilisateur. :::important Vous devez toujours passer `appAccountToken` avec `customerUserId`. Si vous ne passez que le token, il ne sera pas inclus dans la transaction. ::: ```csharp showLineNumbers title="Unity" using UnityEngine; using AdaptySDK; using System; // During configuration: var appAccountToken = new Guid("YOUR_APP_ACCOUNT_TOKEN"); var builder = new AdaptyConfiguration.Builder("YOUR_API_KEY") .SetCustomerUserId("YOUR_USER_ID", appAccountToken); Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); // Or when identifying users Adapty.Identify("YOUR_USER_ID", appAccountToken, (error) => { if (error == null) { // successful identify } }); ``` ## Définir des identifiants de compte masqués (Android) \{#set-obfuscated-account-ids-android\} Google Play exige des identifiants de compte masqués pour certains cas d'usage afin de renforcer la confidentialité et la sécurité des utilisateurs. Ces identifiants permettent à Google Play d'identifier les achats tout en gardant les informations des utilisateurs anonymes, ce qui est particulièrement important pour la prévention des fraudes et l'analyse. Vous devrez peut-être définir ces identifiants si votre application traite des données utilisateur sensibles ou si vous devez vous conformer à des réglementations spécifiques en matière de confidentialité. Les identifiants masqués permettent à Google Play de suivre les achats sans exposer les véritables identifiants des utilisateurs. ```csharp showLineNumbers title="Unity" using UnityEngine; using AdaptySDK; // During configuration: var builder = new AdaptyConfiguration.Builder("YOUR_API_KEY") .SetCustomerUserId("YOUR_USER_ID", null, "YOUR_OBFUSCATED_ACCOUNT_ID"); Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); // Or when identifying users Adapty.Identify("YOUR_USER_ID", null, "YOUR_OBFUSCATED_ACCOUNT_ID", (error) => { if (error == null) { // successful identify } }); ``` ## Détecter les utilisateurs sur plusieurs appareils \{#detect-users-across-devices\} Lors de l'activation du SDK, il lit automatiquement les droits existants de l'utilisateur depuis StoreKit (iOS) ou Google Play Billing (Android) et les synchronise avec le backend Adapty. Un abonnement actif apparaît sur le profil Adapty sans que l'application n'appelle `restorePurchases`. Ce qui **ne** se produit **pas** automatiquement, c'est la reconnaissance qu'un profil sur un nouvel appareil appartient au même utilisateur que le profil sur l'appareil d'origine. Adapty fait correspondre les profils par Customer User ID, donc la continuité d'identité dépend de ce que vous utilisez comme CUID. **Ce qu'Adapty peut détecter entre les appareils** | Votre configuration | Ce qu'Adapty détecte | Ce que vous devez faire | | --- | --- | --- | | Customer User ID = `device_id` (sans connexion à l'application) | Le nouvel appareil reçoit un CUID différent et donc un profil différent. L'abonnement se synchronise avec le nouveau profil via un événement **Access level updated**, mais `subscription_started` ne se déclenche pas — le nouveau profil est traité comme un héritier de l'achat d'origine. Les analyses basées sur `subscription_started` sous-compteront les utilisateurs de retour. | Utilisez un identifiant de compte stable comme Customer User ID pour qu'un utilisateur de retour corresponde au profil existant sur tous les appareils. | | Customer User ID = identifiant de compte stable (connexion sur chaque appareil) | Le SDK synchronise automatiquement l'abonnement lors de l'appel `activate()`, et `identify()` fait correspondre le profil existant par CUID. | Aucune configuration supplémentaire n'est nécessaire — l'identité et l'abonnement se résolvent automatiquement. | | Héritier du partage familial Apple | Le membre de la famille reçoit l'abonnement uniquement via un événement **Access level updated** — `subscription_started` ne se déclenche pas. | Écoutez **Access level updated**. Consultez [Apple Family Sharing](apple-family-sharing) pour la matrice complète des événements. | | Même compte Apple/Google, utilisateurs in-app différents | Le premier profil à enregistrer l'achat devient le parent. Les profils suivants voient l'abonnement via une chaîne d'héritiers, avec un seul événement **Access level updated**. | Exigez une connexion, puis choisissez un [mode de partage](sharing-paid-access-between-user-accounts) adapté à votre modèle. | **Restaurer les achats sur un nouvel appareil** Proposez un bouton « Restaurer les achats » initié par l'utilisateur sur votre paywall. Les directives App Review d'Apple (règle 3.1.1) l'exigent, et il sert de solution de secours quand la synchronisation automatique rate un cas limite. Ce bouton doit appeler `restorePurchases` dans votre SDK. Un appel programmatique à `restorePurchases` au premier lancement n'est pas nécessaire pour une utilisation normale — le SDK effectue déjà l'équivalent lors de l'appel `activate()`. Réservez les appels programmatiques pour forcer une vérification fraîche du reçu, par exemple lors du débogage d'un accès manquant après la fin de `activate()`. --- # File: unity-setting-user-attributes --- --- title: "Définir les attributs utilisateur dans le SDK Unity" description: "Apprenez à mettre à jour les attributs utilisateur et les données de profil dans votre application Unity avec le SDK Adapty." --- Vous pouvez définir des attributs optionnels tels que l'e-mail, le numéro de téléphone, etc., pour les utilisateurs de votre application. Vous pouvez ensuite utiliser ces attributs pour créer des [segments](segments) d'utilisateurs ou simplement les consulter dans le CRM. ### Définir les attributs utilisateur \{#setting-user-attributes\} Pour définir les attributs utilisateur, appelez la méthode `.updateProfile()` : ```csharp showLineNumbers var builder = new Adapty.ProfileParameters.Builder() .SetFirstName("John") .SetLastName("Appleseed") .SetBirthday(new DateTime(1970, 1, 3)) .SetGender(ProfileGender.Female) .SetEmail("example@adapty.io"); Adapty.UpdateProfile(builder.Build(), (error) => { if(error != nil) { // handle the error } }); ``` Notez que les attributs que vous avez précédemment définis avec la méthode `updateProfile` ne seront pas réinitialisés. :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. ::: ### Liste des clés autorisées \{#the-allowed-keys-list\} Les clés `` autorisées de `AdaptyProfileParameters.Builder` et les valeurs `` correspondantes sont répertoriées ci-dessous : | Clé | Valeur | |---|-----| |

email

phoneNumber

firstName

lastName

| String | | gender | Enum, les valeurs autorisées sont : `female`, `male`, `other` | | birthday | Date | ### Attributs utilisateur personnalisés \{#custom-user-attributes\} Vous pouvez définir vos propres attributs personnalisés, généralement liés à l'utilisation de votre application. Par exemple, pour une application de fitness, il peut s'agir du nombre d'exercices par semaine ; pour une application d'apprentissage des langues, du niveau de connaissance de l'utilisateur, etc. Vous pouvez les utiliser dans des segments pour créer des paywalls et des offres ciblés, ainsi que dans les analyses pour identifier quelles métriques produit influencent le plus les revenus. ```csharp showLineNumbers try { builder = builder.SetCustomStringAttribute("string_key", "string_value"); builder = builder.SetCustomDoubleAttribute("double_key", 123.0f); } catch (Exception e) { // handle the exception } ``` Pour supprimer une clé existante, utilisez la méthode `.withRemoved(customAttributeForKey:)` : ```csharp showLineNumbers try { builder = builder.RemoveCustomAttribute("key_to_remove"); } catch (Exception e) { // handle the exception } ``` Il peut parfois être utile de connaître les attributs personnalisés déjà définis. Pour cela, utilisez le champ `customAttributes` de l'objet `AdaptyProfile`. :::warning Gardez à l'esprit que la valeur de `customAttributes` peut ne pas être à jour, car les attributs utilisateur peuvent être envoyés depuis différents appareils à tout moment — les attributs sur le serveur peuvent donc avoir été modifiés depuis la dernière synchronisation. ::: ### Limites \{#limits\} - Jusqu'à 30 attributs personnalisés par utilisateur - Les noms de clés peuvent comporter jusqu'à 30 caractères. Le nom de clé peut contenir des caractères alphanumériques ainsi que les caractères suivants : `_` `-` `.` - La valeur peut être une chaîne de caractères ou un nombre décimal (float) d'au plus 50 caractères. --- # File: unity-listen-subscription-changes --- --- title: "Vérifier le statut d'abonnement dans le SDK Unity" description: "Suivez et gérez le statut d'abonnement des utilisateurs dans Adapty pour améliorer la rétention client dans votre application Unity." --- Avec Adapty, suivre le statut d'un abonnement est simple. Vous n'avez pas besoin d'insérer manuellement des ID de produits dans votre code. Il vous suffit de vérifier l'existence d'un [niveau d'accès](access-level) actif pour confirmer le statut d'abonnement d'un utilisateur.
Avant de vérifier le statut d'abonnement (Cliquez pour développer) - Pour iOS, configurez les [App Store Server Notifications](enable-app-store-server-notifications) - Pour Android, configurez les [Real-time Developer Notifications (RTDN)](enable-real-time-developer-notifications-rtdn)
## Niveau d'accès et l'objet AdaptyProfile \{#access-level-and-the-adaptyprofile-object\} Les niveaux d'accès sont des propriétés de l'objet [AdaptyProfile](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_profile.html). Nous recommandons de récupérer le profil au démarrage de votre application, par exemple lorsque vous [identifiez un utilisateur](unity-identifying-users#setting-customer-user-id-on-configuration), puis de le mettre à jour à chaque fois que des modifications surviennent. Ainsi, vous pouvez utiliser l'objet profil sans avoir à le redemander à chaque fois. Pour être notifié des mises à jour de profil, écoutez les changements de profil comme décrit dans la section [Écouter les mises à jour de profil, y compris les niveaux d'accès](#listening-for-subscription-status-updates) ci-dessous. :::tip Vous souhaitez voir un exemple concret d'intégration du SDK Adapty dans une application mobile ? Consultez nos [exemples d'applications](sample-apps), qui illustrent la configuration complète, notamment l'affichage des paywalls, les achats et d'autres fonctionnalités de base. ::: ## Récupérer le niveau d'accès depuis le serveur \{#retrieving-the-access-level-from-the-server\} Pour obtenir le niveau d'accès depuis le serveur, utilisez la méthode `.GetProfile()` : ```csharp showLineNumbers Adapty.GetProfile((profile, error) => { if (error != null) { // handle the error return; } // check the access }); ``` Paramètres de réponse : | Paramètre | Description | | --------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Profile |

Un objet [AdaptyProfile](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_profile.html). En général, il suffit de vérifier le statut du niveau d'accès du profil pour déterminer si l'utilisateur dispose d'un accès premium à l'application.

La méthode `.getProfile` fournit le résultat le plus à jour, car elle interroge toujours l'API. Si, pour une raison quelconque (par exemple, absence de connexion internet), le SDK ne parvient pas à récupérer les informations depuis le serveur, les données du cache sont renvoyées. Il est également important de noter que le SDK met régulièrement à jour le cache `AdaptyProfile` afin de maintenir ces informations aussi récentes que possible.

| La méthode `.getProfile()` vous fournit le profil utilisateur à partir duquel vous pouvez obtenir le statut du niveau d'accès. Vous pouvez avoir plusieurs niveaux d'accès par application. Par exemple, si vous avez une application de presse et vendez des abonnements à différentes thématiques indépendamment, vous pouvez créer des niveaux d'accès « sports » et « science ». Mais la plupart du temps, un seul niveau d'accès suffira ; dans ce cas, vous pouvez simplement utiliser le niveau d'accès par défaut « premium ». Voici un exemple pour vérifier le niveau d'accès par défaut « premium » : ```csharp showLineNumbers Adapty.GetProfile((profile, error) => { if (error != null) { // handle the error return; } // "premium" is an identifier of default access level var accessLevel = profile.AccessLevels["premium"]; if (accessLevel != null && accessLevel.IsActive) { // grant access to premium features } }); ``` ### Écouter les mises à jour du statut d'abonnement \{#listening-for-subscription-status-updates\} Chaque fois que l'abonnement d'un utilisateur change, Adapty déclenche un événement. Pour recevoir des messages d'Adapty, vous devez effectuer quelques configurations supplémentaires : :::note Dans le SDK 4.0, les interfaces de listener suivent la convention C# avec préfixe I : implémentez `IAdaptyEventListener` plutôt que `AdaptyEventListener`. Les méthodes restent inchangées. Consultez le [guide de migration](migration-to-unity-sdk-v4). ::: ```csharp showLineNumbers // Extend `AdaptyEventListener ` with `OnLoadLatestProfile ` method: public class AdaptyListener : MonoBehaviour, AdaptyEventListener { public void OnLoadLatestProfile(AdaptyProfile profile) { // handle any changes to subscription state } } ``` Adapty déclenche également un événement au démarrage de l'application. Dans ce cas, le statut d'abonnement mis en cache sera transmis. ### Cache du statut d'abonnement \{#subscription-status-cache\} Le cache implémenté dans le SDK Adapty stocke le statut d'abonnement du profil. Ainsi, même si le serveur est indisponible, les données en cache restent accessibles pour fournir les informations sur le statut d'abonnement du profil. Cependant, il est important de noter qu'il n'est pas possible d'effectuer des requêtes directes sur le cache. Le SDK interroge périodiquement le serveur toutes les minutes pour vérifier s'il existe des mises à jour ou des modifications liées au profil. Si des changements sont détectés, comme de nouvelles transactions ou d'autres mises à jour, ils seront envoyés aux données en cache afin de les maintenir synchronisées avec le serveur. --- # File: unity-deal-with-att --- --- title: "Gérer l'ATT dans le SDK Unity" description: "Démarrez avec Adapty sur Unity pour simplifier la configuration et la gestion des abonnements." --- Si votre application utilise le framework AppTrackingTransparency et présente une demande d'autorisation de suivi à l'utilisateur, vous devez envoyer le [statut d'autorisation](https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager/authorizationstatus/) à Adapty. ```csharp showLineNumbers var builder = new Adapty.ProfileParameters.Builder() .SetAppTrackingTransparencyStatus(IOSAppTrackingTransparencyStatus.Authorized); Adapty.UpdateProfile(builder.Build(), (error) => { if(error != null) { // handle the error } }); ``` :::warning Nous vous recommandons vivement d'envoyer cette valeur le plus tôt possible dès qu'elle change — c'est la seule façon de garantir que les données sont transmises en temps opportun aux intégrations que vous avez configurées. ::: --- # File: kids-mode-unity --- --- title: "Mode Enfants dans le SDK Unity" description: "Activez facilement le Mode Enfants pour respecter les politiques d'Apple et de Google. Pas de collecte d'IDFA, GAID ou de données publicitaires dans le SDK Unity." --- Si votre application Unity est destinée aux enfants, vous devez respecter les politiques d'[Apple](https://developer.apple.com/kids/) et de [Google](https://support.google.com/googleplay/android-developer/answer/9893335). Si vous utilisez le SDK Adapty, quelques étapes simples vous permettront de le configurer pour satisfaire ces politiques et passer les revues des stores. ## Qu'est-ce qui est requis ? \{#whats-required\} Vous devez configurer le SDK pour désactiver la collecte des éléments suivants : - [IDFA (Identifier for Advertisers)](https://en.wikipedia.org/wiki/Identifier_for_Advertisers) (iOS) - [Android Advertising ID (AAID/GAID)](https://support.google.com/googleplay/android-developer/answer/6048248) (Android) - [Adresse IP](https://www.ftc.gov/system/files/ftc_gov/pdf/p235402_coppa_application.pdf) En outre, nous recommandons d'utiliser l'identifiant utilisateur avec précaution. Un identifiant au format `` sera clairement considéré comme une collecte de données personnelles, tout comme l'utilisation d'une adresse e-mail. Pour le mode Enfants, la bonne pratique consiste à utiliser des identifiants aléatoires ou anonymisés (par exemple, des identifiants hachés ou des UUID générés par l'appareil) afin de garantir la conformité. ## Activer le mode Enfants \{#enabling-kids-mode\} ### Mises à jour dans l'Adapty Dashboard Dans l'Adapty Dashboard, vous devez désactiver la collecte des adresses IP. Pour ce faire, accédez à [App settings](https://app.adapty.io/settings/general) et cliquez sur **Disable IP address collection** sous **Collect users' IP address**. ### Mises à jour dans le code de votre application \{#updates-in-your-app-code\} Désactivez la collecte de l'Android Advertising ID et de l'adresse IP lors de l'activation du SDK : ```csharp showLineNumbers title="C#" var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") // highlight-start .SetGoogleAdvertisingIdCollectionDisabled(true) // set to `true` .SetIPAddressCollectionDisabled(true); // set to `true` // highlight-end Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); ``` Sur iOS, vous n'avez pas besoin d'appeler `SetAppleIDFACollectionDisabled` — activer le mode Kids pour le build iOS (voir ci-dessous) désactive automatiquement la collecte des IDFA dans la configuration du SDK. ### Activer le mode enfants pour la build iOS \{#enable-kids-mode-for-the-ios-build\} :::important Sur iOS, le mode enfants est un trait de package Swift nommé `KidsMode`. L'activer compile IDFA, AdSupport et AppTrackingTransparency hors du binaire SDK. Il requiert le SDK 4.0 ou une version ultérieure — qui installe le SDK iOS natif via Swift Package Manager — et **Xcode 26** ou une version ultérieure, car les versions antérieures d'Xcode ne prennent pas en charge les traits de packages Swift. ::: 1. Dans l'éditeur Unity, allez dans **Player Settings** > **Other Settings** et ajoutez `ADAPTY_KIDS_MODE` dans **Scripting Define Symbols** pour la plateforme iOS. 2. Compilez votre projet pour iOS normalement. Adapty active le trait `KidsMode` sur la référence de package AdaptySDK-iOS dans le projet Xcode généré, et force `apple_idfa_collection_disabled` dans la configuration d'exécution. :::warning Ajoutez le define dans **Player Settings**, pas dans un profil de build. Les scripting defines d'un profil de build n'atteignent les assemblies Editor qu'après que Unity les recompile, donc un build lancé dans la même session peut produire un binaire qui signale le Kids Mode au runtime tout en continuant à lier IDFA. Adapty fait échouer le build iOS lorsqu'il détecte cet état. `BuildPlayerOptions.extraScriptingDefines` n'est pas pris en charge du tout, car il n'atteint jamais les assemblies Editor. ::: ### Mises à jour de votre manifeste Android \{#updates-in-your-android-manifest\} Si votre application cible **uniquement** les enfants et compile avec Android 13 (API 33) ou version supérieure, Google Play exige que vous ne demandiez pas la permission `AD_ID`. Désactiver la collecte dans la configuration du SDK empêche Adapty de collecter l'identifiant, mais cela ne supprime pas une permission déclarée par un autre plugin via la fusion de manifestes. Pour supprimer cette permission, activez **Custom Main Manifest** dans **Player Settings** > **Publishing Settings**, puis ajoutez ce qui suit à l'intérieur de l'élément `` du fichier `Assets/Plugins/Android/AndroidManifest.xml`. L'élément `` doit déclarer `xmlns:tools="http://schemas.android.com/tools"`. ```xml showLineNumbers title="AndroidManifest.xml" ``` Si votre application Unity est destinée aux enfants, vous devez respecter les politiques d'[Apple](https://developer.apple.com/kids/) et de [Google](https://support.google.com/googleplay/android-developer/answer/9893335). Si vous utilisez le SDK Adapty, quelques étapes simples vous permettront de le configurer pour satisfaire ces politiques et passer les revues des stores. ## Qu'est-ce qui est requis ? \{#whats-required\} Vous devez configurer le SDK pour désactiver la collecte des éléments suivants : - [IDFA (Identifier for Advertisers)](https://en.wikipedia.org/wiki/Identifier_for_Advertisers) (iOS) - [Android Advertising ID (AAID/GAID)](https://support.google.com/googleplay/android-developer/answer/6048248) (Android) - [Adresse IP](https://www.ftc.gov/system/files/ftc_gov/pdf/p235402_coppa_application.pdf) En outre, nous vous recommandons d'utiliser le customer user ID avec précaution. Un identifiant au format `` sera inévitablement considéré comme une collecte de données personnelles, tout comme l'utilisation d'une adresse e-mail. Pour le mode Enfants, la bonne pratique consiste à utiliser des identifiants aléatoires ou anonymisés (par exemple, des ID hachés ou des UUID générés par l'appareil) afin de garantir la conformité. ## Activation du mode enfants \{#enabling-kids-mode\} ### Mises à jour dans l'Adapty Dashboard Dans l'Adapty Dashboard, vous devez désactiver la collecte des adresses IP. Pour ce faire, rendez-vous dans [App settings](https://app.adapty.io/settings/general) et cliquez sur **Disable IP address collection** sous **Collect users' IP address**. ### Mises à jour dans le code de votre application \{#updates-in-your-app-code\} Désactivez la collecte de l'Android Advertising ID et de l'adresse IP lors de l'activation du SDK : ```csharp showLineNumbers title="C#" var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") // highlight-start .SetGoogleAdvertisingIdCollectionDisabled(true) // set to `true` .SetIPAddressCollectionDisabled(true); // set to `true` // highlight-end Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); ``` ### Activer le Mode Enfants pour le build iOS \{#enable-kids-mode-for-the-ios-build\} La compilation sans IDFA ni AdSupport dans le binaire iOS nécessite Adapty Unity SDK 4.0 ou une version ultérieure. Effectuez la mise à niveau en suivant le [guide de migration](migration-to-unity-sdk-v4), puis suivez les instructions SDK 4.0 sur cette page. Avec le SDK 3.x, vous pouvez toujours désactiver la collecte IDFA dans la configuration du SDK avec `SetAppleIDFACollectionDisabled(true)`, mais le code IDFA et AdSupport reste dans le binaire. Pour les options de configuration natives, consultez [Mode Enfants dans le SDK iOS](kids-mode) et [Mode Enfants dans le SDK Android](kids-mode-android). --- # File: unity-onboardings --- --- title: "Onboardings dans le SDK Unity" description: "Découvrez comment utiliser les onboardings dans votre application Unity avec le SDK Adapty." --- :::warning **Les onboardings sont dépréciés dans le SDK v4 et seront supprimés dans une prochaine version.** Ils ne reçoivent plus de correctifs ni d'améliorations. Utilisez les [flows](unity-get-pb-paywalls) à la place : contrairement aux onboardings, qui s'exécutent dans une WebView, les flows s'affichent nativement sur l'appareil — vous offrant des animations plus fluides, un look and feel natif cohérent, des temps de chargement plus rapides et aucune dépendance à un runtime WebView. Consultez [Récupérer les flows et paywalls](unity-get-pb-paywalls) et [Afficher les flows et paywalls](unity-present-paywalls) pour commencer. ::: --- # File: unity-get-onboardings --- --- title: "Récupérer les onboardings dans le SDK Unity" description: "Découvrez comment récupérer les onboardings dans Adapty pour Unity." --- :::warning **Les onboardings sont dépréciés dans le SDK v4 et seront supprimés dans une prochaine version.** Ils ne reçoivent plus de correctifs ni d'améliorations. Utilisez les [flows](unity-get-pb-paywalls) à la place : contrairement aux onboardings, qui s'exécutent dans une WebView, les flows s'affichent nativement sur l'appareil — offrant des animations plus fluides, un rendu natif cohérent, des temps de chargement plus rapides et aucune dépendance à un runtime WebView. Consultez [Obtenir des flows et paywalls](unity-get-pb-paywalls) et [Afficher des flows et paywalls](unity-present-paywalls) pour commencer. ::: Après avoir [conçu la partie visuelle de votre onboarding](design-onboarding) avec le builder dans l'Adapty Dashboard, vous pouvez l'afficher dans votre application Unity. La première étape consiste à récupérer l'onboarding associé au placement et sa configuration d'affichage, comme décrit ci-dessous. Avant de commencer, assurez-vous que : 1. Vous avez installé le [SDK Adapty pour Unity](sdk-installation-unity) version 3.14.0 ou supérieure. 2. Vous avez [créé un onboarding](create-onboarding). 3. Vous avez ajouté l'onboarding à un [placement](placements). ## Récupérer l'onboarding et créer la vue \{#fetch-onboarding-and-create-view\} Lorsque vous créez un [onboarding](onboardings) avec notre builder no-code, il est stocké sous forme de conteneur avec une configuration que votre application doit récupérer et afficher. Ce conteneur gère l'ensemble de l'expérience : le contenu affiché, la façon dont il est présenté, et la manière dont les interactions utilisateur (comme les réponses à des quiz ou les saisies de formulaire) sont traitées. Le conteneur assure également le suivi automatique des événements analytiques, ce qui vous évite d'implémenter un suivi de vue séparé. Pour de meilleures performances, récupérez la configuration de l'onboarding tôt afin de laisser suffisamment de temps aux images pour se télécharger avant de les afficher aux utilisateurs. Pour obtenir un onboarding, utilisez la méthode `GetOnboarding` : ```csharp showLineNumbers Adapty.GetOnboarding("YOUR_PLACEMENT_ID", (onboarding, error) => { if (error != null) { // handle the error return; } // the requested onboarding }); ``` Paramètres : | Paramètre | Présence | Description | |---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **placementId** | requis | L'identifiant du [placement](placements) souhaité. Il s'agit de la valeur que vous avez indiquée lors de la création d'un placement dans l'Adapty Dashboard. | | **locale** |

optionnel

défaut : `en`

|

L'identifiant de la localisation de l'onboarding. Ce paramètre doit être un code de langue composé d'un ou deux sous-tags séparés par le caractère moins (**-**). Le premier sous-tag correspond à la langue, le second à la région.

Exemple : `en` désigne l'anglais, `pt-br` représente le portugais brésilien.

Consultez [Localisations et codes de langue](unity-localizations-and-locale-codes) pour plus d'informations sur les codes de langue et leur utilisation recommandée.

| | **fetchPolicy** | défaut : `.reloadRevalidatingCacheData` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option, car elle garantit que vos utilisateurs disposent toujours des données les plus récentes.

Cependant, si vous pensez que vos utilisateurs ont une connexion internet instable, envisagez d'utiliser `.returnCacheDataElseLoad` pour renvoyer les données en cache si elles existent. Dans ce cas, les utilisateurs pourraient ne pas obtenir les toutes dernières données, mais les temps de chargement seront plus rapides, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, il est donc sûr de l'utiliser durant la session pour éviter des requêtes réseau.

Notez que le cache reste intact après le redémarrage de l'application et n'est effacé qu'à la désinstallation de celle-ci ou lors d'un nettoyage manuel.

Le SDK Adapty stocke les onboardings localement sur deux couches : le cache mis à jour régulièrement décrit ci-dessus, et les onboardings de secours. Nous utilisons également un CDN pour récupérer les onboardings plus rapidement, ainsi qu'un serveur de secours indépendant en cas d'inaccessibilité du CDN. Ce système est conçu pour vous garantir toujours la dernière version de vos onboardings, tout en assurant une fiabilité même lorsque la connexion internet est limitée.

| | **loadTimeout** | défaut : 5 sec |

Cette valeur limite le délai d'attente de cette méthode. Si le délai est dépassé, les données en cache ou le fallback local sont renvoyés.

Notez que dans de rares cas, cette méthode peut expirer légèrement après le délai indiqué dans `loadTimeout`, car l'opération peut impliquer différentes requêtes en coulisses.

| Paramètres de réponse : | Paramètre | Description | |:----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Onboarding | Un objet [`AdaptyOnboarding`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_onboarding.html) contenant : l'identifiant et la configuration de l'onboarding, le Remote Config, ainsi que plusieurs autres propriétés. | Après avoir récupéré l'onboarding, appelez la méthode `CreateOnboardingView`. :::warning Le résultat de la méthode `CreateOnboardingView` ne peut être utilisé qu'une seule fois. Si vous en avez besoin à nouveau, appelez de nouveau la méthode `CreateOnboardingView`. L'appeler deux fois sans recréer peut entraîner l'erreur `AdaptyUIError.viewAlreadyPresented`. ::: ```csharp showLineNumbers AdaptyUI.CreateOnboardingView(onboarding, (view, error) => { // handle the result }); ``` Paramètres : | Paramètre | Présence | Description | |:---------------| :------------- |:-----------------------------------------------------------------------------| | **onboarding** | requis | Un objet `AdaptyOnboarding` pour obtenir une vue pour l'onboarding souhaité. | | **externalUrlsPresentation** |

optionnel

par défaut : `InAppBrowser`

|

Contrôle la façon dont les liens de l'onboarding sont ouverts. Options disponibles :

- `AdaptyWebPresentation.InAppBrowser` - Ouvre les liens dans un navigateur intégré à l'application (par défaut)

- `AdaptyWebPresentation.ExternalBrowser` - Ouvre les liens dans le navigateur externe de l'appareil

Consultez [Personnaliser l'ouverture des liens dans les onboardings](unity-present-onboardings#customize-how-links-open-in-onboardings) pour des exemples d'utilisation.

| Une fois que vous avez chargé avec succès l'onboarding et sa configuration d'affichage, vous pouvez [le présenter dans votre application mobile](unity-present-onboardings). ## Accélérer la récupération des onboardings avec l'onboarding de l'audience par défaut \{#speed-up-onboarding-fetching-with-default-audience-onboarding\} En général, les onboardings sont récupérés presque instantanément, vous n'avez donc pas à vous soucier d'accélérer ce processus. Cependant, si vous avez de nombreuses audiences et onboardings, et que vos utilisateurs disposent d'une connexion internet faible, la récupération d'un onboarding peut prendre plus de temps que souhaité. Dans ces situations, vous pouvez afficher un onboarding par défaut pour garantir une expérience fluide plutôt que de ne rien afficher du tout. Pour résoudre ce problème, vous pouvez utiliser la méthode `GetOnboardingForDefaultAudience`, qui récupère l'onboarding du placement spécifié pour l'audience **All Users**. Cependant, il est essentiel de comprendre que l'approche recommandée est de récupérer l'onboarding via la méthode `getOnboarding`, comme détaillé dans la section [Récupérer l'onboarding](#fetch-onboarding-and-create-view) ci-dessus. :::warning Préférez `GetOnboarding` à `GetOnboardingForDefaultAudience`, car cette dernière présente des limitations importantes : - **Problèmes de compatibilité** : Peut créer des problèmes lors de la prise en charge de plusieurs versions de l'application, nécessitant soit des conceptions rétrocompatibles, soit d'accepter que les anciennes versions s'affichent incorrectement. - **Pas de personnalisation** : Affiche uniquement le contenu pour l'audience « Tous les utilisateurs », supprimant le ciblage basé sur le pays, l'attribution ou les attributs personnalisés. Si une récupération plus rapide compense ces inconvénients pour votre cas d'utilisation, utilisez `GetOnboardingForDefaultAudience` comme indiqué ci-dessous. Sinon, utilisez `GetOnboarding` comme décrit [ci-dessus](#fetch-onboarding-and-create-view). ::: ```csharp showLineNumbers Adapty.GetOnboardingForDefaultAudience("YOUR_PLACEMENT_ID", (onboarding, error) => { if (error != null) { // handle the error return; } // the requested onboarding }); ``` Paramètres : | Paramètre | Présence | Description | |---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **placementId** | requis | L'identifiant du [Placement](placements) souhaité. C'est la valeur que vous avez spécifiée lors de la création d'un placement dans l'Adapty Dashboard. | | **locale** |

optionnel

défaut : `en`

|

L'identifiant de la localisation de l'onboarding. Ce paramètre doit être un code de langue composé d'un ou deux sous-tags séparés par le caractère moins (**-**). Le premier sous-tag correspond à la langue, le second à la région.

Exemple : `en` désigne l'anglais, `pt-br` représente le portugais brésilien.

| | **fetchPolicy** | défaut : `.reloadRevalidatingCacheData` |

Par défaut, le SDK tente de charger les données depuis le serveur et renvoie les données en cache en cas d'échec. Nous recommandons cette option car elle garantit que vos utilisateurs obtiennent toujours les données les plus récentes.

Cependant, si vous pensez que vos utilisateurs ont une connexion internet instable, envisagez d'utiliser `.returnCacheDataElseLoad` pour renvoyer les données en cache si elles existent. Dans ce cas, les utilisateurs n'auront peut-être pas les toutes dernières données, mais le chargement sera plus rapide, quelle que soit la qualité de leur connexion. Le cache est mis à jour régulièrement, il est donc sûr de l'utiliser pendant la session pour éviter les requêtes réseau.

Notez que le cache reste intact après le redémarrage de l'application et n'est effacé que lors de la désinstallation ou via un nettoyage manuel.

Le SDK Adapty stocke les onboardings localement en deux couches : le cache mis à jour régulièrement décrit ci-dessus et les onboardings de secours. Nous utilisons également un CDN pour récupérer les onboardings plus rapidement, ainsi qu'un serveur de secours indépendant en cas d'indisponibilité du CDN. Ce système est conçu pour garantir que vous obtenez toujours la dernière version de vos onboardings tout en assurant la fiabilité même lorsque la connexion internet est limitée.

| --- # File: unity-present-onboardings --- --- title: "Présenter les onboardings dans le SDK Unity" description: "Apprenez à présenter les onboardings efficacement pour augmenter vos conversions." --- :::warning **Les onboardings sont dépréciés dans le SDK v4 et seront supprimés dans une prochaine version.** Ils ne reçoivent plus de correctifs ni d'améliorations. Utilisez les [flows](unity-get-pb-paywalls) à la place : contrairement aux onboardings, qui s'exécutent dans une WebView, les flows s'affichent nativement sur l'appareil — offrant des animations plus fluides, un rendu natif cohérent, des temps de chargement plus rapides et aucune dépendance à un runtime WebView. Consultez [Obtenir des flows et paywalls](unity-get-pb-paywalls) et [Afficher des flows et paywalls](unity-present-paywalls) pour commencer. ::: Si vous avez personnalisé un onboarding avec le builder, vous n'avez pas besoin de vous soucier de son rendu dans votre code Unity pour l'afficher à l'utilisateur. Un tel onboarding contient à la fois ce qui doit être affiché et comment cela doit l'être. Avant de commencer, assurez-vous que : 1. Vous avez installé [Adapty Unity SDK](sdk-installation-unity) 3.14.0 ou version ultérieure. 2. Vous avez [créé un onboarding](create-onboarding). 3. Vous avez ajouté l'onboarding à un [placement](placements). Pour afficher un onboarding, utilisez la méthode `view.Present()` sur la `view` créée par la méthode `CreateOnboardingView`. Chaque `view` ne peut être utilisée qu'une seule fois. Si vous devez afficher le paywall à nouveau, appelez `CreateOnboardingView` une nouvelle fois pour créer une nouvelle instance de `view`. :::warning Réutiliser la même `view` sans la recréer peut entraîner une erreur `AdaptyUIError.viewAlreadyPresented`. ::: ```csharp showLineNumbers title="Unity" view.Present((presentError) => { if (presentError != null) { // handle the error } }; ``` ## Configurer le style de présentation iOS \{#configure-ios-presentation-style\} Configurez la façon dont l'onboarding est présenté sur iOS en passant le paramètre `iosPresentationStyle` à la méthode `Present()`. Le paramètre accepte les valeurs `AdaptyUIIOSPresentationStyle.FullScreen` (par défaut) ou `AdaptyUIIOSPresentationStyle.PageSheet`. ```csharp showLineNumbers title="Unity" view.Present(AdaptyUIIOSPresentationStyle.PageSheet, (error) => { // handle the error }); ``` ## Personnaliser l'ouverture des liens dans les onboardings \{#customize-how-links-open-in-onboardings\} :::important La personnalisation de l'ouverture des liens dans les onboardings est prise en charge à partir du SDK Adapty v3.15. ::: Par défaut, les liens dans les onboardings s'ouvrent dans un navigateur intégré à l'application, offrant une expérience fluide en affichant les pages web directement dans votre application sans changer d'app. Pour ouvrir les liens dans un navigateur externe à la place, passez `AdaptyWebPresentation.ExternalBrowser` à la méthode `CreateOnboardingView` : ```csharp showLineNumbers title="Unity" AdaptyUI.CreateOnboardingView( onboarding, AdaptyWebPresentation.ExternalBrowser, // default — InAppBrowser (view, error) => { if (error != null) { // handle the error return; } // present the onboarding view view.Present((presentError) => { if (presentError != null) { // handle the error } }); } ); ``` Options disponibles : - `AdaptyWebPresentation.InAppBrowser` - Ouvre les liens dans un navigateur intégré à l'application (par défaut) - `AdaptyWebPresentation.ExternalBrowser` - Ouvre les liens dans le navigateur externe de l'appareil --- # File: unity-handling-onboarding-events --- --- title: "Gérer les événements d'onboarding dans le SDK Unity" description: "Gérez les événements liés à l'onboarding dans Unity avec Adapty." --- :::warning **Les onboardings sont dépréciés dans le SDK v4 et seront supprimés dans une prochaine version.** Ils ne reçoivent plus de correctifs ni d'améliorations. Utilisez les [flows](unity-get-pb-paywalls) à la place : contrairement aux onboardings, qui s'exécutent dans une WebView, les flows s'affichent nativement sur l'appareil — offrant des animations plus fluides, un rendu natif cohérent, des temps de chargement plus rapides, et aucune dépendance à un runtime WebView. Consultez [Obtenir des flows & paywalls](unity-get-pb-paywalls) et [Afficher des flows & paywalls](unity-present-paywalls) pour commencer. ::: Avant de commencer, assurez-vous que : 1. Vous avez installé [le SDK Adapty Unity](sdk-installation-unity) version 3.14.0 ou ultérieure. 2. Vous avez [créé un onboarding](create-onboarding). 3. Vous avez ajouté l'onboarding à un [placement](placements). Les onboardings configurés avec le builder génèrent des événements auxquels votre application peut réagir. Découvrez ci-dessous comment gérer ces événements. Pour contrôler ou surveiller les processus qui se déroulent sur l'écran d'onboarding dans votre application Unity, implémentez l'interface `AdaptyOnboardingsEventsListener`. :::note Dans le SDK 4.0, les interfaces listener suivent la convention de préfixe C# `I-` : implémentez `IAdaptyOnboardingsEventsListener` plutôt que `AdaptyOnboardingsEventsListener`. Les méthodes restent inchangées. Consultez le [guide de migration](migration-to-unity-sdk-v4). ::: ## Actions personnalisées \{#custom-actions\} Dans le builder, vous pouvez ajouter une action **personnalisée** à un bouton et lui attribuer un identifiant. Ensuite, vous pouvez utiliser cet ID dans votre code et le gérer comme une action personnalisée. Par exemple, si un utilisateur appuie sur un bouton personnalisé, comme **Login** ou **Allow notifications**, la méthode `OnboardingViewOnCustomAction` sera déclenchée avec le paramètre `actionId` correspondant à l'**Action ID** défini dans le builder. Vous pouvez créer vos propres IDs, comme "allowNotifications". Pour gérer les événements d'onboarding, implémentez l'interface `AdaptyOnboardingsEventsListener` : ```csharp showLineNumbers title="Unity" public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener { void Start() { Adapty.SetOnboardingsEventsListener(this); } public void OnboardingViewOnCustomAction( AdaptyUIOnboardingView view, AdaptyUIOnboardingMeta meta, string actionId ) { if (actionId == "allowNotifications") { // request notification permissions } } public void OnboardingViewDidFailWithError( AdaptyUIOnboardingView view, AdaptyError error ) { // handle errors } // Implement other required interface methods (see examples below) } ```
Exemple d'événement (Cliquez pour développer) ```json { "actionId": "allowNotifications", "meta": { "onboardingId": "onboarding_123", "screenClientId": "profile_screen", "screenIndex": 0, "screensTotal": 3 } } ```
## Fermeture de l'onboarding \{#closing-onboarding\} L'onboarding est considéré comme fermé lorsqu'un utilisateur appuie sur un bouton auquel l'action **Close** est assignée. :::important Notez que vous devez gérer ce qui se passe lorsqu'un utilisateur ferme l'onboarding. Par exemple, vous devez arrêter d'afficher l'onboarding lui-même. ::: Implémentez la méthode `OnboardingViewOnCloseAction` dans votre classe : ```csharp showLineNumbers title="Unity" public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener { public void OnboardingViewOnCloseAction( AdaptyUIOnboardingView view, AdaptyUIOnboardingMeta meta, string actionId ) { view.Dismiss((error) => { if (error != null) { // handle the error } }); } // ... other interface methods } ```
Exemple d'événement (cliquez pour développer) ```json { "action_id": "close_button", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "final_screen", "screen_index": 3, "total_screens": 4 } } ```
## Ouverture d'un paywall \{#opening-a-paywall\} :::tip Gérez cet événement pour ouvrir un paywall si vous souhaitez l'ouvrir à l'intérieur de l'onboarding. Si vous souhaitez ouvrir un paywall après sa fermeture, il existe une méthode plus directe : gérez [`OnboardingViewOnCloseAction`](#closing-onboarding) et ouvrez un paywall sans vous appuyer sur les données de l'événement. ::: La façon la plus fluide de travailler avec les paywalls dans les onboardings est de faire correspondre l'ID d'action à l'ID de placement du paywall. Ainsi, après l'événement `OnboardingViewOnPaywallAction`, vous pouvez utiliser l'ID de placement pour récupérer et ouvrir immédiatement le paywall. :::note Notez que, pour iOS, une seule vue (paywall ou onboarding) peut être affichée à l'écran à la fois. Si vous affichez un paywall par-dessus un onboarding, vous ne pouvez pas contrôler l'onboarding en arrière-plan par programmation. Tenter de fermer l'onboarding fermera le paywall à la place, laissant l'onboarding visible. Pour éviter cela, fermez toujours la vue de l'onboarding avant d'afficher le paywall. ::: ```csharp showLineNumbers title="Unity" public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener { public void OnboardingViewOnPaywallAction( AdaptyUIOnboardingView view, AdaptyUIOnboardingMeta meta, string actionId ) { // Dismiss onboarding before presenting paywall view.Dismiss((dismissError) => { if (dismissError != null) { // handle the error return; } Adapty.GetPaywall(actionId, (paywall, error) => { if (error != null) { // handle the error return; } AdaptyUI.CreatePaywallView(paywall, (paywallView, createError) => { if (createError != null) { // handle the error return; } paywallView.Present((presentError) => { if (presentError != null) { // handle the error } }); }); }); }); } // ... other interface methods } ```
Exemple d'événement (Cliquez pour développer) ```json { "action_id": "premium_offer_1", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "pricing_screen", "screen_index": 2, "total_screens": 4 } } ```
## Fin du chargement de l'onboarding \{#finishing-loading-onboarding\} Lorsque le chargement d'un onboarding se termine, implémentez la méthode `OnboardingViewDidFinishLoading` : ```csharp showLineNumbers title="Unity" public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener { public void OnboardingViewDidFinishLoading( AdaptyUIOnboardingView view, AdaptyUIOnboardingMeta meta ) { // handle loading completion } // ... other interface methods } ```
Exemple d'événement (Cliquez pour développer) ```json { "meta": { "onboarding_id": "onboarding_123", "screen_cid": "welcome_screen", "screen_index": 0, "total_screens": 4 } } ```
## Suivi de la navigation \{#tracking-navigation\} La méthode `OnboardingViewOnAnalyticsEvent` est appelée lorsque divers événements analytiques se produisent au cours du flow d'onboarding. L'objet `analyticsEvent` peut être l'un des types suivants : |Type | Description | |------------|-------------| | `AdaptyOnboardingsAnalyticsEventOnboardingStarted` | Quand l'onboarding a été chargé | | `AdaptyOnboardingsAnalyticsEventScreenPresented` | Quand un écran est affiché | | `AdaptyOnboardingsAnalyticsEventScreenCompleted` | Quand un écran est complété. Inclut un `ElementId` optionnel (identifiant de l'élément complété) et une `Reply` optionnelle (réponse de l'utilisateur). Déclenché quand l'utilisateur effectue une action pour quitter l'écran. | | `AdaptyOnboardingsAnalyticsEventSecondScreenPresented` | Quand le deuxième écran est affiché | | `AdaptyOnboardingsAnalyticsEventUserEmailCollected` | Déclenché quand l'e-mail de l'utilisateur est collecté via le champ de saisie | | `AdaptyOnboardingsAnalyticsEventOnboardingCompleted` | Déclenché quand un utilisateur atteint un écran avec l'ID `final`. Si vous avez besoin de cet événement, [assignez l'ID `final` au dernier écran](design-onboarding). | | `AdaptyOnboardingsAnalyticsEventUnknown` | Pour tout type d'événement non reconnu. Inclut `Name` (le nom de l'événement inconnu) et `meta` (métadonnées supplémentaires) | Chaque événement inclut des informations `meta` contenant : | Champ | Description | |------------|-------------| | `OnboardingId` | Identifiant unique du flow d'onboarding | | `ScreenClientId` | Identifiant de l'écran actuel | | `ScreenIndex` | Position de l'écran actuel dans le flow | | `ScreensTotal` | Nombre total d'écrans dans le flow | Voici un exemple d'utilisation des événements analytics pour le suivi : ```csharp showLineNumbers title="Unity" public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener { public void OnboardingViewOnAnalyticsEvent( AdaptyUIOnboardingView view, AdaptyUIOnboardingMeta meta, AdaptyOnboardingsAnalyticsEvent analyticsEvent ) { switch (analyticsEvent) { case AdaptyOnboardingsAnalyticsEventOnboardingStarted: // track onboarding start TrackEvent("onboarding_started", meta); break; case AdaptyOnboardingsAnalyticsEventScreenPresented: // track screen presentation TrackEvent("screen_presented", meta); break; case AdaptyOnboardingsAnalyticsEventScreenCompleted screenCompleted: // track screen completion with user response TrackEvent("screen_completed", meta, screenCompleted.ElementId, screenCompleted.Reply); break; case AdaptyOnboardingsAnalyticsEventOnboardingCompleted: // track successful onboarding completion TrackEvent("onboarding_completed", meta); break; case AdaptyOnboardingsAnalyticsEventUnknown unknownEvent: // handle unknown events TrackEvent(unknownEvent.Name, meta); break; // handle other cases as needed } } // ... other interface methods } ``` :::note La méthode `TrackEvent` est un espace réservé que vous devez implémenter vous-même pour envoyer des données analytiques à votre service d'analyse préféré. :::
Exemples d'événements (Cliquez pour développer) ```javascript // onboardingStarted { "name": "onboarding_started", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "welcome_screen", "screen_index": 0, "total_screens": 4 } } // screenPresented { "name": "screen_presented", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "interests_screen", "screen_index": 2, "total_screens": 4 } } // screenCompleted { "name": "screen_completed", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "profile_screen", "screen_index": 1, "total_screens": 4 }, "params": { "element_id": "profile_form", "reply": "success" } } // secondScreenPresented { "name": "second_screen_presented", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "profile_screen", "screen_index": 1, "total_screens": 4 } } // userEmailCollected { "name": "user_email_collected", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "profile_screen", "screen_index": 1, "total_screens": 4 } } // onboardingCompleted { "name": "onboarding_completed", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "final_screen", "screen_index": 3, "total_screens": 4 } } ```
--- # File: unity-onboarding-input --- --- title: "Traiter les données des onboardings dans le SDK Unity" description: "Enregistrez et utilisez les données des onboardings dans votre application Unity avec le SDK Adapty." --- :::warning **Les onboardings sont obsolètes dans le SDK v4 et seront supprimés dans une prochaine version.** Ils ne reçoivent plus de correctifs ni d'améliorations. Utilisez les [flows](unity-get-pb-paywalls) à la place : contrairement aux onboardings, qui s'exécutent dans une WebView, les flows s'affichent nativement sur l'appareil — offrant des animations plus fluides, un aspect natif cohérent, des temps de chargement plus rapides et aucune dépendance à l'exécution WebView. Consultez [Obtenir les flows et paywalls](unity-get-pb-paywalls) et [Afficher les flows et paywalls](unity-present-paywalls) pour commencer. ::: Lorsque vos utilisateurs répondent à une question du quiz ou saisissent leurs données dans un champ de saisie, la méthode `OnboardingViewOnStateUpdatedAction` est invoquée. Vous pouvez enregistrer ou traiter le type de champ dans votre code. Implémentez la méthode `OnboardingViewOnStateUpdatedAction` dans votre classe : :::note Dans le SDK 4.0, les interfaces listener suivent la convention C# avec le préfixe I : implémentez `IAdaptyOnboardingsEventsListener` au lieu de `AdaptyOnboardingsEventsListener`. Les méthodes restent inchangées. Consultez le [guide de migration](migration-to-unity-sdk-v4). ::: ```csharp showLineNumbers title="Unity" public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener { public void OnboardingViewOnStateUpdatedAction( AdaptyUIOnboardingView view, AdaptyUIOnboardingMeta meta, string elementId, AdaptyOnboardingsStateUpdatedParams @params ) { switch (@params) { case AdaptyOnboardingsSelectParams selectParams: // handle single selection break; case AdaptyOnboardingsMultiSelectParams multiSelectParams: // handle multiple selections break; case AdaptyOnboardingsInputParams inputParams: // handle text input break; case AdaptyOnboardingsDatePickerParams datePickerParams: // handle date selection break; } } // ... other interface methods } ``` Les paramètres incluent : | Paramètre | Description | |----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `elementId` | Identifiant unique de l'élément de saisie. Vous pouvez l'utiliser pour associer des questions à des réponses lors de leur enregistrement. | | `@params` | L'objet de données saisies par l'utilisateur. Peut être de l'un des types suivants. | | `AdaptyOnboardingsSelectParams` | Sélection unique parmi des options. Contient `Id`, `Value`, `Label` | | `AdaptyOnboardingsMultiSelectParams` | Sélections multiples parmi des options. Contient une liste de `Params` (chacun avec `Id`, `Value`, `Label`)
• `input` : objet avec `type`, `value`
• `datePicker` : objet avec `day`, `month`, `year` | | `AdaptyOnboardingsInputParams` | Champ de saisie de texte. Contient `Input` qui peut être `AdaptyOnboardingsTextInput`, `AdaptyOnboardingsEmailInput` ou `AdaptyOnboardingsNumberInput` | | `AdaptyOnboardingsDatePickerParams` | Sélection de date. Contient `Day`, `Month`, `Year` nullables |
Exemples de données sauvegardées (peuvent différer selon votre implémentation) ```javascript // Example of a saved select action { "elementId": "preference_selector", "meta": { "onboardingId": "onboarding_123", "screenClientId": "preferences_screen", "screenIndex": 1, "screensTotal": 3 }, "params": { "type": "select", "value": { "id": "option_1", "value": "premium", "label": "Premium Plan" } } } // Example of a saved multi-select action { "elementId": "interests_selector", "meta": { "onboardingId": "onboarding_123", "screenClientId": "interests_screen", "screenIndex": 2, "screensTotal": 3 }, "params": { "type": "multiSelect", "value": [ { "id": "interest_1", "value": "sports", "label": "Sports" }, { "id": "interest_2", "value": "music", "label": "Music" } ] } } // Example of a saved input action { "elementId": "name_input", "meta": { "onboardingId": "onboarding_123", "screenClientId": "profile_screen", "screenIndex": 0, "screensTotal": 3 }, "params": { "type": "input", "value": { "type": "text", "value": "John Doe" } } } // Example of a saved date picker action { "elementId": "birthday_picker", "meta": { "onboardingId": "onboarding_123", "screenClientId": "profile_screen", "screenIndex": 0, "screensTotal": 3 }, "params": { "type": "datePicker", "value": { "day": 15, "month": 6, "year": 1990 } } } ```
## Cas d'utilisation \{#use-cases\} ### Enrichir les profils utilisateur avec des données \{#enrich-user-profiles-with-data\} Si vous souhaitez lier immédiatement les données saisies au profil utilisateur et éviter de lui poser deux fois les mêmes questions, vous devez [mettre à jour le profil utilisateur](unity-setting-user-attributes) avec ces données lors du traitement de l'action. Par exemple, vous demandez aux utilisateurs de saisir leur nom dans le champ texte avec l'ID `name`, et vous souhaitez définir la valeur de ce champ comme prénom de l'utilisateur. Vous leur demandez également de saisir leur adresse e-mail dans le champ `email`. Dans le code de votre application, cela peut ressembler à ceci : ```csharp showLineNumbers title="Unity" public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener { public void OnboardingViewOnStateUpdatedAction( AdaptyUIOnboardingView view, AdaptyUIOnboardingMeta meta, string elementId, AdaptyOnboardingsStateUpdatedParams @params ) { if (@params is AdaptyOnboardingsInputParams inputParams) { var builder = new AdaptyProfileParameters.Builder(); switch (elementId) { case "name": if (inputParams.Input is AdaptyOnboardingsTextInput textInput) { builder.SetFirstName(textInput.Value); } break; case "email": if (inputParams.Input is AdaptyOnboardingsEmailInput emailInput) { builder.SetEmail(emailInput.Value); } break; } Adapty.UpdateProfile(builder.Build(), (error) => { if (error != null) { // handle the error } }); } } // ... other interface methods } ``` ### Personnaliser les paywalls selon les réponses \{#customize-paywalls-based-on-answers\} Grâce aux quiz dans les onboardings, vous pouvez également personnaliser les paywalls affichés aux utilisateurs après qu'ils ont terminé l'onboarding. Par exemple, vous pouvez interroger les utilisateurs sur leur expérience sportive et afficher différents CTA et produits à différents groupes d'utilisateurs. 1. [Ajoutez un quiz](onboarding-quizzes) dans le constructeur d'onboarding et attribuez des IDs explicites à ses options. 2. Traitez les réponses au quiz selon leurs IDs et [définissez des attributs personnalisés](unity-setting-user-attributes) pour les utilisateurs. ```csharp showLineNumbers title="Unity" public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener { public void OnboardingViewOnStateUpdatedAction( AdaptyUIOnboardingView view, AdaptyUIOnboardingMeta meta, string elementId, AdaptyOnboardingsStateUpdatedParams @params ) { if (@params is AdaptyOnboardingsSelectParams selectParams) { var builder = new AdaptyProfileParameters.Builder(); switch (elementId) { case "experience": // set custom attribute 'experience' with the selected value (beginner, amateur, pro) builder.SetCustomStringAttribute("experience", selectParams.Value); break; } Adapty.UpdateProfile(builder.Build(), (error) => { if (error != null) { // handle the error } }); } } // ... other interface methods } ``` 3. [Créez des segments](segments) pour chaque valeur d'attribut personnalisé. 4. Créez un [placement](placements) et ajoutez des [audiences](audience) pour chaque segment créé. 5. [Affichez un paywall](unity-paywalls) pour le placement dans le code de votre application. Si votre onboarding comporte un bouton qui ouvre un paywall, implémentez le code du paywall en tant que [réponse à l'action de ce bouton](unity-handling-onboarding-events#opening-a-paywall). --- # File: unity-best-practices --- --- title: "Meilleures pratiques avec le SDK Unity" description: "Modèles de référence pour intégrer le SDK Adapty dans Unity — ordre des appels, gestion des erreurs et autres règles de production." --- --- # File: unity-sdk-call-order --- --- title: "Ordre d'appel dans le SDK Unity" description: "Évitez la perte d'accès premium, les attributions manquantes et les erreurs intermittentes #2002 en appelant les méthodes du SDK Adapty dans le bon ordre." --- `Adapty.Activate()` doit se terminer avant tout autre appel à une méthode du SDK Adapty. Tant que son callback de complétion n'a pas été déclenché, le SDK n'a aucun état. Tout appel effectué avant ou en parallèle de `Activate()` échoue avec [`#2002 notActivated`](unity-handle-errors#custom-network-codes). Si votre application authentifie les utilisateurs et que vous collectez un identifiant utilisateur client après le lancement, appelez `Adapty.Identify()` à ce moment-là. N'appelez pas les méthodes liées aux actions utilisateur avant que le callback `Identify` ne se déclenche. Les appels qui entrent en concurrence avec lui échouent soit avec [`#3006 profileWasChanged`](unity-handle-errors#custom-network-codes), soit atterrissent sur le profil anonyme créé lors de l'activation. Dans ce cas, l'attribution, les identifiants MMP tels que `appsflyer_id` et la propriété de l'installation ne sont pas toujours transférés vers le profil identifié. Si votre application n'authentifie pas les utilisateurs, ignorez `Identify` et continuez à travailler avec le profil anonyme. Les SDK MMP et analytics (AppsFlyer, Adjust, Branch, PostHog) suivent la même règle. Initialisez-les en premier et attendez leurs callbacks d'UID avant d'appeler `Adapty.Activate`. Sinon, l'ID MMP est associé à un profil anonyme éphémère et n'est pas toujours transféré au profil identifié. Pour les spécificités d'AppsFlyer, consultez [AppsFlyer](appsflyer). ## L'ordre correct \{#the-correct-order\} Votre parcours dépend de deux choses : quand vous connaissez l'identifiant utilisateur client, et si vous utilisez un MMP ou un SDK d'analyse. - **Étapes 2 et 5** : Obligatoires pour chaque application. Activez le SDK, puis appelez les méthodes SDK. - **Étapes 1 et 3** : Requises uniquement si vous intégrez un MMP ou un SDK d'analyse (AppsFlyer, Adjust, Branch, PostHog). - **Étape 4** : Requise uniquement si votre application authentifie les utilisateurs et collecte l'identifiant utilisateur client après le lancement. Si vous disposez de l'identifiant utilisateur au lancement de l'application, passez-le directement dans `Activate()` (étape 2a). Ce chemin ne crée jamais de profil anonyme, donc l'étape 4 est inutile. | Étape | Appel | Quand | Notes | |------|---------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| | 1 | Initialisez votre MMP ou SDK analytics (AppsFlyer, Adjust, PostHog, Branch) | Au lancement de l'app, en premier | Attendez le callback UID du MMP, par exemple `getAppsFlyerId`. | | 2a | `Adapty.Activate(builder.Build(), ...)` avec `SetCustomerUserId` défini sur le builder | Au lancement de l'app, après l'étape 1, si vous disposez de l'ID utilisateur client | Recommandé. Aucun profil anonyme n'est jamais créé. | | 2b | `Adapty.Activate(builder.Build(), ...)` sans `SetCustomerUserId` | Au lancement de l'app, après l'étape 1, si vous n'avez pas l'ID utilisateur client (ou ne le collectez jamais) | Adapty crée un profil anonyme. | | 3 | `Adapty.SetIntegrationIdentifier(key, value, callback)` pour chaque MMP | Après l'étape 2, avant tout appel déclenché par une action utilisateur | Nécessaire pour que les IDs MMP soient associés au bon profil. | | 4 | `Adapty.Identify("YOUR_USER_ID", callback)` | Après l'étape 3 (ou l'étape 2 si pas de MMP), avant l'étape 5 — uniquement sur le chemin 2b avec authentification | Attendez le callback de fin. Des appels simultanés pendant `Identify` produisent `#3006 profileWasChanged`. | | 5 | `GetPaywall` (`GetFlow` dans le SDK v4), `GetPaywallProducts`, `RestorePurchases`, `MakePurchase`, `UpdateAttribution`, `UpdateProfile` | Après l'étape 4 si vous appelez `Identify` ; sinon après l'étape 3 (ou l'étape 2 si pas de MMP) | Ces appels nécessitent un profil stable. | :::important Ignorer ces étapes entraîne une perte d'accès premium pour les utilisateurs qui reviennent, l'absence d'`appsflyer_id` sur les profils, et des paywalls renvoyés pour la mauvaise audience. ::: ## Installations via web2app et web-funnel \{#web2app-and-web-funnel-installs\} Si des utilisateurs achètent via un checkout web (Stripe, Paddle) puis installent l'application native, le premier `Activate()` du terminal crée un nouveau profil anonyme. Ce profil n'est pas lié au profil web. Si vous pouvez résoudre l'ID utilisateur client avant le lancement de l'application (depuis votre flow d'authentification ou le referrer d'installation), passez-le directement dans `Activate()`. Dans le cas contraire, l'achat web reste invisible sur le terminal jusqu'à ce que vous appeliez `Identify("YOUR_USER_ID")` puis `RestorePurchases`. Pour les métadonnées à envoyer avec chaque checkout web, consultez : - [Stripe](stripe) - [Paddle](paddle) --- # File: unity-optimize-paywall-fetching --- --- title: "Optimiser la récupération des paywalls dans le SDK Unity" description: "Récupérez les paywalls Adapty de manière fiable : timing, mise en cache et patterns de secours pour Unity." --- Une récupération de paywall fiable dans Unity fait trois choses : s'affiche rapidement, renvoie le paywall ciblé par audience et bascule gracieusement sur un fallback quand le réseau est lent. Les règles ci-dessous couvrent le timing, la mise en cache et les patterns de secours pour y parvenir. :::tip Les règles supposent que `Adapty.Activate()` et `Adapty.Identify()` ont déjà été résolus. Voir [Ordre des appels dans le SDK Unity](unity-sdk-call-order). ::: Les conseils ci-dessous utilisent les noms de méthodes de la v3. Dans le SDK v4, `GetPaywall` est renommé en `GetFlow` (voir le [guide de migration](migration-to-unity-sdk-v4)) — toutes les règles s'appliquent sans changement. ## Règles et pièges \{#rules-and-pitfalls\} | À faire | À ne pas faire | Pourquoi | |---|---|---| | Récupérez le placement que vous êtes sur le point d'afficher. | Pré-charger tous les placements simultanément au démarrage. | Le pré-chargement en masse bloque le thread principal et provoque un écran noir pendant la rafale. | | Récupérez `GetPaywall` après que l'attribution a eu le temps de se résoudre — par exemple, 1 à 2 secondes après `Activate` ou après le déclenchement de `OnLoadLatestProfile`. | Appeler `GetPaywall` dans `Awake()`. | L'attribution n'est pas encore arrivée. Le paywall est résolu par rapport à l'audience par défaut et contourne silencieusement les segments et la personnalisation ASA. | | Définissez un `loadTimeout` et configurez un [paywall de secours](fallback-paywalls) pour chaque placement. | Attendre `GetPaywall` indéfiniment. | Sans timeout, les utilisateurs avec une mauvaise connexion voient un écran vide jusqu'à la résolution du réseau — ou ferment l'application. | Consultez [Récupérer les paywalls et les produits](fetch-paywalls-and-products-unity) pour la référence des paramètres `fetchPolicy` et `loadTimeout`, et [Placements](placements) pour choisir le bon placement. ## Optimiser pour une connexion défaillante \{#tune-for-poor-connectivity\} Pour les marchés où la connexion est régulièrement mauvaise (zones rurales, transports en commun, régions touchées par des problèmes de routage) : - Définissez `fetchPolicy` sur `AdaptyPlacementFetchPolicy.ReturnCacheDataElseLoad` pour chaque appel, sauf le tout premier. - Configurez un [paywall de secours](fallback-paywalls) pour chaque placement dans l'Adapty Dashboard. - Réglez `loadTimeout` entre 3 et 5 secondes et acceptez le paywall de secours lorsque le délai expire. - Ne conditionnez pas l'affichage du paywall à `GetProfile`. Appelez `GetPaywall` indépendamment pour éviter qu'un profil lent ne bloque l'interface. --- # File: unity-test --- --- title: "Tester & publier avec le SDK Unity" description: "Apprenez à tester et publier votre application Unity avec le SDK Adapty." --- Si vous avez déjà intégré le SDK Adapty dans votre application Unity, vous voudrez vérifier que tout est correctement configuré et que les achats fonctionnent comme prévu sur les plateformes iOS et Android. Cela implique de tester à la fois l'intégration du SDK et le flux d'achat réel avec l'environnement sandbox d'Apple et l'environnement de test de Google Play. ## Tester votre application \{#test-your-app\} Pour tester vos achats intégrés de manière exhaustive, consultez nos guides de test spécifiques à chaque plateforme : [guide de test iOS](test-purchases-in-sandbox) et [guide de test Android](testing-on-android). ## Se préparer pour la publication \{#prepare-for-release\} Avant de soumettre votre application au store, suivez la [liste de vérification pour la publication](release-checklist) afin de confirmer que : - La connexion au store et les notifications serveur sont configurées - Les achats s'effectuent et sont bien remontés à Adapty - L'accès se déverrouille et se restaure correctement - Les exigences en matière de confidentialité et d'évaluation sont respectées --- # File: unity-reference --- --- title: "Référence pour le SDK Unity" description: "Documentation de référence pour le SDK Unity Adapty." --- Cette page contient la documentation de référence pour le SDK Unity Adapty. Choisissez le sujet dont vous avez besoin : - **[Modèles SDK](https://unity.adapty.io/)** - Modèles de données et structures utilisés par le SDK - **[Gérer les erreurs](unity-handle-errors)** - Gestion des erreurs et dépannage --- # File: unity-handle-errors --- --- title: "Gérer les erreurs dans le SDK Unity" description: "Gérer les erreurs dans le SDK Unity." --- Chaque erreur retournée par le SDK est de type `AdaptyErrorCode`. Voici un exemple : :::tip **Activez les logs verbeux avant de déboguer.** La plupart des `AdaptyError`s encapsulent une erreur sous-jacente de StoreKit, Play Billing, réseau ou backend. Avec les logs verbeux activés (`Adapty.SetLogLevel(AdaptyLogLevel.Verbose, ...)` — voir [Journalisation](sdk-installation-unity#logging)), cette erreur encapsulée est affichée dans la console, ce qui vous indique généralement la cause réelle. ::: :::important Si ces solutions ne résolvent pas votre problème, consultez la section [Autres problèmes](#other-issues) pour connaître les étapes à suivre avant de contacter le support, afin de nous aider à vous assister plus efficacement. ::: ```csharp showLineNumbers Adapty.MakePurchase(product, (profile, error) => { if (error != null && error.Code == Adapty.ErrorCode.PaymentCancelled) { // payment cancelled } }); ``` ## Codes système StoreKit \{#system-storekit-codes\} | Erreur | Code | Solution | |-----|----|-----------| | [unknown](https://developer.apple.com/documentation/storekit/skerror/code/unknown) | 0 | Code d'erreur indiquant qu'une erreur inconnue ou inattendue s'est produite.
Réessayez ou consultez la section [Autres problèmes](#other-issues). | | [clientInvalid](https://developer.apple.com/documentation/storekit/skerror/code/clientinvalid) | 1 | Ce code d'erreur indique que le client n'est pas autorisé à effectuer l'action tentée. | | [paymentCancelled](https://developer.apple.com/documentation/storekit/skerror/code/paymentcancelled) | 2 |

Ce code d'erreur indique que l'utilisateur a annulé une demande de paiement.

Aucune action n'est requise, mais d'un point de vue logique métier, vous pouvez proposer une remise à votre utilisateur ou lui rappeler ultérieurement.

| | [paymentInvalid](https://developer.apple.com/documentation/storekit/skerror/code/paymentinvalid) | 3 | Cette erreur indique que l'un des paramètres de paiement n'a pas été reconnu par l'App Store. | | [paymentNotAllowed](https://developer.apple.com/documentation/storekit/skerror/code/paymentnotallowed) | 4 | Ce code d'erreur indique que l'utilisateur n'est pas autorisé à valider des paiements. | | [storeProductNotAvailable](https://developer.apple.com/documentation/storekit/skerror/code/storeproductnotavailable) | 5 | Ce code d'erreur indique que le produit demandé n'est pas disponible dans le store.
Essayez de réinstaller l'application. | | [cloudServicePermissionDenied](https://developer.apple.com/documentation/storekit/skerror/code/cloudservicepermissiondenied) | 6 | Ce code d'erreur indique que l'utilisateur n'a pas autorisé l'accès aux informations du service cloud. | | [cloudServiceNetworkConnectionFailed](https://developer.apple.com/documentation/storekit/skerror/code/cloudservicenetworkconnectionfailed) | 7 | Ce code d'erreur indique que l'appareil n'a pas pu se connecter au réseau. | | [cloudServiceRevoked](https://developer.apple.com/documentation/storekit/skerror/code/cloudservicerevoked/) | 8 | Ce code d'erreur indique que l'utilisateur a révoqué l'autorisation d'utiliser ce service cloud. | | [privacyAcknowledgementRequired](https://developer.apple.com/documentation/storekit/skerror/code/privacyacknowledgementrequired) | 9 | Ce code d'erreur indique que l'utilisateur n'a pas encore accepté la politique de confidentialité d'Apple. | | [unauthorizedRequestData](https://developer.apple.com/documentation/storekit/skerror/code/unauthorizedrequestdata) | 10 | Ce code d'erreur indique que l'application tente d'utiliser une propriété pour laquelle elle ne dispose pas des droits requis. | | [invalidOfferIdentifier](https://developer.apple.com/documentation/storekit/skerror/code/invalidofferidentifier) | 11 |

L'[`identifiant`](https://developer.apple.com/documentation/storekit/skpaymentdiscount/identifier) de l'offre n'est pas valide. Par exemple, vous n'avez pas configuré d'offre avec cet identifiant dans l'App Store, ou vous avez révoqué l'offre.

Assurez-vous de configurer les offres souhaitées dans AppStore Connect et de passer un identifiant d'offre valide.

| | [invalidSignature](https://developer.apple.com/documentation/storekit/skerror/code/invalidsignature) | 12 | Ce code d'erreur indique que la signature dans une remise de paiement n'est pas valide. | | [missingOfferParams](https://developer.apple.com/documentation/storekit/skerror/code/missingofferparams) | 13 | Ce code d'erreur indique que des paramètres sont manquants dans une remise de paiement. | | [invalidOfferPrice](https://developer.apple.com/documentation/storekit/skerror/code/invalidofferprice/) | 14 | Ce code d'erreur indique que le prix que vous avez spécifié dans App Store Connect n'est plus valide. Les offres doivent toujours représenter un prix réduit. | ## Codes Android personnalisés \{#custom-android-codes\} | Erreur | Code | Solution | |-----|----|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | adaptyNotInitialized | 20 | Vous devez configurer correctement le SDK Adapty via la méthode `Adapty.activate`. Découvrez comment le faire [pour Unity](sdk-installation-unity#activate-adapty-module-of-adapty-sdk). | | productNotFound | 22 | Cette erreur indique que le produit demandé pour l'achat n'est pas disponible dans le store. | | invalidJson | 23 | Le JSON du paywall n'est pas valide. Corrigez-le dans l'Adapty Dashboard. Consultez la rubrique [Personnaliser le paywall avec Remote Config](customize-paywall-with-remote-config) pour savoir comment le corriger. | | currentSubscriptionToUpdateNotFoundInHistory | 24 | L'abonnement d'origine qui doit être renouvelé est introuvable. | | pendingPurchase | 25 | Cette erreur indique que l'état de l'achat est en attente plutôt que finalisé. Consultez la page [Gestion des transactions en attente](https://developer.android.com/google/play/billing/integrate#pending) dans la documentation Android Developer pour plus de détails. | | billingServiceTimeout | 97 | Cette erreur indique que la requête a atteint le délai d'attente maximum avant que Google Play puisse répondre. Cela peut être causé, par exemple, par un délai dans l'exécution de l'action demandée par l'appel à la bibliothèque Play Billing. | | featureNotSupported | 98 | La fonctionnalité demandée n'est pas prise en charge par le Play Store sur l'appareil actuel. | | billingServiceDisconnected | 99 | Cette erreur fatale indique que la connexion de l'application cliente au service Google Play Store via le `BillingClient` a été interrompue. | | billingServiceUnavailable | 102 | Cette erreur transitoire indique que le service Google Play Billing est actuellement indisponible. Dans la plupart des cas, cela signifie qu'il y a un problème de connexion réseau quelque part entre l'appareil client et les services Google Play Billing. | | billingUnavailable | 103 |

Cette erreur indique qu'une erreur de facturation utilisateur s'est produite pendant le processus d'achat. Exemples de situations où cela peut se produire :

1\. L'application Play Store sur l'appareil de l'utilisateur est obsolète.

2. L'utilisateur se trouve dans un pays non pris en charge.

3. L'utilisateur est un utilisateur entreprise et son administrateur a désactivé les achats pour les utilisateurs.

4. Google Play ne peut pas débiter le moyen de paiement de l'utilisateur. Par exemple, la carte de crédit de l'utilisateur a peut-être expiré.

5. L'utilisateur n'est pas connecté à l'application Play Store.

| | developerError | 105 | Il s'agit d'une erreur fatale indiquant que vous utilisez une API de manière incorrecte. | | billingError | 106 | Il s'agit d'une erreur fatale indiquant un problème interne avec Google Play lui-même. | | itemAlreadyOwned | 107 | Le produit consommable a déjà été acheté. | | itemNotOwned | 108 | Cette erreur indique que l'action demandée sur l'article a échoué car | ## Codes StoreKit personnalisés \{#custom-storekit-codes\} | Erreur | Code | Solution | |-----|----|-----------| | noProductIDsFound | 1000 |

Cette erreur indique qu'aucun des produits que vous avez demandés sur le paywall n'est disponible à l'achat dans l'App Store, même s'ils y sont répertoriés. Cette erreur peut parfois s'accompagner d'un avertissement `InvalidProductIdentifiers`. Si l'avertissement apparaît sans erreur, ignorez-le.

Si vous rencontrez cette erreur, suivez les étapes de la section [Correction de l'erreur Code-1000 `noProductIDsFound`](InvalidProductIdentifiers-unity).

| | productRequestFailed | 1002 |

Impossible de récupérer les produits disponibles pour le moment. Raison possible :

- Aucun cache n'a encore été créé et il n'y a pas de connexion Internet en même temps.

| | cantMakePayments | 1003 | Les achats intégrés ne sont pas autorisés sur cet appareil. Consultez le [guide](cantMakePayments-unity) de dépannage. | | noPurchasesToRestore | 1004 | Cette erreur indique que Google Play n'a pas trouvé d'achat à restaurer. | | cantReadReceipt | 1005 |

Aucun reçu valide n'est disponible sur l'appareil. Cela peut poser problème lors des tests en sandbox.

Aucune action n'est requise, mais d'un point de vue logique métier, vous pouvez proposer une remise à votre utilisateur ou lui rappeler ultérieurement.

| | productPurchaseFailed | 1006 | L'achat du produit a échoué. Cela encapsule une erreur StoreKit sous-jacente — lisez l'erreur encapsulée (ou activez les logs verbeux pour la voir dans la console) pour connaître la raison réelle. L'erreur encapsulée correspond généralement à l'un des codes StoreKit 0–14 du tableau ci-dessus — le plus souvent `paymentCancelled`, `paymentInvalid`, `paymentNotAllowed` ou `invalidOfferPrice`. Si vous ne pouvez pas identifier une raison précise, essayez un nouveau [profil sandbox](test-purchases-in-sandbox) ; si cela échoue encore, contactez le support Apple. | | refreshReceiptFailed | 1010 | Cette erreur indique que le reçu n'a pas été reçu. Applicable uniquement à StoreKit 1. | | receiveRestoredTransactionsFailed | 1011 | La restauration des achats a échoué. | ## Codes réseau personnalisés \{#custom-network-codes\} | Erreur | Code | Solution | |:---------------------|:-----|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | notActivated | 2002 | Le SDK Adapty n'est pas activé.
Cas le plus fréquent : un écran de démarrage ou un hook de script précoce appelle des méthodes Adapty avant que `Adapty.Activate` soit terminé. Le symptôme est intermittent et peut ne pas se reproduire dans l'éditeur car les timings sur appareil réel sont différents. Attendez le callback de complétion d'`Activate` avant de planifier tout autre appel SDK. Voir [Ordre des appels dans le SDK Unity](unity-sdk-call-order) pour la séquence complète. | | badRequest | 2003 | Requête incorrecte.
Assurez-vous d'avoir effectué toutes les étapes requises pour [l'intégration avec l'App Store](app-store-connection-configuration). | | serverError | 2004 | Erreur serveur.
Réessayez après quelques instants. Si le problème persiste, contactez l'équipe support Adapty. | | networkFailed | 2005 | Cette erreur indique des problèmes de connexion réseau sur l'appareil de l'utilisateur.
Essayez de désactiver le VPN ou de passer du réseau cellulaire au WiFi, ou inversement. | | decodingFailed | 2006 | Cette erreur indique que le décodage de la réponse a échoué.
Vérifiez votre code et assurez-vous que les paramètres que vous envoyez sont valides. Par exemple, cette erreur peut indiquer que vous utilisez une clé API invalide. | | encodingFailed | 2009 | Cette erreur indique que l'encodage de la requête a échoué. | | missingURL | 2010 | L'URL demandée est nil. | | analyticsDisabled | 3000 | Nous ne pouvons pas traiter les événements d'analytics, car vous avez [désactivé cette option](analytics-integration#disabling-external-analytics-for-a-specific-customer). | | wrongParam | 3001 | Cette erreur indique que certains de vos paramètres sont incorrects.
Si vous utilisez le Paywall Builder Adapty et ne pouvez pas afficher un paywall à cause de cette erreur, activez **Show on device** dans le Paywall Builder.
Une autre raison possible est que la version du fichier [fallback](fallback-paywalls) local ne correspond pas à la version du SDK. Téléchargez un nouveau fichier depuis le tableau de bord. | | activateOnceError | 3005 | Il n'est pas possible d'appeler la méthode `.activate` plus d'une fois. | | profileWasChanged | 3006 | Le profil utilisateur a été modifié pendant l'opération.
Cela se produit lorsqu'une méthode est appelée pendant qu'`Adapty.Identify` est encore en cours — l'appel en vol arrive sur un profil qui est sur le point d'être remplacé, et le SDK le rejette. Attendez le callback de complétion d'`Identify` avant tout appel d'action utilisateur. Voir [Ordre des appels dans le SDK Unity](unity-sdk-call-order). | | unsupportedData | 3007 | Cette erreur indique que le format de données n'est pas pris en charge par le SDK. | | persistingDataError | 3100 | Une erreur s'est produite lors de l'enregistrement des données. | | fetchTimeoutError | 3101 | Cette erreur indique que l'opération de récupération a dépassé le délai d'attente. | ## Autres problèmes \{#other-issues\} Si vous n'avez pas encore trouvé de solution, voici les prochaines étapes : - **Mettre à jour le SDK vers la dernière version** : nous recommandons toujours de mettre à jour vers les dernières versions du SDK, car elles sont plus stables et incluent des correctifs pour les problèmes connus. - **Contacter l'équipe support ou obtenir de l'aide auprès d'autres développeurs** sur le [forum de support](https://adapty.featurebase.app/). - **Contacter l'équipe support via [support@adapty.io](mailto:support@adapty.io) ou via le chat** : si vous n'êtes pas prêt à mettre à jour le SDK ou si cela n'a pas résolu le problème, contactez notre équipe support. Notez que votre problème sera résolu plus rapidement si vous [activez la journalisation verbeux](sdk-installation-unity#logging) et partagez les logs avec l'équipe. Vous pouvez également joindre des extraits de code pertinents. --- # File: InvalidProductIdentifiers-unity --- --- title: "Correction de l'erreur Code-1000 noProductIDsFound dans le SDK Unity" description: "Résolvez les erreurs d'identifiant de produit invalide lors de la gestion des abonnements dans Adapty." --- L'erreur code 1000, `noProductIDsFound`, indique qu'aucun des produits demandés sur le paywall n'est disponible à l'achat dans l'App Store, même s'ils y sont référencés. Cette erreur peut parfois s'accompagner d'un avertissement `InvalidProductIdentifiers`. Si l'avertissement apparaît sans erreur, vous pouvez l'ignorer sans risque. Si vous rencontrez l'erreur `noProductIDsFound`, suivez ces étapes pour la résoudre : ## Étape 1. Vérifier le bundle ID \{#step-2-check-bundle-id\} 1. Ouvrez [App Store Connect](https://appstoreconnect.apple.com/apps). Sélectionnez votre application et accédez à la section **General** → **App Information**. 2. Copiez le **Bundle ID** dans la sous-section **General Information**. 3. Ouvrez l'onglet [**App settings** -> **iOS SDK**](https://app.adapty.io/settings/ios-sdk) depuis le menu supérieur d'Adapty et collez la valeur copiée dans le champ **Bundle ID**. 4. Revenez à la page **App information** dans App Store Connect et copiez l'**Apple ID** qui s'y trouve. 5. Sur la page [**App settings** -> **iOS SDK**](https://app.adapty.io/settings/ios-sdk) dans l'Adapty Dashboard, collez l'identifiant dans le champ **Apple app ID**. ## Étape 2. Vérifier les produits \{#step-3-check-products\} 1. Rendez-vous dans **App Store Connect** et accédez à [**Monétisation** → **Abonnements**](https://appstoreconnect.apple.com/apps/6477523342/distribution/subscriptions) dans le menu de gauche. 2. Cliquez sur le nom du groupe d'abonnements. Vos produits apparaîtront dans la section **Subscriptions**. 3. Assurez-vous que le produit que vous testez est marqué **Ready to Submit**. 4. Comparez l'identifiant du produit dans le tableau avec celui qui figure dans l'onglet [**Products**](https://app.adapty.io/products) de l'Adapty Dashboard. Si les identifiants ne correspondent pas, copiez l'identifiant du produit depuis le tableau et [créez un produit](create-product) avec cet identifiant dans l'Adapty Dashboard. ## Étape 3. Vérifier la disponibilité du produit \{#step-4-check-product-availability\} 1. Retournez dans **App Store Connect** et ouvrez la même section **Subscriptions**. 2. Cliquez sur le nom du groupe d'abonnements pour afficher vos produits. 3. Sélectionnez le produit que vous testez. 4. Faites défiler jusqu'à la section **Availability** et vérifiez que tous les pays et régions requis y sont bien listés. ## Étape 4. Vérifier les prix du produit \{#step-5-check-product-prices\} 1. De nouveau, rendez-vous dans la section **Monetization** → **Subscriptions** d'**App Store Connect**. 2. Cliquez sur le nom du groupe d'abonnements. 3. Sélectionnez le produit que vous testez. 4. Faites défiler jusqu'à **Subscription Pricing** et dépliez la section **Current Pricing for New Subscribers**. 5. Vérifiez que tous les prix requis sont bien listés. ## Étape 5. Vérifier le statut des apps payantes, le compte bancaire et les formulaires fiscaux \{#step-5-check-app-paid-status-bank-account-and-tax-forms-are-active\} 1. Sur la page d'accueil d'[**App Store Connect**](https://appstoreconnect.apple.com/), cliquez sur **Business**. 2. Sélectionnez le nom de votre entreprise. 3. Faites défiler vers le bas et vérifiez que votre **Paid Apps Agreement**, votre **Bank Account** et vos **Tax forms** affichent bien le statut **Active**. En suivant ces étapes, vous devriez pouvoir résoudre l'avertissement `InvalidProductIdentifiers` et rendre vos produits disponibles dans le store. ## Étape 6. Recréer le produit s'il est bloqué \{#step-6-recreate-the-product-if-its-stuck\} Les étapes 1 à 5 peuvent toutes passer avec succès — statut `Approved`, Bundle ID correspondant, clé API valide — et pourtant le SDK continue de retourner `1000 noProductIDsFound`. Dans ce cas, le produit est peut-être bloqué dans le registre d'Apple. Il arrive que le registre de produits d'Apple entre dans un état où un produit existe dans l'interface d'App Store Connect mais n'est pas exposé au chemin de recherche StoreKit. Supprimez le produit dans App Store Connect et recréez-le avec le même identifiant. Attendez jusqu'à 24 heures après la recréation pour que la propagation soit effective. --- # File: cantMakePayments-unity --- --- title: "Correction de l'erreur Code-1003 cantMakePayment dans le SDK Unity" description: "Résolvez l'erreur de paiement lors de la gestion des abonnements dans Adapty." --- L'erreur 1003, `cantMakePayments`, indique que les achats intégrés ne peuvent pas être effectués sur cet appareil. Si vous rencontrez l'erreur `cantMakePayments`, cela est généralement dû à l'une des raisons suivantes : - Restrictions de l'appareil : L'erreur n'est pas liée à Adapty. Consultez les solutions ci-dessous. - Configuration du mode Observateur : La méthode `makePurchase` et le mode Observateur ne peuvent pas être utilisés simultanément. Consultez la section ci-dessous. ## Problème : Restrictions de l'appareil \{#issue-device-restrictions\} | Problème | Solution | |--------------------------------|-------------------------------------------------------------------------------------------------------------| | Restrictions Screen Time | Désactivez les restrictions d'achat intégré dans [Screen Time](https://support.apple.com/en-us/102470) | | Compte suspendu | Contactez le support Apple pour résoudre les problèmes de compte | | Restrictions régionales | Utilisez un compte App Store d'une région prise en charge | ## Problème : Utilisation simultanée du mode Observateur et de makePurchase \{#issue-using-both-observer-mode-and-makepurchase\} Si vous utilisez `makePurchases` pour gérer les achats, vous n'avez pas besoin d'utiliser le mode Observateur. Le [mode Observateur](observer-vs-full-mode) n'est nécessaire que si vous implémentez vous-même la logique d'achat. Ainsi, si vous utilisez `makePurchase`, vous pouvez supprimer en toute sécurité l'activation du mode Observateur dans le code d'initialisation du SDK. --- # File: unity-sdk-migration-guides --- --- title: "Guides de migration du SDK Unity" description: "Guides de migration pour les versions du SDK Unity d'Adapty." --- Cette page regroupe tous les guides de migration pour le SDK Unity d'Adapty. Choisissez la version vers laquelle vous souhaitez migrer pour obtenir des instructions détaillées : - **[Migrer vers la v4.0 (bêta)](migration-to-unity-sdk-v4)** - **[Migrer vers la v3.14](migration-to-unity-sdk-314)** - **[Migrer vers la v3.4](migration-to-unity-sdk-34)** - **[Migrer vers la v3.3](migration-to-unity330)** - **[Migrer vers la v3.0](migration-to-unity-sdk-v3)** --- # File: migration-to-unity-sdk-v4 --- --- title: "Migrer le SDK Adapty Unity vers la v4.0" description: "Migrez vers le SDK Adapty Unity v4.0 (beta) en remplaçant les API paywall par des API flow, compatibles avec le Flow Builder et le Paywall Builder." --- Le SDK Adapty Unity 4.0 (beta) introduit les flows et renomme les API paywall en conséquence. Les nouvelles API fonctionnent à la fois avec le nouveau Flow Builder et le Paywall Builder existant — aucune modification de configuration n'est requise côté Adapty Dashboard. ## Référence rapide \{#quick-reference\} | v3 | v4 | |---|---| | `Adapty.GetPaywall(placementId, locale, ...)` | `Adapty.GetFlow(placementId, ...)` | | `Adapty.GetPaywallForDefaultAudience(placementId, locale, ...)` | `Adapty.GetFlowForDefaultAudience(placementId, ...)` | | `Adapty.GetPaywallProducts(paywall, ...)` | `Adapty.GetPaywallProducts(flow, ...)` | | `Adapty.LogShowPaywall(paywall, ...)` | `Adapty.LogShowFlow(flow, ...)` | | `AdaptyPaywall` | `AdaptyFlow` | | `AdaptyUI.CreatePaywallView(paywall, ...)` | `AdaptyUI.CreateFlowView(flow, ...)` | | `AdaptyUICreatePaywallViewParameters` | `AdaptyUICreateFlowViewParameters` | | `AdaptyUIPaywallView` | `AdaptyUIFlowView` | | `AdaptyUI.PresentPaywallView(view, ...)` / `DismissPaywallView(view, ...)` | `AdaptyUI.PresentFlowView(view, ...)` / `DismissFlowView(view, ...)` | | `Adapty.SetPaywallsEventsListener(listener)` | `Adapty.SetFlowsEventsListener(listener)` | | `AdaptyPaywallsEventsListener` | `IAdaptyFlowsEventsListener` | | `AdaptyEventListener` | `IAdaptyEventListener` | | `AdaptyOnboardingsEventsListener` | `IAdaptyOnboardingsEventsListener` | | `PaywallViewDidPerformAction`, `PaywallViewDidAppear`, et autres callbacks `PaywallView...` | `FlowViewDidPerformAction`, `FlowViewDidAppear`, et autres callbacks `FlowView...` | | `PaywallViewDidFailRendering` | `FlowViewDidReceiveError` | | `Adapty.SetFallbackPaywalls(...)` (déprécié en v3) | supprimé — utilisez `Adapty.SetFallback(fileName, ...)` | | `Builder.SetIDFACollectionDisabled(...)` (déprécié en v3) | supprimé — utilisez `Builder.SetAppleIDFACollectionDisabled(...)` | | `paywall.Products` (une liste de `AdaptyProductReference`) | supprimé — utilisez `ProductIdentifiers` ou `VendorProductIds`, ou appelez `GetPaywallProducts(flow)` pour les produits complets | | `AdaptyProductReference` | supprimé en tant que type public — voir [Modèle de données](#data-model) | | `paywall.RemoteConfigString` | supprimé — utilisez `flow.RemoteConfig?.Data` | `AdaptyPaywallProduct` garde son nom — les produits appartiennent toujours à un flow, et `GetPaywallProducts` garde également son nom, prenant désormais un `AdaptyFlow`. Les méthodes `GetFlow` et `GetFlowForDefaultAudience` ne prennent plus de paramètre `locale`. Les API d'achat et de profil (`MakePurchase`, `RestorePurchases`, `GetProfile`, `Identify`, `UpdateProfile`) et les fallbacks via `SetFallback` sont inchangés. Les méthodes onboarding fonctionnent toujours mais sont dépréciées — voir [Dépréciation de l'API Onboarding](#onboarding-api-deprecation). Certains comportements par défaut ont changé — voir [Changements de comportement par défaut](#default-behavior-changes). ## Installation \{#installation\} La v4.0 est une pré-version, donc épinglez le tag bêta exact. Pour l'installer via le Unity Package Manager, ajoutez le tag à l'URL Git : ``` https://github.com/adaptyteam/AdaptySDK-Unity.git?path=/Packages/com.adapty.unity-sdk#4.0.0-beta.1 ``` Si vous installez via le package Unity, téléchargez `adapty-unity-plugin-4.0.0-beta.1.unitypackage` depuis la [version 4.0.0-beta.1](https://github.com/adaptyteam/AdaptySDK-Unity/releases/tag/4.0.0-beta.1). Consultez [Installer le SDK Adapty](sdk-installation-unity#install-adapty-sdk) pour la configuration complète. Deux changements de configuration de build sont introduits avec la v4 : - **Les dépendances iOS passent à Swift Package Manager.** Le SDK iOS natif Adapty 4.0 est déclaré comme package Swift distant au lieu d'un pod CocoaPods. Mettez à jour l'[External Dependency Manager](https://github.com/googlesamples/unity-jar-resolver#getting-started) vers la version **1.2.188 ou ultérieure** — les versions antérieures ne prennent pas en charge les dépendances Swift Package Manager. Les étapes CocoaPods (`iOS Resolver -> Install Cocoapods`, ouverture de `Unity-iPhone.xcworkspace`) ne s'appliquent plus. - **La cible de déploiement iOS doit être 15.0 ou supérieure.** Un nouveau validateur de build dans l'éditeur Unity bloque le build iOS si la cible est inférieure. Les SDK natifs Adapty sous-jacents passent à la version 4.x sur les deux plateformes et sont résolus automatiquement — aucune autre modification de build n'est nécessaire. ## Récupération des flows \{#fetching-flows\} ### GetPaywall → GetFlow Le type retourné passe de `AdaptyPaywall` à `AdaptyFlow`, et le paramètre `locale` est supprimé — lors du rendu d'un flow, la locale est résolue automatiquement ; pour les paywalls personnalisés, toutes les locales sont retournées dans `flow.RemoteConfigs` : ```diff showLineNumbers - Adapty.GetPaywall("YOUR_PLACEMENT_ID", "en", (paywall, error) => { + Adapty.GetFlow("YOUR_PLACEMENT_ID", (flow, error) => { if (error != null) { // handle the error return; } - // use the paywall + // use the flow }); ``` `GetPaywallForDefaultAudience` est renommé de la même façon : ```diff showLineNumbers - Adapty.GetPaywallForDefaultAudience("YOUR_PLACEMENT_ID", "en", (paywall, error) => { /* ... */ }); + Adapty.GetFlowForDefaultAudience("YOUR_PLACEMENT_ID", (flow, error) => { /* ... */ }); ``` ### GetPaywallProducts(paywall) → GetPaywallProducts(flow) `GetPaywallProducts` conserve son nom mais prend désormais un `AdaptyFlow` : ```diff showLineNumbers - Adapty.GetPaywallProducts(paywall, (products, error) => { + Adapty.GetPaywallProducts(flow, (products, error) => { if (error != null) { // handle the error return; } // use the products }); ``` ## Modèle de données \{#data-model\} `GetFlow` retourne un `AdaptyFlow` au lieu d'un `AdaptyPaywall`, et la forme de l'objet a changé : | Propriété v3 `AdaptyPaywall` | Propriété v4 `AdaptyFlow` | Action | |---|---|---| | `RemoteConfig` (unique, nullable) | `RemoteConfigs` (liste) | Un flow contient une Remote Config par langue configurée. Lisez celle qui correspond à l'utilisateur via `flow.RemoteConfigs`. Le raccourci `flow.RemoteConfig` renvoie la première entrée. | | _(nouveau)_ | `Paywalls` (liste de `AdaptyFlowPaywall`) | Chaque entrée est une variation de paywall dans le flow, avec son propre `Name`, `VariationId` et `ProductIdentifiers`. Les méthodes de paywall web prennent un `AdaptyFlowPaywall` — voir [Méthodes de paywall web](#web-paywall-methods). | | `ProductIdentifiers`, `VendorProductIds` | conservé | Sur `AdaptyFlow`, ces propriétés agrègent les produits de toutes les variations de paywall. Chaque variation expose également ses propres `ProductIdentifiers` et `VendorProductIds`. Pour récupérer les produits, continuez d'appeler `GetPaywallProducts(flow)`. | | `HasViewConfiguration` | supprimé | Supprimez tout contrôle `HasViewConfiguration` de votre code — `CreateFlowView` renvoie une erreur à la place (voir [Affichage des flows](#displaying-flows)). | | `Products` (liste de `AdaptyProductReference`) | supprimé | `AdaptyProductReference` n'est plus public, et avec lui les valeurs `PromotionalOfferId`, `WinBackOfferId` et `AndroidOfferId` qu'il portait. Utilisez `ProductIdentifiers` — une liste de `AdaptyProductIdentifier` avec `VendorProductId` et le `BasePlanId` réservé à Android (le `AndroidBasePlanId` de la v3) — ou appelez `GetPaywallProducts(flow)` quand vous avez besoin d'objets `AdaptyPaywallProduct` complets avec les prix et les offres. | | `RemoteConfigString` | supprimé | Lisez la chaîne directement depuis la Remote Config : `flow.RemoteConfig?.Data`, ou l'entrée correspondante dans `flow.RemoteConfigs`. | | _(nouveau)_ | `FlowVersionId` (nullable) | L'identifiant de version du flow, ou `null` s'il n'est pas disponible. | `AdaptyPaywallProduct` gagne un champ supplémentaire : `FlowProductId`, l'identifiant du produit au sein du flow, qui est `null` pour les produits n'appartenant pas à un flow. ## Méthodes de paywall web \{#web-paywall-methods\} `OpenWebPaywall` et `CreateWebPaywallUrl` conservent leurs noms, mais l'argument `paywall` accepte désormais un `AdaptyFlowPaywall` — l'une des variantes dans `flow.Paywalls`. Vous pouvez toujours passer un `AdaptyPaywallProduct` à la place : ```diff showLineNumbers - Adapty.OpenWebPaywall(paywall, AdaptyWebPresentation.ExternalBrowser, (error) => { /* ... */ }); + var flowPaywall = flow.Paywalls.FirstOrDefault(); + if (flowPaywall != null) { + Adapty.OpenWebPaywall(flowPaywall, AdaptyWebPresentation.ExternalBrowser, (error) => { /* ... */ }); + } ``` ## Suivi des vues de flow \{#tracking-flow-views\} ### LogShowPaywall → LogShowFlow `LogShowPaywall` est renommé en `LogShowFlow` et prend désormais un `AdaptyFlow`. L'événement est toujours enregistré pour la même variation, donc les métriques de funnel et de test A/B existantes continuent de fonctionner sans modifications du tableau de bord. ```diff showLineNumbers - Adapty.LogShowPaywall(paywall, (error) => { /* ... */ }); + Adapty.LogShowFlow(flow, (error) => { /* ... */ }); ``` Comme dans la v3, vous n'avez pas besoin d'appeler cette méthode lors de l'affichage des flows ou des paywalls rendus par le [Flow Builder](adapty-flow-builder) ou le [Paywall Builder](adapty-paywall-builder) — Adapty suit automatiquement ces vues. ## Afficher des flows \{#displaying-flows\} ### CreatePaywallView → CreateFlowView Renommez la méthode factory et passez l'`AdaptyFlow`. Le type de vue retourné est renommé de `AdaptyUIPaywallView` en `AdaptyUIFlowView`, mais ses méthodes (`Present`, `Dismiss`) restent inchangées, et l'objet de paramètres optionnels conserve les mêmes champs (`LoadTimeout`, `PreloadProducts`, `CustomTags`, `CustomTimers`, `CustomAssets`, `ProductPurchaseParameters`) sous le nouveau nom `AdaptyUICreateFlowViewParameters`, plus deux nouveaux — `Locale` et `EnableSafeAreaPaddings` : ```diff showLineNumbers - AdaptyUI.CreatePaywallView(paywall, parameters, (view, error) => { + AdaptyUI.CreateFlowView(flow, parameters, (view, error) => { if (error != null) { // handle the error return; } view.Present((error) => { /* handle the error */ }); }); ``` `CreateFlowView` retourne une erreur si le flow n'a pas de vue configurée — cela remplace la vérification `HasViewConfiguration` de la v3 : ```diff showLineNumbers - if (paywall.HasViewConfiguration) { - AdaptyUI.CreatePaywallView(paywall, null, (view, error) => { /* ... */ }); - } + AdaptyUI.CreateFlowView(flow, (view, error) => { + if (error != null) { + // the flow has no view configured, or view creation failed + return; + } + view.Present((error) => { /* handle the error */ }); + }); ``` :::note Une vue de flow est à usage unique : après avoir appelé `Dismiss`, la vue est détruite. Appelez donc à nouveau `CreateFlowView` pour afficher le flow une nouvelle fois. ::: ### Marges de zone sécurisée Android \{#android-safe-area-paddings\} `AdaptyUICreateFlowViewParameters` ajoute `EnableSafeAreaPaddings`, qui contrôle les marges de zone sécurisée Android à l'exécution. Il est ignoré sur iOS et vaut `true` par défaut : ```csharp showLineNumbers var parameters = new AdaptyUICreateFlowViewParameters() .SetEnableSafeAreaPaddings(false); ``` ## Gestion des événements \{#handling-events\} Les interfaces de listener suivent désormais la convention C# avec préfixe `I` — il n'existe plus d'alias hérités : renommez `AdaptyEventListener` en `IAdaptyEventListener` et `AdaptyOnboardingsEventsListener` en `IAdaptyOnboardingsEventsListener` partout où vous les implémentez. L'écouteur d'événements de flow est renommé de `AdaptyPaywallsEventsListener` en `IAdaptyFlowsEventsListener`, sa méthode d'enregistrement de `SetPaywallsEventsListener` en `SetFlowsEventsListener`, et ses callbacks remplacent le préfixe `PaywallView` par `FlowView`. Le corps des handlers existants ne nécessite aucune modification — il suffit de renommer l'interface et les méthodes : ```diff showLineNumbers - public class MyListener : MonoBehaviour, AdaptyPaywallsEventsListener { - public void PaywallViewDidFinishPurchase( - AdaptyUIPaywallView view, + public class MyListener : MonoBehaviour, IAdaptyFlowsEventsListener { + public void FlowViewDidFinishPurchase( + AdaptyUIFlowView view, AdaptyPaywallProduct product, AdaptyPurchaseResult purchasedResult ) { // custom logic after purchase } // ... } - Adapty.SetPaywallsEventsListener(myListener); + Adapty.SetFlowsEventsListener(myListener); ``` Un callback est renommé : `PaywallViewDidFailRendering` devient `FlowViewDidReceiveError`. Il se déclenche pour les mêmes erreurs de rendu qu'auparavant, plus d'autres erreurs d'exécution non liées aux achats : ```diff showLineNumbers - public void PaywallViewDidFailRendering(AdaptyUIPaywallView view, AdaptyError error) { } + public void FlowViewDidReceiveError(AdaptyUIFlowView view, AdaptyError error) { } ``` Consultez [Gérer les événements de flow et de paywall](unity-handling-events) pour la liste complète des callbacks. ### Nouvelles API \{#new-apis\} - `Adapty.SetObserverModeResolver(...)` avec un `IAdaptyUIObserverModeResolver` — gérez les achats et restaurations initiés depuis les flows lorsque le SDK fonctionne en [mode Observer](implement-observer-mode-unity). Auparavant, cette fonctionnalité n'était disponible que dans les SDK natifs iOS et Android. Voir [Présenter des flows en mode Observer](unity-present-flows-in-observer-mode). - `Adapty.SetSystemRequestsHandler(...)` avec un `IAdaptyUISystemRequestsHandler` — réservé aux requêtes système provenant d'un flow : invites de permissions OS (`FlowViewDidAskPermission`) et demandes d'évaluation de l'app (`FlowViewDidRequestAppReview`). Les flows ne déclenchent pas encore ces requêtes, vous n'avez donc pas besoin d'enregistrer un handler. - `AdaptyUICreateFlowViewParameters.Locale` (à définir avec `SetLocale`) — affichez un flow ou un paywall avec une [localisation Builder](add-paywall-locale-in-adapty-paywall-builder) spécifique plutôt que la localisation par défaut du flow. Un flow est localisé au moment de la création de sa vue, c'est donc le seul endroit pour choisir sa localisation ; la vue créée indique la localisation avec laquelle elle a été construite dans `view.Locale`. Voir [Utiliser les localisations et les codes de langue](unity-localizations-and-locale-codes). - Le nouveau callback `FlowViewDidReceiveAnalyticEvent` sur `IAdaptyFlowsEventsListener` est réservé aux événements analytiques personnalisés provenant d'un flow. Les flows n'émettent pas encore ces événements vers votre code, implémentez-le donc avec un corps vide. - `AdaptyUI.OpenUrl(url, openIn, ...)` et `AdaptyUI.RequestAppReview(...)` — le traitement natif derrière les actions `open_url` et les demandes d'évaluation de l'app. Appelez `OpenUrl` depuis `FlowViewDidPerformAction` pour conserver le comportement URL par défaut ; `RequestAppReview` sert d'appui à l'invite d'évaluation par défaut, que les flows ne déclenchent pas encore. ## Changements de comportement par défaut \{#default-behavior-changes\} Ces changements ne provoquent pas d'erreurs de compilation, testez-les donc à l'exécution : - **Finalisation d'achat** : en v3, la vue se fermait automatiquement après un achat réussi. En v4, **un flow reste ouvert après un achat ou une erreur jusqu'à ce que vous le fermiez** — le SDK n'applique aucun comportement par défaut. Appelez vous-même `view.Dismiss(...)` dans `FlowViewDidFinishPurchase` dès que l'utilisateur obtient l'accès. - **Bouton retour Android** : le bouton retour système (ou le geste de retour) est transmis à `FlowViewDidPerformAction` sous la forme d'une action `SystemBack` et ne ferme plus le flow par lui-même — alignement avec iOS, où un flow ne peut pas être fermé par un geste système. Donnez aux utilisateurs un moyen de sortir explicite (un bouton **Close** ou une action `on_device_back`), ou fermez la vue vous-même lors du traitement de l'action. - **Les vues sont à usage unique** : après `Dismiss`, la vue est détruite. Appelez à nouveau `CreateFlowView` pour présenter le flow une nouvelle fois. - **Transactions en mode Observer** : `ReportTransaction` ne remonte plus d'erreur de décodage en cas de succès — en v3, la réponse de succès était mal analysée, si bien qu'un rapport réussi se terminait toujours avec une erreur. ## Dépréciation de l'API onboarding \{#onboarding-api-deprecation\} L'ancienne API onboarding est dépréciée dans la v4.0 au profit du [Flow Builder](adapty-flow-builder). Elle fonctionne toujours, mais sera supprimée dans une prochaine version. Prévoyez donc la migration de vos onboardings vers le Flow Builder. Symboles dépréciés : `GetOnboarding`, `GetOnboardingForDefaultAudience`, `AdaptyUI.CreateOnboardingView`, `AdaptyUI.PresentOnboardingView`, `AdaptyUI.DismissOnboardingView` et `Adapty.SetOnboardingsEventsListener`. --- # File: migration-to-unity-sdk-314 --- --- title: "Migrer le SDK Adapty Unity vers la v3.14" description: "Migrez vers le SDK Adapty Unity v3.14 pour de meilleures performances et de nouvelles fonctionnalités de monétisation." --- Le SDK Adapty 3.14.0 est une version majeure qui apporte des améliorations nécessitant toutefois quelques étapes de migration de votre part : 1. Écouteur d'événements distinct pour les événements de paywall. 2. Renommer `AdaptyUI.CreateView` en `AdaptyUI.CreatePaywallView` et les méthodes associées. 3. Mettre à jour la méthode `MakePurchase` pour utiliser `AdaptyPurchaseParameters` à la place des paramètres individuels. 4. Remplacer `SetFallbackPaywalls` par la méthode `SetFallback`. 5. Mettre à jour l'accès aux propriétés du paywall pour utiliser `AdaptyPlacement`. 6. Mettre à jour l'accès à la configuration distante pour utiliser l'objet `AdaptyRemoteConfig`. 7. Remplacer `VendorProductIds` par `ProductIdentifiers` dans le modèle `AdaptyPaywall`. 8. Mettre à jour la politique de récupération de `GetPaywall` pour utiliser `AdaptyFetchPolicy`. ## Écouteur d'événements distinct pour les événements de paywall \{#separate-event-listener-for-paywall-events\} Si vous affichez des paywalls conçus avec le [Paywall Builder](adapty-paywall-builder), les événements de vue de paywall utilisent désormais l'interface dédiée `AdaptyPaywallsEventsListener` et la méthode `SetPaywallsEventsListener`. L'interface principale `AdaptyEventListener` reste utilisée pour les mises à jour de profil et les détails d'installation. ```diff showLineNumbers using UnityEngine; using AdaptySDK; public class AdaptyListener : MonoBehaviour, - AdaptyEventListener { + AdaptyEventListener, + AdaptyPaywallsEventsListener { void Start() { Adapty.SetEventListener(this); + Adapty.SetPaywallsEventsListener(this); } // AdaptyEventListener methods public void OnLoadLatestProfile(AdaptyProfile profile) { } public void OnInstallationDetailsSuccess(AdaptyInstallationDetails details) { } public void OnInstallationDetailsFail(AdaptyError error) { } + // AdaptyPaywallsEventsListener methods + // Implement paywall event handlers here } ``` [En savoir plus sur la gestion des événements de paywall](unity-handling-events). ## Renommer les méthodes de création et de présentation de vue \{#rename-view-creation-and-presentation-methods\} Les méthodes de création et de présentation de vue ont été renommées : ```diff showLineNumbers using AdaptySDK; - AdaptyUI.CreateView(paywall, parameters, (view, error) => { + AdaptyUI.CreatePaywallView(paywall, parameters, (view, error) => { if (error != null) { // handle the error return; } - AdaptyUI.PresentView(view, (error) => { + AdaptyUI.PresentPaywallView(view, (error) => { // handle the error }); }); } ``` De même, la méthode de fermeture a été renommée : ```diff showLineNumbers - AdaptyUI.DismissView(view, (error) => { + AdaptyUI.DismissPaywallView(view, (error) => { // handle the error }); ``` ## Mettre à jour la méthode MakePurchase \{#update-makepurchase-method\} La méthode `MakePurchase` utilise désormais `AdaptyPurchaseParameters` à la place des arguments individuels `subscriptionUpdateParams` et `isOfferPersonalized`. Cela offre une meilleure sécurité de type et permet d'étendre plus facilement les paramètres d'achat à l'avenir. ```diff showLineNumbers using AdaptySDK; void MakePurchase( AdaptyPaywallProduct product, AdaptySubscriptionUpdateParameters subscriptionUpdate, bool? isOfferPersonalized ) { - Adapty.MakePurchase(product, subscriptionUpdate, isOfferPersonalized, (result, error) => { + var parameters = new AdaptyPurchaseParametersBuilder() + .SetSubscriptionUpdateParams(subscriptionUpdate) + .SetIsOfferPersonalized(isOfferPersonalized) + .Build(); + + Adapty.MakePurchase(product, parameters, (result, error) => { switch (result.Type) { case AdaptyPurchaseResultType.Pending: // handle pending purchase break; case AdaptyPurchaseResultType.UserCancelled: // handle purchase cancellation break; case AdaptyPurchaseResultType.Success: var profile = result.Profile; // handle successful purchase break; default: break; } }); } ``` Si aucun paramètre supplémentaire n'est nécessaire, vous pouvez simplement utiliser : ```csharp showLineNumbers using AdaptySDK; void MakePurchase(AdaptyPaywallProduct product) { Adapty.MakePurchase(product, (result, error) => { // handle purchase result }); } ``` ## Mettre à jour la méthode de fallback \{#update-fallback-method\} :::important Lors de la mise à niveau vers le SDK Unity 3.14, vous devrez télécharger les nouveaux fichiers de fallback depuis l'Adapty Dashboard et remplacer ceux existants dans votre projet. ::: La méthode de définition des fallbacks a été mise à jour. La méthode `SetFallbackPaywalls` a été renommée en `SetFallback` : ```diff showLineNumbers using AdaptySDK; void SetFallBackPaywalls() { #if UNITY_IOS var assetId = "adapty_fallback_ios.json"; #elif UNITY_ANDROID var assetId = "adapty_fallback_android.json"; #else var assetId = ""; #endif - Adapty.SetFallbackPaywalls(assetId, (error) => { + Adapty.SetFallback(assetId, (error) => { // handle the error }); } ``` Consultez l'exemple de code final sur la page [Utiliser des paywalls de secours dans Unity](unity-use-fallback-paywalls). ## Mettre à jour l'accès aux propriétés du paywall \{#update-paywall-property-access\} Les propriétés suivantes ont été déplacées de `AdaptyPaywall` vers `AdaptyPlacement` : ```diff showLineNumbers using AdaptySDK; void ProcessPaywall(AdaptyPaywall paywall) { - var abTestName = paywall.ABTestName; - var audienceName = paywall.AudienceName; - var revision = paywall.Revision; - var placementId = paywall.PlacementId; + var abTestName = paywall.Placement.ABTestName; + var audienceName = paywall.Placement.AudienceName; + var revision = paywall.Placement.Revision; + var placementId = paywall.Placement.Id; } ``` ## Mettre à jour l'accès à la configuration distante \{#update-remote-config-access\} Les propriétés du Remote Config ont été restructurées dans un objet `AdaptyRemoteConfig` pour une meilleure organisation : ```diff showLineNumbers using AdaptySDK; void ProcessRemoteConfig(AdaptyPaywall paywall) { - var remoteConfigString = paywall.RemoteConfigString; - var locale = paywall.Locale; - var remoteConfigDict = paywall.RemoteConfig; + var remoteConfigString = paywall.RemoteConfig.Data; + var locale = paywall.RemoteConfig.Locale; + var remoteConfigDict = paywall.RemoteConfig.Dictionary; } ``` ## Mettre à jour l'utilisation du modèle AdaptyPaywall \{#update-adapty-paywall-model-usage\} La propriété `VendorProductIds` est désormais dépréciée au profit de `ProductIdentifiers`. La nouvelle propriété retourne des objets `AdaptyProductIdentifier` au lieu de simples chaînes de caractères, offrant une information produit mieux structurée. ```diff showLineNumbers using AdaptySDK; void ProcessPaywallProducts(AdaptyPaywall paywall) { - var productIds = paywall.VendorProductIds; - foreach (var vendorId in productIds) { - // use vendorId - } + var productIdentifiers = paywall.ProductIdentifiers; + foreach (var productId in productIdentifiers) { + var vendorId = productId.VendorProductId; + // use vendorId + } } ``` L'objet `AdaptyProductIdentifier` donne accès à l'identifiant de produit du vendeur via la propriété `VendorProductId`, conservant la même fonctionnalité tout en offrant une meilleure structure pour les améliorations futures. ## Mettre à jour la politique de récupération de GetPaywall \{#update-getpaywall-fetch-policy\} Le type du paramètre `fetchPolicy` dans la méthode `GetPaywall` a été modifié de `AdaptyPaywallFetchPolicy` en `AdaptyPlacementFetchPolicy`. Ce changement unifie l'utilisation de la politique de récupération dans l'ensemble du SDK. ```diff showLineNumbers using AdaptySDK; void GetPaywall(string placementId) { - Adapty.GetPaywall(placementId, AdaptyPaywallFetchPolicy.ReloadRevalidatingCacheData, null, (paywall, error) => { + Adapty.GetPaywall(placementId, AdaptyPlacementFetchPolicy.ReloadRevalidatingCacheData, null, (paywall, error) => { // handle the result }); } ``` --- # File: migration-to-unity-sdk-34 --- --- title: "Migrer le SDK Adapty Unity vers v3.4" description: "Migrez vers le SDK Adapty Unity v3.4 pour de meilleures performances et de nouvelles fonctionnalités de monétisation." --- Le SDK Adapty 3.4.0 est une version majeure qui introduit des améliorations nécessitant des étapes de migration de votre côté. ## Mettre à jour les fichiers de paywall de secours \{#update-fallback-paywall-files\} Mettez à jour vos fichiers de paywall de secours pour assurer la compatibilité avec la nouvelle version du SDK : 1. [Téléchargez les fichiers de paywall de secours mis à jour](fallback-paywalls) depuis l'Adapty Dashboard. 2. [Remplacez les paywalls de secours existants dans votre application mobile](unity-use-fallback-paywalls) par les nouveaux fichiers. ## Mettre à jour l'implémentation du mode Observateur \{#update-implementation-of-observer-mode\} Si vous utilisez le mode Observateur, assurez-vous de mettre à jour son implémentation. Auparavant, différentes méthodes étaient utilisées pour signaler les transactions à Adapty. Dans la nouvelle version, la méthode `reportTransaction` doit être utilisée de manière cohérente sur Android et iOS. Cette méthode signale explicitement chaque transaction à Adapty, garantissant qu'elle est reconnue. Si un paywall a été utilisé, transmettez l'ID de variation pour associer la transaction à celui-ci. :::warning **Ne sautez pas le signalement des transactions !** Si vous n'appelez pas `reportTransaction`, Adapty ne reconnaîtra pas la transaction, elle n'apparaîtra pas dans les analyses et ne sera pas envoyée aux intégrations. ::: ```diff showLineNumbers - #if UNITY_ANDROID && !UNITY_EDITOR - Adapty.RestorePurchases((profile, error) => { - // handle the error - }); - #endif Adapty.ReportTransaction( "YOUR_TRANSACTION_ID", "PAYWALL_VARIATION_ID", // optional (error) => { // handle the error }); ``` --- # File: migration-to-unity330 --- --- title: "Migrer le SDK Adapty Unity vers la v3.3" description: "Migrez vers le SDK Adapty Unity v3.3 pour de meilleures performances et de nouvelles fonctionnalités de monétisation." --- Le SDK Adapty 3.3.0 est une version majeure qui apporte des améliorations pouvant nécessiter quelques étapes de migration de votre côté. 1. Mettre à jour vers le SDK Adapty v3.3.x. 2. Plusieurs classes, propriétés et méthodes ont été renommées dans les modules Adapty et AdaptyUI du SDK Adapty. 3. Désormais, la méthode `SetLogLevel` accepte un callback en argument. 4. Désormais, la méthode `PresentCodeRedemptionSheet` accepte un callback en argument. 5. Modifier la façon dont la vue paywall est créée 6. Supprimer la méthode `GetProductsIntroductoryOfferEligibility`. 7. Enregistrer les paywalls de secours dans des fichiers séparés (un par plateforme) dans `Assets/StreamingAssets/` et transmettre les noms de fichiers à la méthode `SetFallbackPaywalls`. 8. Mettre à jour le processus d'achat 9. Mettre à jour la gestion des événements du Paywall Builder. 10. Mettre à jour la gestion des erreurs de paywall du Paywall Builder. 11. Mettre à jour les configurations d'intégration pour Adjust, Amplitude, AppMetrica, Appsflyer, Branch, Firebase et Google Analytics, Mixpanel, OneSignal, Pushwoosh. 13. Mettre à jour l'implémentation du mode Observer. 14. Mettre à jour l'initialisation du plugin Unity avec un appel explicite à `Activate`. ## Mettre à jour le SDK Adapty Unity vers la version 3.3.x \{#upgrade-adapty-unity-sdk-to-33x\} Jusqu'à cette version, le SDK Adapty était le SDK principal et obligatoire pour le bon fonctionnement d'Adapty dans votre application, tandis que le SDK AdaptyUI était optionnel et ne devenait nécessaire que si vous utilisiez le Paywall Builder d'Adapty. À partir de la version 3.3.0, le SDK AdaptyUI est déprécié et AdaptyUI est fusionné dans le SDK Adapty en tant que module. Suite à ces changements, vous devez supprimer AdaptyUISDK et réinstaller AdaptySDK. 1. Supprimez les dépendances de packages **AdaptySDK** et **AdaptyUISDK** de votre projet. 2. Supprimez les dossiers **AdaptySDK** et **AdaptyUISDK**. 3. Importez à nouveau le package AdaptySDK comme décrit sur la page [Installation et configuration du SDK Adapty pour Unity](sdk-installation-unity). ## Renommages \{#renamings\} 1. Renommages dans le module Adapty : | Ancienne version | Nouvelle version | | ------------------------- | ------------------------ | | Adapty.sdkVersion | Adapty.SDKVersion | | Adapty.LogLevel | AdaptyLogLevel | | Adapty.Paywall | AdaptyPaywall | | Adapty.PaywallFetchPolicy | AdaptyPaywallFetchPolicy | | PaywallProduct | AdaptyPaywallProduct | | Adapty.Profile | AdaptyProfile | | Adapty.ProfileParameters | AdaptyProfileParameters | | ProfileGender | AdaptyProfileGender | | Error | AdaptyError | 2. Renommages dans le module AdaptyUI : | Ancienne version | Nouvelle version | | ------------------ | ------------------ | | CreatePaywallView | CreateView | | PresentPaywallView | PresentView | | DismissPaywallView | DismissView | | AdaptyUI.View | AdaptyUIView | | AdaptyUI.Action | AdaptyUIUserAction | ## Modifier la méthode SetLogLevel \{#change-the-setloglevel-method\} Désormais, la méthode `SetLogLevel` accepte un callback en argument. ```diff showLineNumbers - Adapty.SetLogLevel(Adapty.LogLevel.Verbose); + Adapty.SetLogLevel(Adapty.LogLevel.Verbose, null); // or you can pass the callback to handle the possible error ``` ## Modifier la méthode PresentCodeRedemptionSheet \{#change-the-presentcoderedemptionsheet-method\} Désormais, la méthode `PresentCodeRedemptionSheet` accepte un callback en argument. ```diff showLineNumbers - Adapty.PresentCodeRedemptionSheet(); + Adapty.PresentCodeRedemptionSheet(null); // or you can pass the callback to handle the possible error ``` ## Modifier la façon dont la vue paywall est créée \{#change-how-the-paywall-view-is-created\} Pour un exemple de code complet, consultez [Récupérer la configuration de vue d'un paywall conçu avec le Paywall Builder](unity-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder). ```diff showLineNumbers + var parameters = new AdaptyUICreateViewParameters() + .SetPreloadProducts(true); - AdaptyUI.CreatePaywallView( + AdaptyUI.CreateView( paywall, - preloadProducts: true, + parameters, (view, error) => { // use the view }); ``` ## Supprimer la méthode GetProductsIntroductoryOfferEligibility \{#remove-the-getproductsintroductoryoffereligibility-method\} Avant le SDK Adapty iOS 3.3.0, l'objet produit incluait toujours les offres, que l'utilisateur y soit éligible ou non. Vous deviez vérifier manuellement l'éligibilité avant d'utiliser l'offre. Désormais, l'objet produit n'inclut une offre que si l'utilisateur est éligible. Vous n'avez donc plus besoin de vérifier l'éligibilité — si une offre est présente, l'utilisateur y est éligible. ## Mettre à jour la méthode de fourniture des paywalls de secours \{#update-method-for-providing-fallback-paywalls\} Jusqu'à cette version, les paywalls de secours étaient transmis sous forme de JSON sérialisé. À partir de la v3.3.0, le mécanisme a changé : 1. Enregistrez les paywalls de secours dans des fichiers dans `/Assets/StreamingAssets/`, 1 fichier pour Android et un autre pour iOS. 2. Transmettez les noms de fichiers à la méthode `SetFallbackPaywalls`. Votre code changera de la façon suivante : ```diff showLineNumbers using AdaptySDK; void SetFallBackPaywalls() { + #if UNITY_IOS + var assetId = "adapty_fallback_ios.json"; + #elif UNITY_ANDROID + var assetId = "adapty_fallback_android.json"; + #else + var assetId = ""; + #endif - Adapty.SetFallbackPaywalls("FALLBACK_PAYWALLS_JSON_STRING", (error) => { + Adapty.SetFallbackPaywalls(assetId, (error) => { // handle the error }); } ``` Consultez l'exemple de code final sur la page [Utiliser les paywalls de secours dans Unity](unity-use-fallback-paywalls). ## Mettre à jour le processus d'achat \{#update-making-purchase\} Auparavant, les achats annulés et en attente étaient considérés comme des erreurs et retournaient respectivement les codes `PaymentCancelled` et `PendingPurchase`. Une nouvelle classe `AdaptyPurchaseResultType` est désormais utilisée pour traiter les achats annulés, réussis et en attente. Mettez à jour le code d'achat de la façon suivante : ```diff showLineNumbers using AdaptySDK; void MakePurchase(AdaptyPaywallProduct product) { - Adapty.MakePurchase(product, (profile, error) => { - // handle successfull purchase + Adapty.MakePurchase(product, (result, error) => { + switch (result.Type) { + case AdaptyPurchaseResultType.Pending: + // handle pending purchase + break; + case AdaptyPurchaseResultType.UserCancelled: + // handle purchase cancellation + break; + case AdaptyPurchaseResultType.Success: + var profile = result.Profile; + // handle successful purchase + break; + default: + break; } }); } ``` Consultez l'exemple de code final sur la page [Effectuer des achats dans une application mobile](unity-making-purchases). ## Mettre à jour la gestion des événements du Paywall Builder \{#update-handling-of-paywall-builder-events\} Les achats annulés et en attente ne sont plus considérés comme des erreurs ; tous ces cas sont traités via la méthode `PaywallViewDidFinishPurchase`. 1. Supprimez le traitement de l'événement d'achat annulé. 2. Mettez à jour la gestion de l'événement d'achat réussi de la façon suivante : ```diff showLineNumbers - public void OnFinishPurchase( - AdaptyUI.View view, - Adapty.PaywallProduct product, - Adapty.Profile profile - ) { } + public void PaywallViewDidFinishPurchase( + AdaptyUIView view, + AdaptyPaywallProduct product, + AdaptyPurchaseResult purchasedResult + ) { } ``` 3. Mettez à jour la gestion des actions : ```diff showLineNumbers - public void OnPerformAction( - AdaptyUI.View view, - AdaptyUI.Action action - ) { + public void PaywallViewDidPerformAction( + AdaptyUIView view, + AdaptyUIUserAction action + ) { switch (action.Type) { - case AdaptyUI.ActionType.Close: + case AdaptyUIUserActionType.Close: view.Dismiss(null); break; - case AdaptyUI.ActionType.OpenUrl: + case AdaptyUIUserActionType.OpenUrl: var urlString = action.Value; if (urlString != null { Application.OpenURL(urlString); } default: // handle other events break; } } ``` 4. Mettez à jour la gestion du démarrage d'un achat : ```diff showLineNumbers - public void OnSelectProduct( - AdaptyUI.View view, - Adapty.PaywallProduct product - ) { } + public void PaywallViewDidSelectProduct( + AdaptyUIView view, + string productId + ) { } ``` 5. Mettez à jour la gestion d'un achat échoué : ```diff showLineNumbers - public void OnFailPurchase( - AdaptyUI.View view, - Adapty.PaywallProduct product, - Adapty.Error error - ) { } + public void PaywallViewDidFailPurchase( + AdaptyUIView view, + AdaptyPaywallProduct product, + AdaptyError error + ) { } ``` 6. Mettez à jour la gestion d'une restauration réussie : ```diff showLineNumbers - public void OnFailRestore( - AdaptyUI.View view, - Adapty.Error error - ) { } + public void PaywallViewDidFailRestore( + AdaptyUIView view, + AdaptyError error + ) { } ``` Consultez l'exemple de code final sur la page [Gérer les événements du paywall](unity-handling-events). ## Mettre à jour la gestion des erreurs de paywall du Paywall Builder \{#update-handling-of-paywall-builder-paywall-errors\} La gestion des erreurs a également changé. Mettez à jour votre code selon les indications ci-dessous. 1. Mettez à jour la gestion des erreurs de chargement des produits : ```diff showLineNumbers - public void OnFailLoadingProducts( - AdaptyUI.View view, - Adapty.Error error - ) { } + public void PaywallViewDidFailLoadingProducts( + AdaptyUIView view, + AdaptyError error + ) { } ``` 2. Mettez à jour la gestion des erreurs de rendu : ```diff showLineNumbers - public void OnFailRendering( - AdaptyUI.View view, - Adapty.Error error - ) { } + public void PaywallViewDidFailRendering( + AdaptyUIView view, + AdaptyError error + ) { } ``` ## Mettre à jour la configuration du SDK d'intégration tierce \{#update-third-party-integration-sdk-configuration\} À partir du SDK Adapty Unity 3.3.0, nous avons mis à jour l'API publique de la méthode `updateAttribution`. Auparavant, elle acceptait un dictionnaire `[AnyHashable: Any]`, vous permettant de passer directement des objets d'attribution de divers services. Désormais, elle requiert un `[String: any Sendable]`, vous devrez donc convertir les objets d'attribution avant de les transmettre. Pour garantir le bon fonctionnement des intégrations avec le SDK Adapty Unity 3.3.0 et versions ultérieures, mettez à jour vos configurations SDK pour les intégrations suivantes comme décrit dans les sections ci-dessous. ### Adjust Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la [configuration du SDK pour l'intégration Adjust](adjust#connect-your-app-to-adjust). ```diff showLineNumbers - using static AdaptySDK.Adapty; using AdaptySDK; Adjust.GetAdid((adid) => { - Adjust.GetAttribution((attribution) => { - Dictionary data = new Dictionary(); - - data["network"] = attribution.Network; - data["campaign"] = attribution.Campaign; - data["adgroup"] = attribution.Adgroup; - data["creative"] = attribution.Creative; - - String attributionString = JsonUtility.ToJson(data); - Adapty.UpdateAttribution(attributionString, AttributionSource.Adjust, adid, (error) => { - // handle the error - }); + if (adid != null) { + Adapty.SetIntegrationIdentifier( + "adjust_device_id", + adid, + (error) => { + // handle the error + }); } }); Adjust.GetAttribution((attribution) => { Dictionary data = new Dictionary(); data["network"] = attribution.Network; data["campaign"] = attribution.Campaign; data["adgroup"] = attribution.Adgroup; data["creative"] = attribution.Creative; String attributionString = JsonUtility.ToJson(data); - Adapty.UpdateAttribution(attributionString, AttributionSource.Adjust, adid, (error) => { + Adapty.UpdateAttribution(attributionString, "adjust", (error) => { // handle the error }); }); ``` ### Amplitude Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la [configuration du SDK pour l'intégration Amplitude](amplitude#sdk-configuration). ```diff showLineNumbers using AdaptySDK; - var builder = new Adapty.ProfileParameters.Builder(); - builder.SetAmplitudeUserId("YOUR_AMPLITUDE_USER_ID"); - builder.SetAmplitudeDeviceId(amplitude.getDeviceId()); - Adapty.UpdateProfile(builder.Build(), (error) => { - // handle error - }); + Adapty.SetIntegrationIdentifier( + "amplitude_user_id", + "YOUR_AMPLITUDE_USER_ID", + (error) => { + // handle the error + }); + Adapty.SetIntegrationIdentifier( + "amplitude_device_id", + amplitude.getDeviceId(), + (error) => { + // handle the error + }); ``` ### AppMetrica Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la [configuration du SDK pour l'intégration AppMetrica](appmetrica#sdk-configuration). ```diff showLineNumbers using AdaptySDK; - var deviceId = AppMetrica.GetDeviceId(); - if (deviceId != null { - var builder = new Adapty.ProfileParameters.Builder(); - builder.SetAppmetricaProfileId("YOUR_ADAPTY_CUSTOMER_USER_ID"); - builder.SetAppmetricaDeviceId(deviceId); - Adapty.UpdateProfile(builder.Build(), (error) => { - // handle error - }); - } + var deviceId = AppMetrica.GetDeviceId(); + if (deviceId != null { + Adapty.SetIntegrationIdentifier( + "appmetrica_device_id", + deviceId, + (error) => { + // handle the error + }); + + Adapty.SetIntegrationIdentifier( + "appmetrica_profile_id", + "YOUR_ADAPTY_CUSTOMER_USER_ID", + (error) => { + // handle the error + }); + } ``` ### AppsFlyer Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la [configuration du SDK pour l'intégration AppsFlyer](appsflyer#connect-your-app-to-appsflyer). ```diff showLineNumbers using AppsFlyerSDK; using AdaptySDK; // before SDK initialization AppsFlyer.getConversionData(this.name); // in your IAppsFlyerConversionData void onConversionDataSuccess(string conversionData) { // It's important to include the network user ID - string appsFlyerId = AppsFlyer.getAppsFlyerId(); - Adapty.UpdateAttribution(conversionData, AttributionSource.Appsflyer, appsFlyerId, (error) => { + string appsFlyerId = AppsFlyer.getAppsFlyerId(); + + Adapty.SetIntegrationIdentifier( + "appsflyer_id", + appsFlyerId, + (error) => { // handle the error }); + + Adapty.UpdateAttribution( + conversionData, + "appsflyer", + (error) => { + // handle the error + }); } ``` ### Branch Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la [configuration du SDK pour l'intégration Branch](branch#connect-your-app-to-branch). ```diff showLineNumbers using AdaptySDK; - class YourBranchImplementation { - func initializeBranch() { - Branch.getInstance().initSession(launchOptions: launchOptions) { (data, error) in - if let data { - Adapty.updateAttribution(data, source: .branch) - } - } - } - } + Branch.initSession(delegate(Dictionary parameters, string error) { + string attributionString = JsonUtility.ToJson(parameters); + + Adapty.UpdateAttribution( + attributionString, + "branch", + (error) => { + // handle the error + }); + }); ``` ### Firebase et Google Analytics Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la [configuration du SDK pour l'intégration Firebase et Google Analytics](firebase-and-google-analytics). ```diff showLineNumbers // We suppose FirebaseAnalytics Unity Plugin is already installed using AdaptySDK; Firebase.Analytics .FirebaseAnalytics .GetAnalyticsInstanceIdAsync() .ContinueWithOnMainThread((task) => { if (!task.IsCompletedSuccessfully) { // handle error return; } var firebaseId = task.Result var builder = new Adapty.ProfileParameters.Builder(); - builder.SetFirebaseAppInstanceId(firebaseId); - - Adapty.UpdateProfile(builder.Build(), (error) => { - // handle error + Adapty.SetIntegrationIdentifier( + "firebase_app_instance_id", + firebaseId, + (error) => { + // handle the error }); }); ``` ### Mixpanel Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la [configuration du SDK pour l'intégration Mixpanel](mixpanel#sdk-configuration). ```diff showLineNumbers using AdaptySDK; - var builder = new Adapty.ProfileParameters.Builder(); - builder.SetMixpanelUserId(Mixpanel.DistinctId); - Adapty.UpdateProfile(builder.Build(), (error) => { - // handle error - }); + var distinctId = Mixpanel.DistinctId; + if (distinctId != null) { + Adapty.SetIntegrationIdentifier( + "mixpanel_user_id", + distinctId, + (error) => { + // handle the error + }); + } ``` ### OneSignal Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la [configuration du SDK pour l'intégration OneSignal](onesignal#sdk-configuration). ```diff showLineNumbers using AdaptySDK; - using OneSignalSDK; - var pushUserId = OneSignal.Default.PushSubscriptionState.userId; - var builder = new Adapty.ProfileParameters.Builder(); - builder.SetOneSignalPlayerId(pushUserId); - Adapty.UpdateProfile(builder.Build(), (error) => { - // handle error - }); + var distinctId = Mixpanel.DistinctId; + if (distinctId != null) { + Adapty.SetIntegrationIdentifier( + "mixpanel_user_id", + distinctId, + (error) => { + // handle the error + }); + } ``` ### Pushwoosh Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la [configuration du SDK pour l'intégration Pushwoosh](pushwoosh#sdk-configuration). ```diff showLineNumbers using AdaptySDK; - var builder = new Adapty.ProfileParameters.Builder(); - builder.SetPushwooshHWID(Pushwoosh.Instance.HWID); - Adapty.UpdateProfile(builder.Build(), (error) => { - // handle error - }); + Adapty.SetIntegrationIdentifier( + "pushwoosh_hwid", + Pushwoosh.Instance.HWID, + (error) => { + // handle the error + }); ``` ## Mettre à jour l'implémentation du mode Observer \{#update-observer-mode-implementation\} Mettez à jour la façon dont vous associez les paywalls aux transactions. Auparavant, vous utilisiez la méthode `setVariationId` pour assigner le `variationId`. Désormais, vous pouvez inclure le `variationId` directement lors de l'enregistrement de la transaction grâce à la nouvelle méthode `reportTransaction`. Consultez l'exemple de code final dans [Associer les paywalls aux transactions d'achat en mode Observer](report-transactions-observer-mode-unity). ```diff showLineNumbers // every time when calling transaction.finish() - Adapty.SetVariationForTransaction("", "", (error) => { - if(error != null) { - // handle the error - return; - } - - // successful binding - }); + Adapty.ReportTransaction( + "YOUR_TRANSACTION_ID", + "PAYWALL_VARIATION_ID", // optional + (error) => { + // handle the error + }); ``` ## Mettre à jour l'initialisation du plugin Unity \{#update-the-unity-plugin-initialization\} À partir du SDK Adapty Unity 3.3.0, l'appel explicite à la méthode `Activate` lors de l'initialisation du plugin est obligatoire : ```csharp showLineNumbers Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); ``` --- # File: migration-to-unity-sdk-v3 --- --- title: "Migrer le SDK Adapty Unity vers v3.0" description: "Migrez vers le SDK Adapty Unity v3.0 pour de meilleures performances et de nouvelles fonctionnalités de monétisation." --- Le SDK Adapty v3.0 apporte la prise en charge du nouveau [Adapty Paywall Builder](adapty-paywall-builder), la nouvelle version de l'outil no-code convivial pour créer des paywalls. Grâce à sa flexibilité maximale et à ses riches capacités de design, vos paywalls deviendront plus efficaces et rentables que jamais. ## Processus de migration \{#upgrade-process\} Le processus de migration pour Unity suit les mêmes étapes que pour les autres plateformes : 1. Mettre à niveau vers le SDK Adapty v3.x 2. Migrer vos paywalls existants vers le nouveau Paywall Builder Pour des instructions de migration spécifiques à Unity, consultez le [guide d'installation du SDK Unity](sdk-installation-unity) et suivez les étapes de migration générales décrites dans le guide de migration principal. --- # File: unity-migration-guide --- --- title: "Guide de migration SDK" description: "Guides de migration pour le SDK Adapty Unity." --- ## Guides de migration ### [Guide de migration vers le SDK Adapty Unity 3.x](unity-sdk-migration-guides) Apprenez à migrer depuis les versions antérieures vers le SDK Adapty Unity 3.x. ## Nouveautés ### Version 3.x - Présentation des paywalls améliorée - Gestion des erreurs améliorée - Meilleur support C# - Optimisations des performances ### Version 2.x - Nouvelles fonctionnalités d'onboarding - Analytics améliorée - Flow d'achat amélioré - Corrections de bugs et améliorations de stabilité ## Changements majeurs ### Version 3.x - API Observer mise à jour - Méthodes de présentation des paywalls modifiées - Structure de gestion des erreurs modifiée ### Version 2.x - API d'onboarding mise à jour - Structure du profil modifiée - Flow d'achat modifié ## Liste de contrôle pour la migration Lors de la migration vers une nouvelle version : - [ ] Vérifier les changements majeurs - [ ] Mettre à jour les appels API - [ ] Tester toutes les fonctionnalités - [ ] Mettre à jour la gestion des erreurs - [ ] Vérifier le suivi des analytics - [ ] Tester sur toutes les plateformes --- # End of Documentation _Generated on: 2026-08-11T20:58:32.471Z_ _Successfully processed: 52/52 files_