# REACT-NATIVE - Adapty Documentation (Full Content) This file contains the complete content of all documentation pages for this platform. Locale: fr Generated on: 2026-08-11T07:13:23.541Z Total files: 57 --- # File: react-native-sdk-overview --- --- title: "React Native SDK overview" description: "Découvrez le SDK React Native Adapty et ses fonctionnalités clés." --- [](https://github.com/adaptyteam/AdaptySDK-React-Native/releases) Bienvenue ! Nous sommes là pour simplifier vos achats intégrés 🚀 Nous avons conçu le SDK React Native Adapty pour vous libérer des contraintes des achats intégrés et vous permettre de vous concentrer sur ce que vous faites le mieux – créer des applications extraordinaires. Voici ce dont nous nous occupons pour vous : - Gestion des achats, validation des reçus et gestion des abonnements prêts à l'emploi - Création et test de flows et de paywalls sans mise à jour de l'application - Analyses d'achats détaillées sans aucune configuration – cohortes, LTV, churn et analyse de funnel inclus - Statut d'abonnement utilisateur toujours à jour entre les sessions et les appareils - Intégration avec des services d'attribution marketing et d'analyse en une seule ligne de code Que votre application soit développée avec **Expo** ou en **React Native pur**, le SDK Adapty prend en charge les deux environnements. :::note Avant de plonger dans le code, vous devrez intégrer Adapty avec App Store Connect et Google Play Console, puis configurer vos produits dans le tableau de bord. Consultez notre [guide de démarrage rapide](quickstart) pour tout configurer en premier. ::: ## Premiers pas \{#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 aborder dans le guide d'intégration : 1. [Installer et configurer le SDK](sdk-installation-reactnative) : Ajoutez le SDK comme dépendance à votre projet et activez-le dans le code. Adapty fonctionne aussi bien avec **Expo** que dans des projets **React Native purs**. 2. [Activer les achats via les flows](react-native-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](react-native-quickstart-manual). 3. [Vérifier le statut d'abonnement](react-native-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 (optionnel)](react-native-quickstart-identify) : Associez les utilisateurs à leurs profils Adapty pour garantir la cohérence de leurs données sur tous les appareils. ### En action \{#see-it-in-action\} Envie de voir comment tout s'assemble ? Nous avons ce qu'il vous faut : - **Exemples d'applications** : Consultez nos [exemples complets](https://github.com/adaptyteam/AdaptySDK-React-Native/tree/master/examples) qui illustrent la configuration complète - **Tutoriel vidéo** : Suivez notre vidéo d'implémentation étape par étape ci-dessous
### 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 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 la valeur du paramètre en dur, tous les utilisateurs seront considérés comme un seul.
:::
Attendez toujours la résolution de `identify` avec `await` avant d'appeler d'autres méthodes du SDK. Les appels simultanés produisent l'erreur `#3006 profileWasChanged` ou atterrissent sur le profil anonyme. Consultez [Ordre des appels dans le SDK React Native](react-native-sdk-call-order).
```typescript showLineNumbers
try {
await adapty.identify("YOUR_USER_ID"); // Unique for each user
// successfully identified
} catch (error) {
// handle the error
}
```
### Lors de l'activation du SDK \{#during-the-sdk-activation\}
Si vous connaissez déjà un customer user ID au moment d'activer le SDK, vous pouvez l'envoyer dans la méthode `activate` au lieu 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 qu'au moment 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é) ou un nouveau. Si vous en passez un nouveau, le profil créé lors de l'activation sera automatiquement lié à ce customer user ID.
:::note
Par défaut, la création de profils anonymes n'affecte pas les tableaux de bord d'analyse, car les installations sont comptées sur la base des ID d'appareil.
Un ID d'appareil représente une seule installation de l'application depuis le store sur un appareil et n'est regé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 nième 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 réinstallation ne génèrent pas d'événements d'installation supplémentaires.
Si vous souhaitez compter 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).
:::
```typescript showLineNumbers
adapty.activate("PUBLIC_SDK_KEY", {
customerUserId: "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.
});
```
### Déconnecter les utilisateurs \{#log-users-out\}
Si votre application propose un bouton de déconnexion, utilisez la méthode `logout`.
:::important
La déconnexion des utilisateurs crée un nouveau profil anonyme pour l'utilisateur.
:::
```typescript showLineNumbers
try {
await adapty.logout();
// successful logout
} catch (error) {
// handle the error
}
```
:::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 avant et après leur connexion à 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 l'associe à 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 assigne 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`](react-native-check-subscription-status) juste après l'identification, soit [écouter les mises à jour du profil](react-native-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) : Vérifiez que tout fonctionne comme prévu
- [**Onboardings**](react-native-onboardings) : Engagez les utilisateurs avec des onboardings et stimulez la rétention
- [**Intégrations**](configuration) : Intégrez des services d'attribution marketing et d'analyse en une seule ligne de code
- [**Définir des attributs de profil personnalisés**](react-native-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-react-native
---
---
title: "Intégrer Adapty dans votre application React Native 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 React Native 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-react-native) à la place — il guide votre outil IA à travers chaque étape avec la bonne documentation.
:::
La [compétence adapty-sdk-integration](https://github.com/adaptyteam/adapty-sdk-integration-skill) automatise l'intégration Adapty de bout en bout : configuration du tableau de bord, installation du SDK, paywall et vérification à chaque étape. Elle détecte automatiquement votre plateforme et récupère la documentation Adapty pertinente à chaque étape.
**Outils compatibles** : Claude Code, GitHub Copilot CLI, OpenAI Codex, Gemini CLI.
Pour installer, choisissez le formulaire correspondant à votre outil. La liste complète se trouve dans le [README de la compétence](https://github.com/adaptyteam/adapty-sdk-integration-skill).
**Claude Code**
```
claude plugin marketplace add adaptyteam/adapty-sdk-integration-skill
claude plugin install adapty-sdk-integration@adapty
```
**GitHub Copilot CLI**
```
gh skill install adaptyteam/adapty-sdk-integration-skill
```
**Gemini CLI**
```
gemini skills install https://github.com/adaptyteam/adapty-sdk-integration-skill
```
**OpenAI Codex ou tout autre outil** — utilisez la [CLI skills](https://skills.sh) (notez que les compétences installées de cette façon ne se mettent pas à jour automatiquement) :
```
npx skills add adaptyteam/adapty-sdk-integration-skill
```
Vous pouvez également cloner le dépôt et copier `skills/adapty-sdk-integration/` dans le répertoire des compétences de votre outil.
Après l'installation, exécutez la compétence dans votre projet :
```
/adapty-sdk-integration
```
La compétence 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-react-native
---
---
title: "Intégrer Adapty dans votre application React Native avec l'aide de l'IA"
description: "Un guide pas à pas pour intégrer Adapty dans votre application React Native 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 React Native à l'aide d'un outil de codage 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 une configuration dans le tableau de bord avant d'écrire le moindre 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 app, vos produits, niveaux d'accès, paywalls et placements directement — sans ouvrir le Dashboard à chaque étape. Il vous suffit de [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 pour savoir quand ouvrir le Dashboard afin de connecter vos stores.
### Approche manuelle via le Dashboard \{#dashboard-approach\}
Si vous préférez tout configurer manuellement, voici ce dont vous avez besoin 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 app 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 trouvez la section **API keys**. Dans le code, c'est la chaîne que vous passez à `adapty.activate("YOUR_PUBLIC_SDK_KEY")`.
3. **Créez au moins un produit** : Dans l'Adapty Dashboard, rendez-vous sur 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 du 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 apps. 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 que vous avez ces cinq éléments, vous êtes prêt à coder. Dites à votre LLM : "Ma clé SDK publique est X, mon ID de placement est Y" pour qu'il génère du code d'initialisation et de récupération de paywall correct.
:::
### À configurer quand vous êtes 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**. Aucune modification de code nécessaire.
[Tests A/B](ab-tests)
- **Paywalls et placements supplémentaires** : Ajoutez d'autres appels `getPaywall` avec des IDs de placement différents.
- **Intégrations analytics** : Configurez-les sur la page **Integrations**. La configuration varie selon l'intégration. Voir [intégrations analytics](analytics-integration) et [intégrations attribution](attribution-integration).
## Fournir les docs 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 en fonction de 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 React Native SDK
```
:::warning
Même si Context7 supprime le besoin de coller des liens de docs manuellement, l'ordre d'implémentation reste important. Suivez le [parcours d'implémentation](#implementation-walkthrough) ci-dessous étape par étape pour vous assurer que tout fonctionne.
:::
### 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-react-native.md](https://adapty.io/docs/fr/adapty-cursor-react-native.md).
Chaque étape du [parcours d'implémentation](#implementation-walkthrough) ci-dessous inclut un bloc "Envoyez ceci à 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\}
Le reste de ce guide parcourt l'intégration d'Adapty dans l'ordre d'implémentation. Chaque étape inclut les docs à envoyer à votre LLM, ce que vous devriez voir une fois terminé, et les problèmes courants.
### Planifier votre intégration \{#plan-your-integration\}
Avant de vous lancer 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 Cursor ou le mode plan de 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 qu'il devra suivre :
- [**Adapty Paywall Builder**](adapty-paywall-builder) : Vous créez des paywalls dans l'éditeur no-code d'Adapty, et le SDK les affiche automatiquement.
- [**Paywalls créés manuellement**](react-native-making-purchases) : Vous construisez votre propre interface de paywall dans le code, mais utilisez quand même Adapty pour récupérer les produits et gérer les achats.
- [**Mode Observer**](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 guide de démarrage](react-native-quickstart-paywalls).
### Installer et configurer le SDK \{#install-and-configure-the-sdk\}
Ajoutez la dépendance Adapty SDK via npm (ou yarn) et activez-la avec votre clé SDK publique. C'est la base — rien d'autre ne fonctionne sans ça.
Nous avons des guides d'installation distincts pour Expo et les projets React Native bare — choisissez celui qui correspond à votre configuration.
**Guides :**
- [Installer avec Expo](sdk-installation-react-native-expo)
- [Installer avec React Native bare](sdk-installation-react-native-pure)
Envoyez ceci à votre LLM (choisissez celui qui correspond à votre configuration, ou envoyez les deux) :
```
Read these Adapty docs before writing code:
- https://adapty.io/docs/fr/sdk-installation-react-native-expo.md
- https://adapty.io/docs/fr/sdk-installation-react-native-pure.md
```
:::tip[Point de contrôle]
- **Attendu :** L'app se compile et tourne sur iOS et Android. Les logs de Metro bundler affichent le log d'activation Adapty.
- **Problème fréquent :** "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.
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 `.returnCacheDataElseLoad` pour renvoyer les données en cache si elles existent. Dans ce cas, les utilisateurs ne recevront peut-être pas 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 sûr de l'utiliser pendant la session afin d'éviter des 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.
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](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 de toujours obtenir la dernière version de vos paywalls tout en assurant la fiabilité même lorsque la connexion internet est limitée.
| | **loadTimeoutMs** | 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 seront 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 comprendre différentes requêtes en arrière-plan.
Pour Android : Vous pouvez créer un `TimeInterval` avec des fonctions d'extension (comme `5.seconds`, où `.seconds` provient de `import com.adapty.utils.seconds`), ou `TimeInterval.seconds(5)`. Pour ne pas fixer de limite, utilisez `TimeInterval.INFINITE`.
| ## Paramètres de réponse \{#response-parameters\} | Paramètre | Description | | :-------- |:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Flow | Un objet `AdaptyFlow` contenant les identifiants du flow (`id`, `variationId`), son nom, son placement, ses variantes de paywall (`paywalls`) et les éventuels Remote Configs (`remoteConfigs`). | ## Récupérer la configuration de la vue \{#fetch-the-view-configuration\} :::important Assurez-vous d'activer le bouton **Show on device** dans le builder. Si cette option n'est pas activée, la configuration de la vue ne sera pas disponible. ::: Si le placement a été conçu dans le **Flow Builder** ou le **Paywall Builder**, Adapty génère l'interface utilisateur pour vous. Créez la vue avec `createFlowView`, puis [présentez le flow ou le paywall](react-native-present-paywalls). Si le placement est un paywall personnalisé sans interface dans le Builder, [gérez-le comme un paywall Remote Config](present-remote-config-paywalls-react-native) à la place. Dans le SDK React Native, appelez `createFlowView` directement — inutile de récupérer d'abord la configuration de la vue. :::warning Le résultat de la méthode `createFlowView` ne peut être utilisé qu'une seule fois. Si vous devez l'utiliser à nouveau, appelez de nouveau la méthode `createFlowView`. L'appeler deux fois sans recréer la vue peut entraîner l'erreur `AdaptyUIError.viewAlreadyPresented`. ::: ```typescript showLineNumbers try { const view = await createFlowView(flow); } catch (error) { // handle the error } ``` Paramètres : | Paramètre | Présence | Description | | :------------------- | :------- | :----------------------------------------------------------- | | **flow** | requis | Un objet `AdaptyFlow` permettant d'obtenir un contrôleur pour le flow/paywall souhaité. | | **locale** | optionnel | L'identifiant de la [localisation du flow](add-paywall-locale-in-adapty-paywall-builder) avec laquelle afficher la vue — par exemple, `en` ou `pt-br`. Si omis, la vue s'affiche en `en`, ou dans la localisation par défaut du flow si celui-ci ne dispose pas de `en`. Nécessite le SDK 4.0.2 ou version ultérieure. Voir [Localisations et codes de langue](react-native-localizations-and-locale-codes). | | **customTags** | optionnel | Définit un dictionnaire de tags personnalisés et leurs valeurs résolues. Les tags personnalisés servent de placeholders dans le contenu, remplacés dynamiquement par des chaînes spécifiques pour personnaliser le contenu du flow/paywall. Consultez la rubrique Tags personnalisés dans le Paywall Builder pour plus de détails. | | **prefetchProducts** | optionnel | À activer pour optimiser le moment d'affichage des produits à l'écran. Lorsque `true`, AdaptyUI récupère automatiquement les produits nécessaires. Par défaut : `false`. | | **android.enableSafeArea** | optionnel | Android uniquement (ignoré sur iOS). À passer en tant qu'objet imbriqué : `android: { enableSafeArea: true }`. Lorsque `true`, la vue du flow applique les marges de zone sécurisée. Par défaut `true` pour la présentation modale (`createFlowView` + `present()`) et `false` pour le composant `AdaptyFlowView` intégré. La valeur par défaut convient à la plupart des cas. | :::note Si vous utilisez plusieurs langues, découvrez comment ajouter une [localisation de flow](add-paywall-locale-in-adapty-paywall-builder) et comment utiliser correctement les codes de langue [ici](react-native-localizations-and-locale-codes). ::: Une fois que vous avez la vue, [affichez le flow/paywall](react-native-present-paywalls). ## Récupérer 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 règle générale, les flows et les paywalls 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 placements et que vos utilisateurs disposent d'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 du tout. Pour remédier à cela, 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 indiqué dans la section [Récupérer le flow/paywall](#fetch-flowpaywall) 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 paywalls différents selon les versions de l'application (actuelle et futures), vous pourrez rencontrer des difficultés. Vous devrez soit concevoir des paywalls compatibles avec la version actuelle (héritée), soit accepter que les utilisateurs de cette version puissent rencontrer des problèmes avec des paywalls non affichés. - **Perte de ciblage** : Tous les utilisateurs verront le même paywall 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'un chargement plus rapide des flows ou des paywalls, utilisez la méthode `getFlowForDefaultAudience` comme suit. Sinon, restez sur `getFlow` décrit [ci-dessus](#fetch-flowpaywall). ::: ```typescript showLineNumbers try { const id = 'YOUR_PLACEMENT_ID'; const flow = await adapty.getFlowForDefaultAudience(id); // the requested flow/paywall } catch (error) { // handle the error } ``` | Paramètre | Présence | Description | |---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **placementId** | obligatoire | L'identifiant du [Placement](placements). Il s'agit de la valeur que vous avez spécifiée lors de la création d'un placement dans votre Adapty Dashboard. | | **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 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 peuvent 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 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 désinstallation ou par un nettoyage manuel.
| ## Personnaliser les ressources \{#customize-assets\} Pour personnaliser les images et vidéos dans votre flow/paywall, implémentez des ressources personnalisées. Les images et vidéos hero ont des identifiants prédéfinis : `hero_image` et `hero_video`. Dans un bundle de ressources personnalisé, vous ciblez ces éléments par leur identifiant et personnalisez leur comportement. Pour les autres images et vidéos, vous devez [définir un identifiant 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 de l'image principale distante. - Afficher une image de prévisualisation avant de lancer une vidéo. :::important Pour utiliser cette fonctionnalité, mettez à jour le SDK React Native 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 : ```javascript const customAssets: Recordoptionnel
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 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](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 disposent toujours des données les plus récentes.
Cependant, si vous pensez que vos utilisateurs sont confrontés à 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 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 après le redémarrage de l'application et n'est effacé que lors de la réinstallation de l'application ou via 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'indisponibilité 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.
| | **loadTimeoutMs** | 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 être composée de différentes requêtes en coulisses.
Pour Android : vous pouvez créer un `TimeInterval` avec des fonctions d'extension (comme `5.seconds`, où `.seconds` provient de `import com.adapty.utils.seconds`), ou `TimeInterval.seconds(5)`. Pour ne pas définir de limite, utilisez `TimeInterval.INFINITE`.
| ## Paramètres de réponse \{#response-parameters\} | Paramètre | Description | | :-------- |:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Paywall | Un objet [`AdaptyPaywall`](https://react-native.adapty.io/interfaces/adaptypaywall) contenant une liste d'identifiants de produits, l'identifiant du paywall, la Remote Config, ainsi que plusieurs autres propriétés. | ## Récupérer la configuration de vue d'un paywall conçu avec le 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 de vue ne sera pas disponible à 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 le 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-react-native). Dans le SDK React Native, 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 à nouveau la méthode `createPaywallView`. L'appeler deux fois sans recréer peut entraîner l'erreur `AdaptyUIError.viewAlreadyPresented`. ::: ```typescript showLineNumbers // for the Adapty SDK < 3.14 – import {createPaywallView} from 'react-native-adapty/dist/ui'; if (paywall.hasViewConfiguration) { try { const view = await createPaywallView(paywall); } catch (error) { // handle the error } } else { //use your custom logic } ``` Paramètres : | Paramètre | Présence | Description | | :------------------- | :------- | :----------------------------------------------------------- | | **paywall** | obligatoire | Un objet `AdaptyPaywall` permettant d'obtenir un contrôleur pour le paywall souhaité. | | **customTags** | optionnel | Définit un dictionnaire de tags personnalisés et leurs valeurs résolues. Les tags personnalisés servent de marqueurs de substitution dans le contenu du paywall, remplacés dynamiquement par des chaînes spécifiques pour personnaliser le contenu du paywall. Consultez la rubrique Custom tags in paywall builder pour plus de détails. | | **prefetchProducts** | optionnel | À activer pour optimiser le moment d'affichage des produits à l'écran. Lorsque la valeur est `true`, AdaptyUI récupère automatiquement les produits nécessaires. Par défaut : `false`. | :::note Si vous utilisez plusieurs langues, découvrez comment ajouter une [localisation dans le Paywall Builder](add-paywall-locale-in-adapty-paywall-builder) et comment utiliser correctement les codes de langue [ici](react-native-localizations-and-locale-codes). ::: Une fois que vous avez la vue, [affichez le paywall](react-native-present-paywalls). ## Récupérer un paywall pour l'audience par défaut afin d'accélérer le chargement \{#get-a-paywall-for-a-default-audience-to-fetch-it-faster\} 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 résoudre ce problème, 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 est de récupérer le paywall via la méthode `getPaywall`, comme décrit dans la section [Récupérer les informations du paywall](#fetch-paywall-designed-with-paywall-builder) ci-dessus. :::warning Pourquoi nous recommandons d'utiliser `getPaywall` La méthode `getPaywallForDefaultAudience` présente quelques inconvénients importants : - **Problèmes potentiels de compatibilité descendante** : si vous devez afficher des paywalls différents selon les versions de l'application (actuelle et futures), vous risquez de rencontrer des difficultés. Il vous faudra soit concevoir des paywalls compatibles avec la version actuelle (legacy), soit accepter que les utilisateurs de cette version puissent avoir des problèmes d'affichage. - **Perte de ciblage** : tous les utilisateurs verront le même paywall 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 êtes prêt à accepter ces inconvénients pour bénéficier d'une récupération plus rapide des paywalls, utilisez la méthode `getPaywallForDefaultAudience` comme suit. Sinon, restez sur `getPaywall` décrit [ci-dessus](#fetch-paywall-designed-with-paywall-builder). ::: ```typescript showLineNumbers try { const id = 'YOUR_PLACEMENT_ID'; const locale = 'en'; const paywall = await adapty.getPaywallForDefaultAudience(id, locale); // the requested paywall } catch (error) { // handle the error } ``` :::note La méthode `getPaywallForDefaultAudience` est disponible à partir de la version 2.11.2 du SDK React Native. ::: | 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. | | **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 locale](react-native-localizations-and-locale-codes) pour plus d'informations sur les codes de locale et notre recommandation d'utilisation.
| | **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.
Cependant, 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 verront pas forcément 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 un redémarrage de l'application et n'est effacé que lors d'une réinstallation ou d'un nettoyage manuel.
| ## Personnaliser les ressources \{#customize-assets\} Pour personnaliser les images et vidéos de votre paywall, implémentez des ressources personnalisées. Les images et vidéos hero ont des ID prédéfinis : `hero_image` et `hero_video`. Dans un bundle de ressources personnalisées, vous ciblez ces éléments par leur ID et personnalisez leur comportement. Pour les autres images et vidéos, vous devez [définir un ID personnalisé](custom-media) dans le tableau de bord Adapty. 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 React Native d'Adapty vers la version 3.8.0 ou supérieure. ::: Voici un exemple illustrant comment fournir des ressources personnalisées via un simple dictionnaire : ```javascript const customAssets: Record
## Le nombre de vues du paywall est trop élevé \{#the-paywall-view-number-is-too-big\}
**Problème** : Le compteur de vues du paywall affiche le double du nombre attendu.
**Cause** : Vous appelez peut-être `logShowFlow` (SDK React Native v4+) / `logShowPaywall` dans votre code, ce qui duplique le compteur de vues si vous utilisez le Paywall Builder ou le Flow Builder. Pour les flows et paywalls créés avec ces outils, les analytics sont suivies automatiquement, vous n'avez donc pas besoin d'utiliser cette méthode.
**Solution** : Vérifiez que vous n'appelez pas `logShowFlow` (SDK React Native 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** : Migrez le SDK vers la dernière version à l'aide des [guides de migration](react-native-sdk-migration-guides) si nécessaire. De nombreux problèmes sont résolus dans les versions plus récentes du SDK.
---
# File: react-native-implement-paywalls-manually
---
---
title: "Implémenter les paywalls manuellement dans le SDK React Native"
description: "Apprenez à implémenter les paywalls manuellement dans votre application React Native 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`. Ainsi, nous gérerons tous les scénarios utilisateur, et vous n'aurez qu'à traiter les résultats des achats.
:::important
`makePurchase` fonctionne avec les produits créés dans 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).
:::
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 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é qu'en cas de réinstallation ou de 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](react-native-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 autonome en cas d'indisponibilité du CDN. Ce système est conçu pour vous garantir toujours la dernière version de vos flows tout en assurant la fiabilité, même lorsque la connexion internet est limitée.
| | **loadTimeoutMs** | 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 seront 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 être composée de différentes requêtes en coulisses.
| :::note Dans la v4, `getFlow` ne prend plus de paramètre `locale`. Pour les paywalls personnalisés, toutes les locales disponibles sont retournées dans le Remote Config du flow (`flow.remoteConfigs`) — choisissez celle qui correspond à la langue de l'appareil ou au paramètre de l'application. ::: Ne codez pas les identifiants de produit en dur ! Les flows étant configurés à distance, les produits disponibles, leur nombre et les offres spéciales (comme les essais gratuits) peuvent évoluer dans le temps. Assurez-vous que votre code gère ces scénarios. Par exemple, si vous récupérez initialement 2 produits, votre application doit les afficher. Mais si vous en récupérez 3 plus tard, votre application doit tous les afficher sans aucune 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 le placement, les identifiants (`id`, `variationId`), le nom, ses variations de paywall (`paywalls`), et un tableau `remoteConfigs` (une entrée par locale configurée). Pour récupérer les produits du flow, appelez `getPaywallProducts(flow)`. | ## 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 : ```typescript showLineNumbers try { // ...flow const products = await adapty.getPaywallProducts(flow); // the requested products list } catch (error) { // handle the error } ``` Paramètres de la réponse : | Paramètre | Description | | :-------- |:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Products | Liste d'objets [`AdaptyPaywallProduct`](https://react-native.adapty.io/interfaces/adaptypaywallproduct) avec : 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 paywall, vous aurez probablement besoin d'accéder aux propriétés de l'objet [`AdaptyPaywallProduct`](https://react-native.adapty.io/interfaces/adaptypaywallproduct). Les propriétés les plus couramment utilisées sont illustrées ci-dessous, mais consultez le document lié pour obtenir des détails complets 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 de nombre 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 (par ex. semaine, mois, année, etc.), utilisez `product.subscription?.localizedSubscriptionPeriod`. 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?.subscriptionPeriod`. Vous pouvez ensuite accéder à la propriété `unit` pour obtenir la durée (c'est-à-dire `'day'`, `'week'`, `'month'`, `'year'` ou `'unknown'`). La valeur `numberOfUnits` vous donne le nombre d'unités de période. Par exemple, pour un abonnement trimestriel, vous verrez `'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 d'introduction. Chaque objet de phase contient les propriétés utiles suivantes :Par défaut, le SDK tentera de charger les données depuis le serveur et retournera 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 retourner les données en cache si elles existent. Dans ce cas, les utilisateurs pourraient ne pas obtenir 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 lors du redémarrage de l'application et n'est effacé que lors de la désinstallation de l'application ou via un nettoyage manuel.
|optionnel
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](react-native-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 reçoivent toujours les données les plus récentes.
Toutefois, si votre application est utilisée dans des conditions de connectivité instable, envisagez d'utiliser `.returnCacheDataElseLoad` pour renvoyer les données en cache lorsqu'elles existent. Dans ce cas, les utilisateurs n'auront pas forcément 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 fiable 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 sur deux couches : le cache mis à jour régulièrement décrit ci-dessus et les [paywalls de secours](react-native-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 vous garantir la dernière version de vos paywalls tout en assurant une fiabilité même lorsque la connexion internet est limitée.
| | **loadTimeoutMs** | 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 spécifié dans `loadTimeout`, car l'opération peut reposer sur plusieurs requêtes en arrière-plan.
| N'intégrez pas les identifiants de produit en dur dans votre code ! Comme les paywalls 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 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 3 par la suite, votre application doit tous les afficher sans nécessiter de modification du code. La seule chose à intégrer en dur est l'identifiant du placement. Paramètres de réponse : | Paramètre | Description | | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | | Paywall | Un objet [`AdaptyPaywall`](https://react-native.adapty.io/interfaces/adaptypaywall) contenant : une liste d'identifiants de produits, l'identifiant du paywall, la Remote Config, et plusieurs autres propriétés. | ## Récupérer les produits \{#fetch-products\} Une fois que vous avez le paywall, vous pouvez interroger le tableau de produits qui lui correspond : ```typescript showLineNumbers try { // ...paywall const products = await adapty.getPaywallProducts(paywall); // the requested products list } catch (error) { // handle the error } ``` Paramètres de réponse : | Paramètre | Description | | :-------- |:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Products | Liste d'objets [`AdaptyPaywallProduct`](https://react-native.adapty.io/interfaces/adaptypaywallproduct) avec : identifiant du produit, nom du produit, prix, devise, durée d'abonnement et plusieurs autres propriétés. | Lors de la mise en œuvre de votre propre design de paywall, vous aurez probablement besoin d'accéder à ces propriétés depuis l'objet [`AdaptyPaywallProduct`](https://react-native.adapty.io/interfaces/adaptypaywallproduct). Les propriétés les plus couramment utilisées sont illustrées ci-dessous, mais consultez le document lié pour obtenir tous les détails sur l'ensemble des 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 du terminal. | | **Price** | Pour afficher le prix localisé, utilisez `product.price?.localizedString`. Cette localisation est basée sur les paramètres régionaux du terminal. 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?.localizedSubscriptionPeriod`. Cette localisation est basée sur les paramètres régionaux du terminal. Pour récupérer la période d'abonnement de façon programmatique, utilisez `product.subscription?.subscriptionPeriod`. Vous pouvez accéder à la propriété `unit` pour obtenir la durée (c'est-à-dire `'day'`, `'week'`, `'month'`, `'year'` ou `'unknown'`). La valeur `numberOfUnits` vous donnera le nombre d'unités de période. Par exemple, pour un abonnement trimestriel, vous verrez `'month'` dans la propriété unit et `3` dans la propriété numberOfUnits. | | **Introductory Offer** | Pour afficher un badge ou un indicateur signalant qu'un abonnement inclut 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 d'introduction. Chaque objet de phase contient les propriétés suivantes :optionnel
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 indique la langue, le second la région.
Exemple : `en` désigne l'anglais, `pt-br` le portugais brésilien.
Consultez [Localisations et codes de langue](react-native-localizations-and-locale-codes) pour plus d'informations sur les codes de langue et notre façon de les utiliser.
| | **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 instable, envisagez d'utiliser `.returnCacheDataElseLoad` pour renvoyer les données en cache lorsqu'elles existent. Dans ce cas, les utilisateurs n'auront pas forcément 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 pour éviter les 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 l'application ou via un nettoyage manuel.
|Si la requête a réussi, la réponse contient cet objet. Un objet [AdaptyProfile](https://react-native.adapty.io/interfaces/adaptyprofile) 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 la version StoreKit d'Apple inférieure à v2.0 et une version du SDK Adapty 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 l'abonnement actuel, le comportement dépend du store : - Pour l'App Store, l'abonnement est automatiquement mis à jour au sein du groupe d'abonnements. Si un utilisateur achète un abonnement d'un groupe alors qu'il a déjà un abonnement d'un autre groupe, les deux abonnements seront actifs simultanément. - Pour Google Play, l'abonnement n'est pas automatiquement mis à jour. Vous devrez gérer le changement dans le code de votre application mobile comme décrit ci-dessous. Pour remplacer l'abonnement par un autre sur Android, appelez la méthode `.makePurchase()` avec le paramètre supplémentaire : ```typescript showLineNumbers try { const purchaseResult = await adapty.makePurchase(product, params); switch (purchaseResult.type) { case 'success': const isSubscribed = purchaseResult.profile?.accessLevels['YOUR_ACCESS_LEVEL']?.isActive; if (isSubscribed) { // Grant access to the paid features } break; case 'user_cancelled': // Handle the case where the user canceled the purchase break; case 'pending': // Handle deferred purchases (e.g., the user will pay offline with cash) break; } } catch (error) { // Handle the error } ``` Paramètre de requête supplémentaire : | Paramètre | Présence | Description | | :--------- | :------- | :----------------------------------------------------------- | | **params** | requis | un objet de type [`MakePurchaseParamsInput`](https://react-native.adapty.io/types/makepurchaseparamsinput). | :::info **Version 3.8.2+** : La structure `MakePurchaseParamsInput` a été mise à jour. `oldSubVendorProductId` et `prorationMode` sont désormais imbriqués sous `subscriptionUpdateParams`, et `isOfferPersonalized` est déplacé au niveau supérieur. Exemple : ```javascript makePurchase(product, { android: { subscriptionUpdateParams: { oldSubVendorProductId: 'old_product_id', prorationMode: 'charge_prorated_price' }, isOfferPersonalized: true } }); ``` ::: Vous pouvez en savoir plus sur les abonnements et les modes de remplacement dans la documentation Google Developer : - [À 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 réel n'aura lieu qu'à la fin de la période de facturation de l'abonnement actuel. ## Utiliser des codes promotionnels sur iOS \{#redeem-offer-codes-in-ios\}Un objet [`AdaptyProfile`](https://react-native.adapty.io/interfaces/adaptyprofile). 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-react-native --- --- title: "Implémenter le mode Observateur dans le SDK React Native" description: "Implémentez le mode Observateur dans Adapty pour suivre les événements d'abonnement des utilisateurs dans le SDK React Native." --- Si vous disposez déjà de votre propre infrastructure d'achat et que vous n'êtes pas prêt à basculer entièrement vers 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'analytique. Si cela correspond à vos besoins, il vous suffit de : 1. L'activer lors de la configuration du SDK Adapty en définissant le paramètre `observerMode` sur `true`. Suivez les instructions de configuration pour [React Native](sdk-installation-reactnative). 2. [Signaler les transactions](report-transactions-observer-mode-react-native) depuis votre infrastructure d'achat existante vers Adapty. ### Configuration du mode Observateur \{#observer-mode-setup\} Activez le mode Observateur si vous gérez les achats et le statut des abonnements vous-même et que vous utilisez Adapty uniquement pour envoyer des événements d'abonnement et des données analytiques. :::important En mode Observateur, le SDK Adapty ne clôturera aucune transaction ; assurez-vous donc de les gérer vous-même. ::: ```typescript showLineNumbers title="App.tsx" adapty.activate('YOUR_PUBLIC_SDK_KEY', { observerMode: true, // Enable observer mode }); ``` Paramètres : | 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 Observateur \{#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 Observateur. Voici ce que vous devrez faire en plus des étapes ci-dessus : 1. Affichez les paywalls normalement pour les [paywalls Remote Config](present-remote-config-paywalls-react-native). 3. [Associez les paywalls](report-transactions-observer-mode-react-native) aux transactions d'achat. --- # File: report-transactions-observer-mode-react-native --- --- title: "Signaler des transactions en mode Observer dans le SDK React Native" description: "Signalez les transactions d'achat en mode Observer Adapty pour les informations utilisateur et le suivi des revenus dans le SDK React Native." ---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 chaîne (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 chaîne de la variante. Vous pouvez l'obtenir via la propriété `variationId` de l'objet [AdaptyPaywall](https://react-native.adapty.io/interfaces/adaptypaywall). |phoneNumber
firstName
lastName
| String | | gender | Enum, valeurs autorisées : `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 app. 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ées, ainsi que dans les analyses pour déterminer quelles métriques produit influencent le plus les revenus. ```typescript showLineNumbers try { await adapty.updateProfile({ codableCustomAttributes: { key_1: 'value_1', key_2: 2, }, }); } catch (error) { // handle `AdaptyError` } ``` Pour supprimer une clé existante, utilisez la méthode `.withRemoved(customAttributeForKey:)` : ```typescript showLineNumbers try { // to remove a key, pass null as its value await adapty.updateProfile({ codableCustomAttributes: { key_1: null, key_2: null, }, }); } catch (error) { // handle `AdaptyError` } ``` 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 être obsolète, car les attributs utilisateur peuvent être envoyés depuis différents appareils à tout moment — les attributs sur le serveur ont donc pu être modifiés depuis la dernière synchronisation. ::: ### Limites \{#limits\} - Jusqu'à 30 attributs personnalisés par utilisateur - Les noms de clés peuvent contenir jusqu'à 30 caractères. Ils peuvent inclure des caractères alphanumériques et l'un des symboles suivants : `_` `-` `.` - La valeur peut être une chaîne de caractères ou un nombre flottant, avec 50 caractères maximum. --- # File: react-native-listen-subscription-changes --- --- title: "Vérifier le statut d'abonnement dans le SDK React Native" description: "Suivez et gérez le statut d'abonnement des utilisateurs dans Adapty pour améliorer la rétention client dans votre application React Native." --- Avec Adapty, le suivi du statut d'abonnement est simplifié. Inutile d'insérer manuellement des identifiants de produits dans votre code. Il vous suffit de vérifier la présence d'un [niveau d'accès](access-level) actif pour confirmer l'état d'abonnement d'un utilisateur.Un objet [AdaptyProfile](https://react-native.adapty.io/interfaces/adaptyprofile). En général, il suffit de vérifier le statut du niveau d'accès du profil pour déterminer si l'utilisateur bénéficie d'un accès premium à l'application.
La méthode `.getProfile` fournit le résultat le plus récent, car elle interroge toujours l'API. Si, pour une raison quelconque (par exemple, absence de connexion internet), le SDK Adapty ne parvient pas à récupérer les informations depuis le serveur, les données du cache sont retournées. Il est également important de noter que le SDK Adapty met à jour le cache `AdaptyProfile` régulièrement afin de maintenir ces informations aussi à jour 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, vous n'aurez besoin que d'un seul niveau d'accès ; dans ce cas, vous pouvez simplement utiliser le niveau d'accès par défaut « premium ». Voici un exemple de vérification du niveau d'accès « premium » par défaut : ```typescript showLineNumbers try { const profile = await adapty.getProfile(); const isActive = profile.accessLevels?.["premium"]?.isActive; if (isActive) { // grant access to premium features } } catch (error) { // handle the error } ``` ### É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 les messages d'Adapty, vous devez effectuer quelques configurations supplémentaires : ```typescript showLineNumbers // Create an "onLatestProfileLoad" event listener adapty.addEventListener('onLatestProfileLoad', 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 est transmis. ### Cache du statut d'abonnement \{#subscription-status-cache\} Le cache intégré au SDK Adapty stocke le statut d'abonnement du profil. Cela signifie que même si le serveur est indisponible, les données mises en cache restent accessibles pour fournir des informations sur le statut d'abonnement du profil. Il est toutefois important de noter qu'il n'est pas possible d'interroger directement le cache. Le SDK interroge périodiquement le serveur toutes les minutes pour vérifier s'il y a des mises à jour ou des changements liés au profil. S'il y a des modifications, comme de nouvelles transactions ou d'autres mises à jour, elles sont envoyées dans les données mises en cache afin de les maintenir synchronisées avec le serveur. --- # File: react-native-deal-with-att --- --- title: "Gérer l'ATT dans le SDK React Native" description: "Démarrez avec Adapty sur React Native 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. ```typescript showLineNumbers try { await adapty.updateProfile({ // you can also pass a string value (validated via tsc) if you prefer appTrackingTransparencyStatus: AppTrackingTransparencyStatus.Authorized, }); } catch (error) { // handle `AdaptyError` } ``` :::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 transmettre les données en temps voulu aux intégrations que vous avez configurées. ::: --- # File: kids-mode-react-native --- --- title: "Mode Enfants dans le SDK React Native" description: "Activez facilement le Mode Enfants pour respecter les politiques d'Apple et Google. Aucune collecte d'IDFA, GAID ou données publicitaires dans le SDK React Native." --- Si votre application React Native 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 répondre à ces politiques et passer les revues des stores. :::important Sur iOS, le Mode Enfants est activé via le trait du package Swift `KidsMode`, qui exclut à la compilation tout le code lié à l'IDFA, AdSupport et AppTrackingTransparency. Il nécessite le SDK v4 (qui installe le SDK iOS natif via Swift Package Manager) et **Xcode 26** ou une version ultérieure. Voir [Modifications dans votre Podfile iOS](#updates-in-your-ios-podfile) ci-dessous. ::: ## Ce qui est requis \{#whats-required\} Vous devez configurer le SDK Adapty pour désactiver la collecte de : - [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) De plus, nous recommandons d'utiliser l'identifiant utilisateur avec précaution. Un identifiant au format `optionnel
par 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` signifie 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** | 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.
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 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 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 désinstallation de l'application ou via 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 et un serveur de secours indépendant en cas d'indisponibilité du CDN. Ce système est conçu pour vous garantir toujours la dernière version de vos onboardings tout en assurant la fiabilité même lorsque la connexion internet est limitée.
| | **loadTimeoutMs** | par défaut : 5 sec |Cette valeur limite le délai d'attente pour cette méthode. Si le délai est dépassé, les données en cache ou le fallback local seront 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 comprendre plusieurs requêtes en arrière-plan.
| Paramètres de réponse : | Paramètre | Description | |:----------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------| | Onboarding | Un objet [`AdaptyOnboarding`](https://react-native.adapty.io/interfaces/adaptyonboarding) contenant : l'identifiant et la configuration de l'onboarding, le Remote Config, et plusieurs autres propriétés. | ## Accélérer la récupération de l'onboarding 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, lorsque vous avez de nombreuses audiences et onboardings et que vos utilisateurs ont une connexion internet faible, la récupération d'un onboarding peut prendre plus de temps que souhaité. Dans ce cas, vous pourriez vouloir afficher un onboarding par défaut pour garantir une expérience utilisateur fluide plutôt que de n'afficher aucun onboarding. Pour répondre à ce besoin, 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 un onboarding](#fetch-onboarding) 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 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 puissent s'afficher incorrectement. - **Aucune personnalisation** : affiche uniquement le contenu pour l'audience "All Users", sans ciblage basé sur le pays, l'attribution ou les attributs personnalisés. Si une récupération plus rapide l'emporte sur ces inconvénients pour votre cas d'usage, utilisez `getOnboardingForDefaultAudience` comme indiqué ci-dessous. Sinon, utilisez `getOnboarding` comme décrit [ci-dessus](#fetch-onboarding). ::: ```typescript showLineNumbers try { const placementId = 'YOUR_PLACEMENT_ID'; const locale = 'en'; const onboarding = await adapty.getOnboardingForDefaultAudience(placementId, locale); // the requested onboarding } catch (error) { // handle the error } ``` 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 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` signifie 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** | 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.
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 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 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 désinstallation de l'application ou via 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 et un serveur de secours indépendant en cas d'indisponibilité du CDN. Ce système est conçu pour vous garantir toujours la dernière version de vos onboardings tout en assurant la fiabilité même lorsque la connexion internet est limitée.
| --- # File: react-native-present-onboardings --- --- title: "Présenter les onboardings dans React Native SDK" description: "Découvrez comment présenter des onboardings dans React Native pour booster les conversions et les revenus." --- :::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 plutôt les [flows](react-native-get-pb-paywalls) : 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 au runtime WebView. Consultez [Récupérer les flows & paywalls](react-native-get-pb-paywalls) et [Afficher les flows & paywalls](react-native-present-paywalls) pour démarrer. ::: Si vous avez personnalisé un onboarding via 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 onboarding contient à la fois ce qui doit être affiché et la façon dont cela doit l'être. Avant de commencer, assurez-vous que : 1. Vous avez installé [Adapty React Native SDK](sdk-installation-reactnative) 3.8.0 ou ultérieur. 2. Vous avez [créé un onboarding](create-onboarding). 3. Vous avez ajouté l'onboarding à un [placement](placements). Adapty React Native SDK propose deux façons de présenter les onboardings : - **Composant React** : un composant embarqué qui vous permet de l'intégrer à l'architecture et au système de navigation de votre application. - **Présentation modale** ## Composant React \{#react-component\} Pour intégrer un onboarding dans votre arbre de composants existant, utilisez le composant `AdaptyOnboardingView` directement dans la hiérarchie de vos composants React Native. Ce composant embarqué vous permet de l'intégrer à l'architecture et au système de navigation de votre application. :::note Sur Android, nous recommandons une configuration supplémentaire pour `AdaptyOnboardingView` afin d'éviter un artefact de rendu visuel. Consultez [L'interface système chevauche le contenu de l'onboarding sur Android](#system-ui-overlaps-onboarding-content-on-android). :::
Vous pouvez ensuite 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**, le gestionnaire d'événements sera déclenché avec le paramètre `actionId` correspondant à l'**Action ID** défini dans le builder. Vous pouvez créer vos propres IDs, comme "allowNotifications".
:::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.
:::
Ce code d'erreur indique que l'utilisateur a annulé une demande de paiement.
Aucune action n'est requise, mais en termes de logique métier, vous pouvez proposer une réduction à votre utilisateur ou lui rappeler plus tard.
| | [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.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 transmettre 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 réduction 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 réduction 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 procéder [pour React Native](sdk-installation-reactnative). | | 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 plus de détails. | | currentSubscriptionToUpdateNotFoundInHistory | 24 | L'abonnement d'origine à renouveler est introuvable. | | pendingPurchase | 25 | Cette erreur indique que l'état de l'achat est en attente plutôt qu'acheté. 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 maximal avant que Google Play puisse répondre. Cela peut être causé, par exemple, par un retard 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 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. Voici des exemples de situations pouvant provoquer cette erreur :
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 d'entreprise, et son administrateur a désactivé les achats pour les utilisateurs.
4. Google Play n'est pas en mesure de 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 incorrectement une API. | | 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é sin | ## 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-react-native).
| | productRequestFailed | 1002 |Impossible de récupérer les produits disponibles pour le moment. Cause 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-react-native) de dépannage. | | noPurchasesToRestore | 1004 | Cette erreur indique que Google Play n'a pas trouvé l'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 en termes de logique métier, vous pouvez proposer une réduction à votre utilisateur ou lui rappeler plus tard.
| | 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 est 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 le problème persiste, 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é.
2. Cliquez sur le nom du groupe d'abonnements. Vos produits apparaissent 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 de l'onglet [**Products**](https://app.adapty.io/products) dans 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 sont bien listés.
## Étape 4. Vérifier les prix du produit \{#step-5-check-product-prices\}
1. Retournez 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éveloppez 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 applications 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 tous 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 être validées — statut `Approved`, Bundle ID correspondant, clé API valide — et pourtant le SDK retourne toujours `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 de produit. Attendez jusqu'à 24 heures après la recréation pour que la propagation s'effectue.
---
# File: cantMakePayments-react-native
---
---
title: "Correction de l'erreur Code-1003 cantMakePayment dans le SDK React Native"
description: "Résoudre 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: react-native-sdk-migration-guides
---
---
title: "Guides de migration du SDK React Native"
description: "Guides de migration pour les versions du SDK Adapty React Native."
---
Cette page regroupe tous les guides de migration pour le SDK Adapty React Native. Choisissez la version vers laquelle vous souhaitez migrer pour obtenir les instructions détaillées :
- **[Migrer vers v4.0](migration-to-react-native-sdk-v4)**
- **[Migrer vers v3.14](migration-react-native-314)**
- **[Migrer vers v3.8](react-native-migration-guide-380)**
- **[Migrer vers v3.4](migration-to-react-native-sdk-34)**
- **[Migrer vers v3.3](migration-to-react-native330)**
- **[Migrer vers v3.0](migration-to-react-native-sdk-v3)**
---
# File: migration-to-react-native-sdk-v4
---
---
title: "Migrer le SDK React Native Adapty vers v4.0"
description: "Migrez vers le SDK React Native Adapty v4.0 en remplaçant les API paywall par des API flow, compatibles avec le Flow Builder et le Paywall Builder."
---
Le SDK React Native Adapty 4.0 introduit les flows et renomme les API paywall en conséquence. Les nouvelles API fonctionnent aussi bien avec le nouveau Flow Builder qu'avec le Paywall Builder existant — aucune modification de configuration n'est nécessaire côté Adapty Dashboard.
## Référence rapide \{#quick-reference\}
| v3 | v4 |
|---|---|
| `adapty.getPaywall(placementId, locale?, params?)` | `adapty.getFlow(placementId, params?)` |
| `adapty.getPaywallForDefaultAudience(placementId, locale?, params?)` | `adapty.getFlowForDefaultAudience(placementId, params?)` |
| `adapty.getPaywallProducts(paywall)` | `adapty.getPaywallProducts(flow)` |
| `adapty.logShowPaywall(paywall)` | `adapty.logShowFlow(flow)` |
| `AdaptyPaywall` (type) | `AdaptyFlow` |
| `createPaywallView(paywall)` | `createFlowView(flow)` |
| `AdaptyPaywallView` (composant) | `AdaptyFlowView` |
| `EventHandlers` (type) | `FlowEventHandlers` |
| `onPaywallShown` | `onAppeared` |
| `onPaywallClosed` | `onDisappeared` |
| `onRenderingFailed` | `onError` |
`AdaptyPaywallProduct` garde son nom — les produits appartiennent toujours à un flow, et `getPaywallProducts` prend désormais un `AdaptyFlow`. Les méthodes `getFlow` et `getFlowForDefaultAudience` n'acceptent plus de paramètre `locale` — passez-le à `createFlowView` à la place. Les méthodes de vue `present`, `dismiss`, `setEventHandlers` et `showDialog`, ainsi que les gestionnaires d'événements `onCloseButtonPress`, `onUrlPress`, `onCustomAction`, `onProductSelected`, `onPurchaseStarted`, `onPurchaseCompleted`, `onPurchaseFailed`, `onRestoreStarted`, `onRestoreCompleted`, `onRestoreFailed`, `onLoadingProductsFailed`, `onWebPaymentNavigationFinished` et `onAndroidSystemBack` conservent les mêmes noms qu'en v3. Certains comportements par défaut ont changé — voir [Changements de comportement par défaut](#default-behavior-changes).
## Version iOS minimale \{#minimum-ios-version\}
Le SDK React Native Adapty 4.0 fait passer la version minimale de déploiement iOS de iOS 13.0 à **iOS 15.0**. Définissez votre cible de déploiement iOS à 15.0 ou supérieure avant de procéder à la mise à jour.
## Installation \{#installation\}
### Mettre à jour le package
Mettez à jour le package `react-native-adapty` vers la v4.0 :
```bash showLineNumbers
npm install react-native-adapty@4.0.2
# or
yarn add react-native-adapty@4.0.2
```
### iOS : les SDK natifs passent désormais par Swift Package Manager
[Le dépôt de specs CocoaPods passe en lecture seule en décembre 2026](https://blog.cocoapods.org/CocoaPods-Specs-Repo/), aussi à partir de la v4, les SDK natifs `Adapty`, `AdaptyUI` et `AdaptyPlugin` **ne sont plus inclus en tant que sous-dépendances CocoaPods** — le podspec les récupère via **Swift Package Manager** (grâce au helper `spm_dependency`). Deux points à respecter :
- **React Native 0.75 ou version ultérieure** — nécessaire pour le helper de podspec `spm_dependency`. Sur une version plus ancienne, `pod install` échoue avec une erreur explicite ; mettez d'abord à jour React Native, ou restez sur `react-native-adapty` 3.x.
- **Frameworks dynamiques** — les dépendances SPM nécessitent un linkage dynamique. La façon de l'activer diffère entre Expo et bare React Native.
#### Expo
Ajoutez le plugin de configuration [`expo-build-properties`](https://docs.expo.dev/versions/latest/sdk/build-properties/) et définissez les frameworks iOS en dynamique dans `app.json` (ou `app.config.js`) :
```json showLineNumbers title="app.json"
{
"expo": {
"plugins": [
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "dynamic",
"buildReactNativeFromSource": true
}
}
]
]
}
}
```
`buildReactNativeFromSource` est requis sur **Expo SDK 57 et versions ultérieures**. Expo SDK 57 embarque un framework React Native précompilé dont les en-têtes sont inaccessibles aux autres packages lorsque les frameworks sont dynamiques, ce qui provoque des erreurs de build iOS comme `'React/RCTBridge.h' file not found` dans `expo-updates` ou `@expo/ui`. Compiler React Native depuis les sources permet d'éviter ce conflit, au prix de builds iOS plus longs. Sur Expo SDK 56 et versions antérieures, vous pouvez omettre cette option.
Installez ensuite le plugin et régénérez le projet natif :
```bash showLineNumbers
npx expo install expo-build-properties
npx expo prebuild --clean
```
#### Bare React Native
Ajoutez les frameworks dynamiques à votre cible iOS, puis réinstallez les pods :
```ruby showLineNumbers title="ios/Podfile"
use_frameworks! :linkage => :dynamic
```
```bash showLineNumbers
cd ios && pod install --repo-update
```
Si vous avez précédemment ajouté `Adapty`, `AdaptyUI` ou `AdaptyPlugin` en tant que sous-dépendances CocoaPods, supprimez d'abord toute ligne explicite `pod 'Adapty'`, `pod 'AdaptyUI'` ou `pod 'AdaptyPlugin'` de votre `Podfile`.
:::warning
Passer de la liaison statique par défaut aux frameworks dynamiques peut entrer en conflit avec des bibliothèques qui ne prennent pas encore en charge les en-têtes modulaires, et est incompatible avec Flipper. Si vous rencontrez des problèmes de compilation, consultez cet [article sur l'intégration de Swift Package Manager avec les bibliothèques React Native](https://www.callstack.com/blog/integrating-swift-package-manager-with-react-native-libraries).
:::
Consultez [Installer le SDK Adapty](sdk-installation-reactnative) pour la configuration complète.
## Récupérer des flows \{#fetching-flows\}
### getPaywall → getFlow
Le type retourné passe de `AdaptyPaywall` à `AdaptyFlow`, et le paramètre `locale` se déplace de l'appel de récupération vers `createFlowView` ; pour les paywalls personnalisés, toutes les locales sont retournées dans `flow.remoteConfigs` :
```diff showLineNumbers
- const paywall = await adapty.getPaywall('YOUR_PLACEMENT_ID', 'en');
+ const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');
+ const view = await createFlowView(flow, { locale: 'en' });
```
`locale` reste optionnel dans `createFlowView` : si vous l'omettez, la vue s'affiche en `en`, ou dans la localisation par défaut du flow si celui-ci ne possède pas de version `en`. Cette fonctionnalité nécessite le SDK 4.0.2 ou une version ultérieure — voir [Localisations et codes de langue](react-native-localizations-and-locale-codes).
`getPaywallForDefaultAudience` est renommé de la même façon :
```diff showLineNumbers
- const paywall = await adapty.getPaywallForDefaultAudience('YOUR_PLACEMENT_ID', 'en');
+ const flow = await adapty.getFlowForDefaultAudience('YOUR_PLACEMENT_ID');
```
### getPaywallProducts(paywall) → getPaywallProducts(flow)
`getPaywallProducts` conserve son nom mais prend désormais un `AdaptyFlow` :
```diff showLineNumbers
- const products = await adapty.getPaywallProducts(paywall);
+ const products = await adapty.getPaywallProducts(flow);
```
### Fichiers de secours \{#fallback-files\}
Le format des fichiers de secours [a changé avec le SDK v4](fallback-flows). Téléchargez le nouveau fichier depuis **[Placements](https://app.adapty.io/placements)** > **Fallbacks** et intégrez-le à votre application.
## Modèle de données \{#data-model\}
`getFlow` renvoie un `AdaptyFlow` au lieu d'un `AdaptyPaywall`, et la structure de l'objet a changé :
| Champ v3 `AdaptyPaywall` | Champ v4 `AdaptyFlow` | Action |
|---|---|---|
| `remoteConfig?` (unique) | `remoteConfigs?: AdaptyRemoteConfig[]` (tableau) | Un flow contient un Remote Config par langue configurée. Lisez celui qui correspond à l'utilisateur : `flow.remoteConfigs?.find((c) => c.lang === 'en')`. |
| `products` | `flow.paywalls[i].productIdentifiers` | Les identifiants de produits se trouvent désormais sur chaque variante du flow, pas sur le flow lui-même. |
| `webPurchaseUrl?` | `flow.paywalls[i].webPurchaseUrl` | Déplacé du flow vers chaque variante de paywall. |
| `version?: number` | `flowVersionId?: string` | Renommé, et le type a changé de `number` à `string`. |
| `hasViewConfiguration` | supprimé | Supprimez tout contrôle `hasViewConfiguration` de votre code. |
| `requestLocale` | supprimé | La locale ne fait plus partie du modèle. |
| _(nouveau)_ | `paywalls: AdaptyFlowPaywall[]` | Chaque entrée correspond à une variante de paywall dans le flow. |
| _(nouveau)_ | `responseCreatedAt: number` | Horodatage de la réponse serveur, en millisecondes. |
Product identifiers moved from the flow to each variation:
```diff showLineNumbers
- const ids = paywall.products;
+ const ids = flow.paywalls[0].productIdentifiers;
```
## Méthodes de paywall web \{#web-paywall-methods\}
`openWebPaywall` et `createWebPaywallUrl` conservent leurs noms, mais le premier argument est désormais un `AdaptyFlowPaywall` (une variante de flow) au lieu d'un `AdaptyPaywall`. Vous pouvez toujours passer un `AdaptyPaywallProduct`.
```diff showLineNumbers
const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');
- await adapty.openWebPaywall(paywall);
+ await adapty.openWebPaywall(flow.paywalls[0]);
```
## 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 modification du tableau de bord.
```diff showLineNumbers
- await adapty.logShowPaywall(paywall);
+ await adapty.logShowFlow(flow);
```
Comme dans la v3, vous n'avez pas besoin d'appeler cette méthode lors de l'affichage de flows ou de 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 fonction factory et passez l'`AdaptyFlow`. Les méthodes du contrôleur retourné (`present`, `dismiss`, `setEventHandlers`, `showDialog`) restent inchangées :
```diff showLineNumbers
- import { createPaywallView } from 'react-native-adapty';
+ import { createFlowView } from 'react-native-adapty';
- const view = await createPaywallView(paywall);
+ const view = await createFlowView(flow);
await view.present();
```
### AdaptyPaywallView → AdaptyFlowView
Si vous effectuez le rendu avec le composant React, renommez-le et passez la prop `flow` :
```diff showLineNumbers
- import { AdaptyPaywallView } from 'react-native-adapty';
+ import { AdaptyFlowView } from 'react-native-adapty';
- ```diff showLineNumbers - subscriptionDetails?: AdaptySubscriptionDetails; + subscription?: AdaptySubscriptionDetails; ``` 2. [AdaptySubscriptionDetails](https://react-native.adapty.io/interfaces/adaptysubscriptiondetails) : - `promotionalOffer` est supprimé. L'offre promotionnelle est désormais transmise via la propriété `offer` uniquement si elle est disponible. Dans ce cas, `offer?.identifier?.type` sera `'promotional'`. - `introductoryOfferEligibility` est supprimé (les offres ne sont retournées que si l'utilisateur est éligible). - `offerId` est supprimé. L'identifiant de l'offre est désormais stocké dans `AdaptySubscriptionOffer.identifier`. - `offerTags` est déplacé vers `AdaptySubscriptionOffer.android`.
```diff showLineNumbers - introductoryOffers?: AdaptyDiscountPhase[]; + offer?: AdaptySubscriptionOffer; ios?: { - promotionalOffer?: AdaptyDiscountPhase; subscriptionGroupIdentifier?: string; }; android?: { - offerId?: string; basePlanId: string; - introductoryOfferEligibility: OfferEligibility; - offerTags?: string[]; renewalType?: 'prepaid' | 'autorenewable'; }; } ``` 3. [AdaptyDiscountPhase](https://react-native.adapty.io/interfaces/adaptydiscountphase) : - Le champ `identifier` est supprimé du modèle `AdaptyDiscountPhase`. L'identifiant de l'offre est désormais stocké dans `AdaptySubscriptionOffer.identifier`.
```diff showLineNumbers - ios?: { - readonly identifier?: string; - }; ``` ### Modèles supprimés \{#remove-models\} 1. `AttributionSource` : - Une chaîne de caractères est désormais utilisée aux endroits où `AttributionSource` était précédemment utilisé. 2. `OfferEligibility` : - Ce modèle a été supprimé car il n'est plus nécessaire. Désormais, une offre n'est retournée que si l'utilisateur est éligible. ## Supprimer la méthode `getProductsIntroductoryOfferEligibility` \{#remove-getproductsintroductoryoffereligibility-method\} Avant le SDK Adapty 3.3.1, les objets produit incluaient toujours les offres, même si l'utilisateur n'était pas éligible. Vous deviez donc vérifier manuellement l'éligibilité avant d'utiliser l'offre. À partir de la version 3.3.1, l'objet produit n'inclut les offres que si l'utilisateur est éligible. Cela simplifie le processus, car vous pouvez supposer que l'utilisateur est éligible si une offre est présente. ## Mettre à jour la création d'achat \{#update-making-purchase\} Dans les versions précédentes, les achats annulés et en attente étaient traités comme des erreurs et retournaient les codes `2: 'paymentCancelled'` et `25: 'pendingPurchase'` respectivement. À partir de la version 3.3.1, les achats annulés et en attente sont désormais considérés comme des résultats réussis et doivent être gérés en conséquence : ```typescript showLineNumbers try { const purchaseResult = await adapty.makePurchase(product); switch (purchaseResult.type) { case 'success': const isSubscribed = purchaseResult.profile?.accessLevels['YOUR_ACCESS_LEVEL']?.isActive; if (isSubscribed) { // Grant access to the paid features } break; case 'user_cancelled': // Handle the case where the user canceled the purchase break; case 'pending': // Handle deferred purchases (e.g., the user will pay offline with cash) break; } } catch (error) { // Handle the error } ``` ## Mettre à jour la présentation des paywalls du Paywall Builder \{#update-paywall-builder-paywall-presentation\} Pour des exemples mis à jour, consultez la documentation [Présenter les nouveaux paywalls du Paywall Builder dans React Native](react-native-present-paywalls). ```diff showLineNumbers - import { createPaywallView } from '@adapty/react-native-ui'; + import { createPaywallView } from 'react-native-adapty/dist/ui'; const view = await createPaywallView(paywall); view.registerEventHandlers(); // handle close press, etc try { await view.present(); } catch (error) { // handle the error } ``` ## Mettre à jour l'implémentation des timers définis par le développeur \{#update-developer-defined-timer-implementation\} Renommez le paramètre `timerInfo` en `customTimers` : ```diff showLineNumbers - let timerInfo = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) } + let customTimers = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) } //and then you can pass it to createPaywallView as follows: - view = await createPaywallView(paywall, { timerInfo }) + view = await createPaywallView(paywall, { customTimers }) ``` ## Modifier les événements d'achat du Paywall Builder \{#modify-paywall-builder-purchase-events\} Précédemment : - Les achats annulés déclenchaient le callback `onPurchaseCancelled`. - Les achats en attente retournaient le code d'erreur `25: 'pendingPurchase'`. Maintenant : - Les deux sont gérés par le callback `onPurchaseCompleted`. #### Étapes de migration : \{#steps-to-migrate\} 1. Supprimez le callback `onPurchaseCancelled`. 2. Supprimez la gestion du code d'erreur `25: 'pendingPurchase'`. 3. Mettez à jour le callback `onPurchaseCompleted` : ```typescript showLineNumbers const view = await createPaywallView(paywall); const unsubscribe = view.registerEventHandlers({ // ... other optional callbacks onPurchaseCompleted(purchaseResult, product) { switch (purchaseResult.type) { case 'success': const isSubscribed = purchaseResult.profile?.accessLevels['YOUR_ACCESS_LEVEL']?.isActive; if (isSubscribed) { // Grant access to the paid features } break; // highlight-start case 'user_cancelled': // Handle the case where the user canceled the purchase break; case 'pending': // Handle deferred purchases (e.g., the user will pay offline with cash) break; // highlight-end } // highlight-start return purchaseResult.type !== 'user_cancelled'; // highlight-end }, }); ``` ## Modifier les événements d'action personnalisée du Paywall Builder \{#modify-paywall-builder-custom-action-events\} Callbacks supprimés : - `onAction` - `onCustomEvent` Callback ajouté : - Nouveau callback `onCustomAction(actionId)`. Utilisez-le pour les actions personnalisées. ## Modifier le callback `onProductSelected` \{#modify-onproductselected-callback\} Précédemment, `onProductSelected` nécessitait l'objet `product`. Il requiert maintenant `productId` sous forme de chaîne de caractères. ## Supprimer les paramètres d'intégration tiers de la méthode `updateProfile` \{#remove-third-party-integration-parameters-from-updateprofile-method\} Les identifiants d'intégration tiers sont désormais définis via la méthode `setIntegrationIdentifier`. La méthode `updateProfile` ne les accepte plus. ## Mettre à jour la configuration des SDK d'intégration tiers \{#update-third-party-integration-sdk-configuration\} Pour garantir le bon fonctionnement des intégrations avec le SDK Adapty React Native 3.3.1 et versions ultérieures, mettez à jour vos configurations SDK pour les intégrations suivantes comme décrit dans les sections ci-dessous. De plus, si vous utilisiez `AttributionSource` pour obtenir l'identifiant d'attribution, modifiez votre code pour fournir l'identifiant requis sous forme de chaîne de caractères. ### Adjust \{#adjust\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration Adjust](adjust#connect-your-app-to-adjust). ```diff showLineNumbers import { Adjust, AdjustConfig } from "react-native-adjust"; import { adapty } from "react-native-adapty"; var adjustConfig = new AdjustConfig(appToken, environment); // Before submiting Adjust config... adjustConfig.setAttributionCallbackListener(attribution => { // Make sure Adapty SDK is activated at this point // You may want to lock this thread awaiting of `activate` adapty.updateAttribution(attribution, "adjust"); }); // ... Adjust.create(adjustConfig); + Adjust.getAdid((adid) => { + if (adid) + adapty.setIntegrationIdentifier("adjust_device_id", adid); + }); ``` ### AirBridge \{#airbridge\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration AirBridge](airbridge#connect-your-app-to-airbridge). ```diff showLineNumbers import Airbridge from 'airbridge-react-native-sdk'; import { adapty } from 'react-native-adapty'; try { const deviceId = await Airbridge.state.deviceUUID(); - await adapty.updateProfile({ - airbridgeDeviceId: deviceId, - }); + await adapty.setIntegrationIdentifier("airbridge_device_id", deviceId); } catch (error) { // handle `AdaptyError` } ``` ### Amplitude \{#amplitude\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration Amplitude](amplitude#sdk-configuration). ```diff showLineNumbers import { adapty } from 'react-native-adapty'; try { - await adapty.updateProfile({ - amplitudeDeviceId: deviceId, - amplitudeUserId: userId, - }); + await adapty.setIntegrationIdentifier("amplitude_device_id", deviceId); + await adapty.setIntegrationIdentifier("amplitude_user_id", userId); } catch (error) { // handle `AdaptyError` } ``` ### AppMetrica \{#appmetrica\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration AppMetrica](appmetrica#sdk-configuration). ```diff showLineNumbers import { adapty } from 'react-native-adapty'; import AppMetrica, { DEVICE_ID_KEY, StartupParams, StartupParamsReason } from '@appmetrica/react-native-analytics'; // ... const startupParamsCallback = async ( params?: StartupParams, reason?: StartupParamsReason ) => { const deviceId = params?.deviceId if (deviceId) { try { - await adapty.updateProfile({ - appmetricaProfileId: 'YOUR_ADAPTY_CUSTOMER_USER_ID', - appmetricaDeviceId: deviceId, - }); + await adapty.setIntegrationIdentifier("appmetrica_profile_id", 'YOUR_ADAPTY_CUSTOMER_USER_ID'); + await adapty.setIntegrationIdentifier("appmetrica_device_id", deviceId); } catch (error) { // handle `AdaptyError` } } } AppMetrica.requestStartupParams(startupParamsCallback, [DEVICE_ID_KEY]) ``` ### AppsFlyer \{#appsflyer\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration AppsFlyer](appsflyer#connect-your-app-to-appsflyer). ```diff showLineNumbers import { adapty, AttributionSource } from 'react-native-adapty'; import appsFlyer from 'react-native-appsflyer'; appsFlyer.onInstallConversionData(installData => { try { - const networkUserId = appsFlyer.getAppsFlyerUID(); - adapty.updateAttribution(installData, AttributionSource.AppsFlyer, networkUserId); + const uid = appsFlyer.getAppsFlyerUID(); + adapty.setIntegrationIdentifier("appsflyer_id", uid); + adapty.updateAttribution(installData, "appsflyer"); } catch (error) { // handle the error } }); // ... appsFlyer.initSdk(/*...*/); ``` ### Branch \{#branch\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration Branch](branch#connect-your-app-to-branch). ```diff showLineNumbers import { adapty, AttributionSource } from 'react-native-adapty'; import branch from 'react-native-branch'; branch.subscribe({ enComplete: ({ params, }) => { - adapty.updateAttribution(params, AttributionSource.Branch); + adapty.updateAttribution(params, "branch"); }, }); ``` ### Facebook Ads \{#facebook-ads\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration Facebook Ads](facebook-ads#connect-your-app-to-facebook-ads). ```diff showLineNumbers import { adapty } from 'react-native-adapty'; import { AppEventsLogger } from 'react-native-fbsdk-next'; try { const anonymousId = await AppEventsLogger.getAnonymousID(); - await adapty.updateProfile({ - facebookAnonymousId: anonymousId, - }); + await adapty.setIntegrationIdentifier("facebook_anonymous_id", anonymousId); } catch (error) { // handle `AdaptyError` } ``` ### Firebase et Google Analytics \{#firebase-and-google-analytics\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration Firebase et Google Analytics](firebase-and-google-analytics). ```diff showLineNumbers import analytics from '@react-native-firebase/analytics'; import { adapty } from 'react-native-adapty'; try { const appInstanceId = await analytics().getAppInstanceId(); - await adapty.updateProfile({ - firebaseAppInstanceId: appInstanceId, - }); + await adapty.setIntegrationIdentifier("firebase_app_instance_id", appInstanceId); } catch (error) { // handle `AdaptyError` } ``` ### Mixpanel \{#mixpanel\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration Mixpanel](mixpanel#sdk-configuration). ```diff showLineNumbers import { adapty } from 'react-native-adapty'; import { Mixpanel } from 'mixpanel-react-native'; // ... try { - await adapty.updateProfile({ - mixpanelUserId: mixpanelUserId, - }); + await adapty.setIntegrationIdentifier("mixpanel_user_id", mixpanelUserId); } catch (error) { // handle `AdaptyError` } ``` ### OneSignal \{#onesignal\} Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour l'exemple de code complet, consultez la [configuration SDK pour l'intégration OneSignal](onesignal#sdk-configuration).