Migrer le SDK Adapty Capacitor vers v4.1.1
Adapty Capacitor SDK 4.1.1 est la version stable actuelle de la ligne 4.x — la 4.0 n’a été publiée qu’en bêta, donc si vous êtes sur la 3.x, migrez directement vers la 4.1.1. Ce guide couvre l’intégralité de la migration : les flows introduits en 4.0 et les changements apportés par la 4.1.1.
La ligne 4.x introduit les flows et renomme les API de paywall en conséquence. Les nouvelles API fonctionnent avec les flows, et elles restent compatibles avec les paywalls de l’ancien builder — aucun changement de configuration n’est requis côté Adapty Dashboard. Par ailleurs, la version 4.1.1 rend l’attribution Adapty opt-in, renomme la méthode d’attribution externe, modifie le format du fichier de secours et ajoute la prise en charge des achats intégrés mis en avant sur l’App Store.
Vous venez de la bêta 4.0 ? Remplacez la version bêta épinglée par la dernière version, puis seules quatre sections s’appliquent : L’attribution Adapty est désactivée par défaut, les API d’attribution externe renommées, les fichiers de secours, et les achats intégrés promus sur l’App Store.
Référence rapide
| v3 | v4.1.1 |
|---|---|
| Attribution Adapty activée automatiquement | désactivée par défaut — à activer avec adaptyAttributionEnabled: true |
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 + AdaptyFlowPaywall |
createPaywallView(paywall, params?) | createFlowView(flow, params?) |
PaywallViewController | FlowViewController |
EventHandlers (type) | FlowEventHandlers |
CreatePaywallViewParamsInput | CreateFlowViewParamsInput |
onRenderingFailed | onError |
adapty.updateAttribution({ attribution, source }) | adapty.updateExternalAttribution({ attribution, provider }) |
AdaptyProfile.appliedAttributionSources | AdaptyProfile.appliedExternalAttributionProviders |
AttributionSource | AdaptyExternalAttributionProvider |
| Fichier de secours téléchargé pour 3.x | nouveau format de fichier de secours — retéléchargez le fichier |
| Achats intégrés promus complétés automatiquement, sans possibilité de les intercepter | l’événement 'onPromotedPurchaseReceived' et adapty.makePromotedPurchase({ product }) transfèrent la complétion à votre application |
AdaptyPaywallProduct conserve son nom — les produits appartiennent toujours à un flow, et getPaywallProducts conserve également son nom, en prenant désormais un AdaptyFlow. Les méthodes getFlow et getFlowForDefaultAudience ne prennent plus de paramètre locale — passez-le plutôt à createFlowView. Les API d’achat et de profil (makePurchase, restorePurchases, getProfile, identify, updateProfile) et setFallback conservent les mêmes signatures, mais le fichier de secours lui-même doit être re-téléchargé — voir Fichiers de secours. Les méthodes de vue present, dismiss, setEventHandlers, clearEventHandlers, 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. Les méthodes d’onboarding fonctionnent toujours mais sont dépréciées — voir Dépréciation de l’API onboarding. Certains comportements par défaut ont changé — voir Changements de comportement par défaut.
Versions minimales
Les prérequis d’exécution restent inchangés depuis v3.16+ : iOS 15.0, Android minSdk 24 et Capacitor 8. Aucune modification de cible de déploiement n’est nécessaire.
Il y a une nouvelle exigence de build : Xcode 26 ou version ultérieure — le SDK iOS Adapty natif fourni avec cette version utilise Swift tools 6.2.
Installation
Mettre à jour le package
npm install @adapty/capacitor@latest
Puis synchronisez les projets natifs :
npx cap sync
iOS : Swift Package Manager uniquement
Le dépôt de specs CocoaPods passe en lecture seule en décembre 2026, donc à partir de la v4, le fichier AdaptyCapacitor.podspec est supprimé et le SDK s’installe sur iOS uniquement via Swift Package Manager (SPM). Le projet iOS de votre application doit utiliser l’intégration SPM de Capacitor :
- Nouvelles applications : ajoutez la plateforme iOS avec le gestionnaire de paquets SPM :
npx cap add ios --packagemanager SPM
- Applications existantes basées sur CocoaPods : migrez le projet iOS en suivant le guide Capacitor pour utiliser SPM dans un projet existant.
Consultez Installer le SDK Adapty pour la configuration complète.
⚠️ L’attribution Adapty est désactivée par défaut
Si vous utilisez l’attribution Adapty et mettez à jour vers le SDK 4.1.1 sans l’activer explicitement, elle cesse de fonctionner silencieusement — les installations ne sont plus enregistrées, sans aucun avertissement.
Dans les versions précédentes, le SDK enregistrait automatiquement les installations pour Adapty Attribution. À partir de la version 4.1.1 du SDK, cette fonctionnalité est désactivée par défaut : le SDK n’enregistre plus les installations, les événements 'onInstallationDetailsSuccess' et 'onInstallationDetailsFail' ne se déclenchent jamais, et getCurrentInstallationStatus renvoie le statut not_available.
Si vous utilisez Adapty Attribution, activez-le lors de l’initialisation du SDK :
await adapty.activate({
apiKey: 'YOUR_PUBLIC_SDK_KEY',
params: {
+ adaptyAttributionEnabled: true,
},
});
Si vous n’utilisez pas l’Attribution Adapty, aucune modification n’est nécessaire.
Récupération des flows
getPaywall → getFlow
Le type retourné passe de AdaptyPaywall à AdaptyFlow, et l’option locale quitte l’appel de récupération pour rejoindre createFlowView ; pour les paywalls personnalisés, toutes les locales sont retournées dans flow.remoteConfigs :
- const paywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en' });
+ const flow = await adapty.getFlow({ placementId: 'YOUR_PLACEMENT_ID' });
+ const view = await createFlowView(flow, { locale: 'en' });
locale reste optionnel sur createFlowView : omettez-le et la vue s’affiche en en, ou dans la localisation par défaut du flow si celui-ci n’a pas de version en. En raison de ce repli, la vue peut s’afficher dans une localisation différente de celle demandée — la nouvelle propriété FlowViewController.locale indique laquelle a été utilisée. Voir Localisations et codes de langue.
getPaywallForDefaultAudience est renommé de la même façon :
- const paywall = await adapty.getPaywallForDefaultAudience({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en' });
+ const flow = await adapty.getFlowForDefaultAudience({ placementId: 'YOUR_PLACEMENT_ID' });
getPaywallProducts(paywall) → getPaywallProducts(flow)
getPaywallProducts conserve son nom mais accepte désormais un AdaptyFlow :
- const products = await adapty.getPaywallProducts({ paywall });
+ const products = await adapty.getPaywallProducts({ flow });
Fichiers de secours
Le format du fichier de secours a changé dans la version 4.0, puis à nouveau dans la version 4.1.1. Téléchargez à nouveau le fichier depuis Placements > Fallbacks et intégrez-le à votre application, même si vous en aviez déjà téléchargé un pour une version bêta 4.0.
Cette étape ne génère aucune erreur de build. Si vous la sautez, setFallback rejetera le fichier obsolète et chaque placement perdra son paywall de secours.
Modèle de données
getFlow retourne 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'). |
productIdentifiers | flow.paywalls[i].productIdentifiers | Les identifiants de produits se trouvent désormais sur chaque variante de flow, et non sur le flow lui-même. |
products (déprécié en v3) | supprimé | Utilisez flow.paywalls[i].productIdentifiers, ou appelez getPaywallProducts(flow) pour obtenir les produits complets. ProductReference est supprimé en tant que type public. |
webPurchaseUrl? | flow.paywalls[i].webPurchaseUrl | Déplacé du flow vers chaque variante de paywall. |
version?: number | flowVersionId?: string | Renommé, et le type est passé de number à string. |
requestLocale | supprimé | La locale ne fait plus partie du modèle. |
| (nouveau) | paywalls: AdaptyFlowPaywall[] | Chaque entrée est une variante de paywall dans le flow. |
| (nouveau) | responseCreatedAt: number | Horodatage de la réponse du serveur, en millisecondes. |
requestLocale reste sur AdaptyOnboarding — seul le modèle flow le supprime.
Les identifiants de produits ont été déplacés du flow vers chaque variation :
- const ids = paywall.productIdentifiers;
+ const ids = flow.paywalls[0].productIdentifiers;
Si votre code lit encore paywall.products — déprécié en v3 et maintenant supprimé — passez à productIdentifiers, ou appelez getPaywallProducts(flow) si vous avez besoin des produits complets plutôt que des identifiants.
Méthodes de paywall web
openWebPaywall et createWebPaywallUrl conservent leurs noms, mais l’option paywallOrProduct accepte désormais un AdaptyFlowPaywall (une variante de flow) plutôt qu’un AdaptyPaywall. Vous pouvez toujours passer un AdaptyPaywallProduct. Vérifiez que flow.paywalls n’est pas vide avant de lire la première entrée :
const flow = await adapty.getFlow({ placementId: 'YOUR_PLACEMENT_ID' });
- await adapty.openWebPaywall({ paywallOrProduct: paywall });
+ await adapty.openWebPaywall({ paywallOrProduct: flow.paywalls[0] });
Suivi des vues de flow
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.
- await adapty.logShowPaywall({ paywall });
+ await adapty.logShowFlow({ flow });
Comme dans v3, vous n’avez pas besoin d’appeler cette méthode lors de l’affichage de flows ou de paywalls rendus par Adapty — Adapty enregistre automatiquement ces vues.
Affichage des flows
createPaywallView → createFlowView
Renommez la fonction factory et passez l’AdaptyFlow. Le contrôleur retourné est renommé de PaywallViewController en FlowViewController, mais ses méthodes (present, dismiss, setEventHandlers, clearEventHandlers et showDialog) restent inchangées. Le type des paramètres est renommé de CreatePaywallViewParamsInput en CreateFlowViewParamsInput :
- import { createPaywallView } from '@adapty/capacitor';
+ import { createFlowView } from '@adapty/capacitor';
- const view = await createPaywallView(paywall);
+ const view = await createFlowView(flow);
await view.present();
Une vue de flow est à usage unique : après avoir appelé dismiss(), la vue est détruite et ses gestionnaires d’événements sont effacés. Appelez à nouveau createFlowView pour afficher le flow une nouvelle fois.
Nouveaux paramètres
CreateFlowViewParamsInput conserve tous les paramètres v3 (prefetchProducts, loadTimeoutMs, customTags, customTimers, customAssets, productPurchaseParams) et en ajoute trois :
customTimers existe toujours, mais il n’affecte que les paywalls créés avec l’ancien Paywall Builder. Le minuteur de compte à rebours d’un flow fonctionne selon le comportement défini dans le Flow & Paywall Builder, donc un flow ignore ce que vous passez ici.
| Paramètre | Description |
|---|---|
locale | La localisation à utiliser pour afficher le flow. Elle a été déplacée ici depuis getPaywall — voir getPaywall → getFlow. |
customLayoutId | L’ID personnalisé d’une mise en page dans la configuration des mises en page du flow. Passez-le pour afficher une mise en page spécifique plutôt que celle que le SDK choisit automatiquement en fonction du type d’appareil et de la taille d’écran. Si aucune mise en page ne correspond à l’ID, l’appel échoue avec une erreur no-view-configuration. Le Flow & Paywall Builder n’attribue pas encore d’ID de mise en page personnalisés, donc laissez ce paramètre non défini. |
android.enableSafeArea | Contrôle les marges de zone de sécurité Android à l’exécution. Imbriqué sous la clé android, vaut true par défaut. |
const view = await createFlowView(flow, {
locale: 'en',
customLayoutId: 'tablet_landscape',
android: { enableSafeArea: true },
});
Gestion des événements
L’interface du gestionnaire d’événements est renommée de EventHandlers en FlowEventHandlers, et un callback est renommé. Les corps des gestionnaires existants n’ont pas besoin d’être modifiés — il suffit de renommer :
- onRenderingFailed: (error) => { /* … */ },
+ onError: (error) => { /* … */ },
Tous les autres gestionnaires d’événements conservent leur nom. L’un d’eux change de signature : onAppeared est désormais (view) au lieu de (), où view est un FlowEventView décrivant la vue qui est apparue — y compris la localisation avec laquelle elle a été construite. Les gestionnaires existants continuent de fonctionner, car ils ignorent le nouvel argument. Consultez Gérer les événements de flow et de paywall pour la liste complète.
La v4 ajoute également quelques fonctionnalités que vous pouvez activer à la demande :
adapty.openWebUrl({ url, openIn })etadapty.requestAppReview()— ces méthodes sont utilisées par les gestionnaires par défautonUrlPressetonRequestAppReview, donc les URLs et les demandes d’avis sur l’application sont gérées nativement sans configuration supplémentaire. Appelez-les directement uniquement si vous surchargez ces gestionnaires.- Gestion des achats en mode Observer dans les flows via les nouveaux gestionnaires
onObserverPurchaseInitiated/onObserverRestoreInitiated. Voir Présenter des flows en mode Observer. onAnalytics: (name, params)— événements d’analyse émis par un flow, à commencer par une vue d’écran pour chaque écran ouvert par l’utilisateur. Voir Suivre les vues d’écran des flows.onRequestPermission: (permission, customArgs)— réservé aux demandes de permissions système (comme les notifications push ou l’accès à la caméra) émises par un flow. Les flows ne déclenchent pas encore de demandes de permissions, vous n’avez donc pas besoin de l’implémenter.
Séparément, la version 4.1.1 ajoute un événement au niveau du SDK plutôt qu’un gestionnaire de flow : 'onPromotedPurchaseReceived', transmis via adapty.addListener. Sans écouteur enregistré, le SDK finalise lui-même l’achat promu ; en enregistrer un délègue la finalisation à votre application. Voir Achats intégrés promus sur l’App Store.
APIs d’attribution externes renommées
À partir de la version 4.1.1 du SDK, les APIs permettant de transmettre des données d’attribution depuis un fournisseur externe (Adjust, AppsFlyer, Branch, Tenjin ou un fournisseur personnalisé) ont été renommées pour correspondre aux SDKs natifs. Il n’existe pas d’alias dépréciés, donc les appels existants cessent de fonctionner jusqu’à ce que vous les renommiez :
| Avant 4.1.1 | 4.1.1 |
|---|---|
adapty.updateAttribution({ attribution, source }) | adapty.updateExternalAttribution({ attribution, provider }) |
AttributionSource | AdaptyExternalAttributionProvider |
AdaptyProfile.appliedAttributionSources | AdaptyProfile.appliedExternalAttributionProviders |
updateAttribution → updateExternalAttribution
La méthode a été renommée et son option source devient provider. Les données d’attribution restent un objet simple :
- await adapty.updateAttribution({ attribution, source: 'adjust' });
+ await adapty.updateExternalAttribution({ attribution, provider: 'adjust' });
AttributionSource → AdaptyExternalAttributionProvider
Le type du fournisseur est renommé. Il reste une union ouverte — les valeurs prédéfinies sont 'apple_search_ads', 'adjust', 'appsflyer', 'branch' et 'tenjin', et toute autre chaîne est acceptée, ce qui permet d’utiliser un fournisseur ajouté ultérieurement par Adapty sans mise à jour du SDK :
- import type { AttributionSource } from '@adapty/capacitor';
+ import type { AdaptyExternalAttributionProvider } from '@adapty/capacitor';
AdaptyProfile.appliedAttributionSources → appliedExternalAttributionProviders
La propriété du profil qui liste les fournisseurs d’attribution appliqués au profil est renommée, et le type de ses éléments change en conséquence :
- if (profile.appliedAttributionSources?.includes('apple_search_ads')) {
+ if (profile.appliedExternalAttributionProviders?.includes('apple_search_ads')) {
// Apple Ads attribution has been applied
}
Le code qui la lit doit être mis à jour — voir Afficher un paywall ciblé Apple Ads.
Achats intégrés mis en avant sur l’App Store
Avant la version 4.1.1, un achat intégré mis en avant sur votre page produit App Store se finalisait de lui-même et Adapty enregistrait la transaction, mais votre application n’avait aucun moyen de l’intercepter. La version 4.1.1 ajoute ce point d’entrée, ce qui en fait une nouvelle fonctionnalité plutôt qu’une étape de migration : sans code de votre part, le SDK continue de finaliser les achats mis en avant automatiquement.
Rédigez du code uniquement pour prendre en charge la complétion vous-même — par exemple pour afficher un écran en premier. Enregistrez un écouteur pour le nouvel événement 'onPromotedPurchaseReceived', et complétez l’achat avec adapty.makePromotedPurchase. Tant que cet écouteur est enregistré, le SDK cesse de compléter les achats promus à votre place.
Changements de comportement par défaut
Ces changements ne provoquent pas d’erreurs de compilation, testez-les donc à l’exécution :
onAndroidSystemBack: Le comportement par défaut est passé de la fermeture de la vue à son maintien ouvert. Pour retrouver l’ancien comportement, renvoyeztruedepuis le handler.onPurchaseCompleted: Le comportement par défaut est passé de la fermeture de la vue (sauf si l’utilisateur a annulé l’achat) à son maintien ouvert dans tous les cas. Pour retrouver l’ancien comportement, renvoyezpurchaseResult.type !== 'user_cancelled'depuis le handler.onRestoreCompleted: Le comportement par défaut est passé de la fermeture de la vue après une restauration réussie à son maintien ouvert. Pour retrouver l’ancien comportement, renvoyeztruedepuis le handler.onUrlPress: Le comportement par défaut ouvre désormais l’URL via la couche native, en respectant le paramètre de navigateur intégré ou externe configuré dans le tableau de bord. Surchargez le handler pour ouvrir les URL vous-même.- Les vues sont à usage unique : après
dismiss(), la vue est détruite. AppelezcreateFlowViewà nouveau pour afficher le flow une nouvelle fois.
API supprimées
Exports supprimés
Ces symboles ne sont plus exportés depuis @adapty/capacitor. Supprimez leurs imports :
AdaptyPaywall: UtilisezAdaptyFlowetAdaptyFlowPaywallà la place.ProductReference: UtilisezAdaptyProductIdentifier, accessible viaflow.paywalls[i].productIdentifiers.AdaptyPaywallBuilder: Supprimé. Les flows et paywalls s’affichent nativement.AdaptyAndroidSubscriptionUpdateParameters: Utilisez la structure imbriquée des paramètres d’achatandroid(voir ci-dessous).
activate: lockMethodsUntilReady
lockMethodsUntilReady (déjà obsolète et sans effet en v3) est supprimé. Retirez-le de votre appel activate — le conserver ne compile plus :
- await adapty.activate({ apiKey: 'PUBLIC_SDK_KEY', params: { lockMethodsUntilReady: true } });
+ await adapty.activate({ apiKey: 'PUBLIC_SDK_KEY' });
makePurchase : paramètres Android
La forme Android plate (deprecated) de MakePurchaseParamsInput est supprimée — seule la forme imbriquée subsiste. Déplacez les paramètres d’achat Android dans params: { android: { ... } }. Consultez Effectuer des achats pour un exemple complet.
Dépréciation de l’API onboarding
L’API onboarding historique est dépréciée dans la v4 au profit du Flow & Paywall Builder. Elle fonctionne toujours, mais sera supprimée dans une prochaine version — prévoyez donc la migration de vos onboardings vers le Flow & Paywall Builder.
Symboles dépréciés : getOnboarding, getOnboardingForDefaultAudience, createOnboardingView et OnboardingViewController.