---
title: "Migrer le SDK Kotlin Multiplatform Adapty vers la v4.0"
description: "Migrez vers le SDK Kotlin Multiplatform Adapty v4.0 (bêta) en remplaçant les API paywall par des API flow, compatibles avec le Flow Builder et le Paywall Builder."
---

Le SDK Kotlin Multiplatform Adapty 4.0 (bêta) introduit les flows et renomme les API paywall en conséquence. Les nouvelles API fonctionnent à la fois avec le nouveau Flow Builder et le Paywall Builder existant — aucune modification de configuration n'est requise côté Adapty Dashboard.

## Référence rapide \{#quick-reference\}

| v3 | v4 |
|---|---|
| `Adapty.getPaywall(placementId, locale)` | `Adapty.getFlow(placementId)` |
| `Adapty.getPaywallForDefaultAudience(placementId, locale)` | `Adapty.getFlowForDefaultAudience(placementId)` |
| `Adapty.getPaywallProducts(paywall)` | `Adapty.getPaywallProducts(flow)` |
| `Adapty.logShowPaywall(paywall)` | `Adapty.logShowFlow(flow)` |
| `AdaptyPaywall` | `AdaptyFlow` |
| `AdaptyUI.createPaywallView(paywall, ...)` | `AdaptyUI.createFlowView(flow, ...)` |
| `AdaptyUI.createNativePaywallView(...)` → `AdaptyNativePaywallView` | `AdaptyUI.createNativeFlowView(...)` → `AdaptyNativeFlowView` |
| `AdaptyUIPaywallView` | `AdaptyUIFlowView` |
| `AdaptyUI.presentPaywallView(view)` / `dismissPaywallView(view)` | `AdaptyUI.presentFlowView(view)` / `dismissFlowView(view)` |
| `AdaptyUI.setPaywallsEventsObserver(observer)` | `AdaptyUI.setFlowsEventsObserver(observer)` |
| `AdaptyUI.registerPaywallEventsListener` / `unregisterPaywallEventsListener` | `AdaptyUI.registerFlowEventsListener` / `unregisterFlowEventsListener` |
| `AdaptyUIPaywallsEventsObserver` | `AdaptyUIFlowsEventsObserver` |
| `AdaptyUIPaywallPlatformView(paywall, ...)` | `AdaptyUIFlowPlatformView(flow, ...)` |
| `paywallViewDidPerformAction`, `paywallViewDidAppear` et autres callbacks `paywallView...` | `flowViewDidPerformAction`, `flowViewDidAppear` et autres callbacks `flowView...` |
| `paywallViewDidFailRendering` | `flowViewDidReceiveError` |

`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` n'acceptent plus de paramètre `locale` — passez-le plutôt à `createFlowView`. Les APIs d'achat et de profil (`makePurchase`, `restorePurchases`, `getProfile`, `identify`, `updateProfile`) ainsi que `setFallback` conservent les mêmes signatures, mais le fichier de secours lui-même doit être retéléchargé — voir [Fichiers de secours](#fallback-files). Les méthodes d'onboarding fonctionnent toujours mais sont dépréciées — voir [Dépréciation de l'API d'onboarding](#onboarding-api-deprecation). Certains comportements par défaut ont changé — voir [Changements de comportement par défaut](#default-behavior-changes).

## Installation \{#installation\}

La v4.0 est une version préliminaire, donc épinglez la version exacte — Gradle ne sélectionne pas les versions préliminaires via les plages dynamiques :

```toml showLineNumbers title="libs.versions.toml"
[versions]
adapty-kmp = "4.0.1-beta.1"

[libraries]
adapty-kmp = { module = "io.adapty:adapty-kmp", version.ref = "adapty-kmp" }
adapty-kmp-ui = { module = "io.adapty:adapty-kmp-ui", version.ref = "adapty-kmp" }
```

Le module `adapty-kmp-ui` n'est nécessaire que si vous affichez des flows et des paywalls avec la couche Compose Multiplatform (`view.present()`). Consultez [Installer le SDK Adapty](sdk-installation-kotlin-multiplatform) pour la configuration complète.

Les SDK natifs Adapty sous-jacents sont mis à jour vers leurs versions 4.x sur les deux plateformes et sont résolus automatiquement — aucune modification de build n'est nécessaire. La cible de déploiement iOS reste **15.0**, inchangée dans cette version.

## Récupération 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
- Adapty.getPaywall("YOUR_PLACEMENT_ID", locale = "en")
-     .onSuccess { paywall ->
-         // use the paywall
+ Adapty.getFlow("YOUR_PLACEMENT_ID")
+     .onSuccess { flow ->
+         AdaptyUI.createFlowView(flow = flow, locale = "en")
      }
      .onError { error ->
          // handle the error
      }
```

`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 ne possède pas de version `en`. Voir [Localisations et codes de langue](kmp-localizations-and-locale-codes).

`getPaywallForDefaultAudience` est renommé de la même façon :

```diff showLineNumbers
- Adapty.getPaywallForDefaultAudience("YOUR_PLACEMENT_ID", locale = "en")
+ Adapty.getFlowForDefaultAudience("YOUR_PLACEMENT_ID")
```

### getPaywallProducts(paywall) → getPaywallProducts(flow)

`getPaywallProducts` conserve son nom mais prend désormais un `AdaptyFlow` :

```diff showLineNumbers
- Adapty.getPaywallProducts(paywall)
+ Adapty.getPaywallProducts(flow)
      .onSuccess { products ->
          // use the products
      }
```

### Fichiers de secours \{#fallback-files\}

Le format du fichier de secours [a changé dans 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` à la place d'un `AdaptyPaywall`, et la structure de l'objet a changé :

| Propriété v3 `AdaptyPaywall` | Propriété v4 `AdaptyFlow` | Action |
|---|---|---|
| `remoteConfig: AdaptyRemoteConfig?` (unique) | `remoteConfigs: List<AdaptyRemoteConfig>` | Un flow contient une Remote Config par langue configurée. Lisez celle qui correspond à l'utilisateur : `flow.remoteConfigs.firstOrNull { it.locale == "en" }`. |
| _(nouveau)_ | `paywalls: List<AdaptyFlowPaywall>` | Chaque entrée est une variante de paywall dans le flow, avec son propre `name`, `variationId` et `productIdentifiers`. Les méthodes de paywall web prennent un `AdaptyFlowPaywall` — voir [Méthodes de paywall web](#web-paywall-methods). |
| `productIdentifiers` | déplacé | Les identifiants de produit se trouvent désormais sur chaque variante : `flow.paywalls[i].productIdentifiers`. Pour récupérer les produits, continuez d'appeler `getPaywallProducts(flow)`. |
| `hasViewConfiguration` | supprimé | Supprimez tout contrôle `hasViewConfiguration` de votre code — `createFlowView` renvoie une erreur à la place (voir [Affichage des flows](#displaying-flows)). |

`hasViewConfiguration` reste sur `AdaptyOnboarding` — seul le modèle de flow le supprime.

## Méthodes de paywall web \{#web-paywall-methods\}

`openWebPaywall` et `createWebPaywallUrl` conservent leurs noms, mais le paramètre `paywall` est remplacé par un paramètre `flowPaywall` qui prend un `AdaptyFlowPaywall` — l'une des variantes dans `flow.paywalls`. Vous pouvez toujours passer un `AdaptyPaywallProduct` à la place :

```diff showLineNumbers
- Adapty.openWebPaywall(paywall = paywall)
+ flow.paywalls.firstOrNull()?.let { flowPaywall ->
+     Adapty.openWebPaywall(flowPaywall = flowPaywall)
+ }
```

## 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, de sorte que les métriques de funnel et de test A/B existantes continuent de fonctionner sans modification du tableau de bord.

```diff showLineNumbers
- Adapty.logShowPaywall(paywall)
+ Adapty.logShowFlow(flow)
```

Comme en v3, vous n'avez pas besoin d'appeler cette méthode lors de l'affichage de flows ou de paywalls générés par le [Flow Builder](adapty-flow-builder) ou le [Paywall Builder](adapty-paywall-builder) — Adapty suit ces vues automatiquement.

## Affichage des flows \{#displaying-flows\}

### createPaywallView → createFlowView

Renommez la méthode factory et transmettez l'`AdaptyFlow`. Le type de vue renvoyé est renommé de `AdaptyUIPaywallView` en `AdaptyUIFlowView`, mais ses méthodes (`present`, `dismiss`) et les paramètres optionnels (`loadTimeout`, `preloadProducts`, `customTags`, `customTimers`, `customAssets`, `productPurchaseParams`) restent inchangés. Un paramètre optionnel est nouveau : `locale`, qui remplace le `locale` que vous passiez auparavant à `getPaywall` — voir [Récupérer les flows](#fetching-flows).

```diff showLineNumbers
- AdaptyUI.createPaywallView(paywall)
+ AdaptyUI.createFlowView(flow)
      .onSuccess { view ->
          view.present()
      }
      .onError { error ->
          // handle the error
      }
```

Si vous n'utilisez pas Compose Multiplatform, la méthode factory native est renommée de la même façon :

```diff showLineNumbers
- AdaptyUI.createNativePaywallView(paywall)
+ AdaptyUI.createNativeFlowView(flow)
```

`createFlowView` retourne un `AdaptyResult.Error` si le flow n'a pas de vue configurée — cela remplace la vérification `hasViewConfiguration` de la v3 :

```diff showLineNumbers
- if (paywall.hasViewConfiguration) {
-     AdaptyUI.createPaywallView(paywall)
-         .onSuccess { view -> view.present() }
- }
+ AdaptyUI.createFlowView(flow)
+     .onSuccess { view -> view.present() }
+     .onError { error ->
+         // the flow has no view configured, or view creation failed
+     }
```

:::note
Une vue de flow est à usage unique : après avoir appelé `dismiss()`, la vue est détruite. Appelez à nouveau `createFlowView` pour afficher le flow une nouvelle fois.
:::

## Gestion des événements \{#handling-events\}

L'observateur d'événements est renommé de `AdaptyUIPaywallsEventsObserver` en `AdaptyUIFlowsEventsObserver`, et ses callbacks remplacent le préfixe `paywallView` par `flowView`. Le contenu des handlers existants n'a pas besoin d'être modifié — il suffit de renommer le type et les overrides :

```diff showLineNumbers
- AdaptyUI.setPaywallsEventsObserver(object : AdaptyUIPaywallsEventsObserver {
-     override fun paywallViewDidFinishPurchase(
-         view: AdaptyUIPaywallView,
+ AdaptyUI.setFlowsEventsObserver(object : AdaptyUIFlowsEventsObserver {
+     override fun flowViewDidFinishPurchase(
+         view: AdaptyUIFlowView,
          product: AdaptyPaywallProduct,
          purchaseResult: AdaptyPurchaseResult
      ) {
          // custom logic after purchase
      }
  })
```

Un callback est également renommé : `paywallViewDidFailRendering` devient `flowViewDidReceiveError`. Il se déclenche pour les mêmes erreurs de rendu qu'auparavant, ainsi que pour d'autres erreurs d'exécution non liées aux achats :

```diff showLineNumbers
- override fun paywallViewDidFailRendering(view: AdaptyUIPaywallView, error: AdaptyError) {}
+ override fun flowViewDidReceiveError(view: AdaptyUIFlowView, error: AdaptyError) {}
```

Consultez [Gérer les événements flow et paywall](kmp-handling-events) pour la liste complète des callbacks.

### Vue de la plateforme Compose \{#compose-platform-view\}

Si vous intégrez des vues avec le composable Compose Multiplatform, `AdaptyUIPaywallPlatformView(paywall, ...)` est renommé en `AdaptyUIFlowPlatformView(flow, ...)`. Les callbacks d'événements conservent leurs noms `onDid...`, sauf `onDidFailRendering`, qui devient `onDidReceiveError` :

```diff showLineNumbers
- AdaptyUIPaywallPlatformView(
-     paywall = paywall,
+ AdaptyUIFlowPlatformView(
+     flow = flow,
      onDidFinishPurchase = { view, product, result -> /* ... */ },
  )
```

Comme dans la v3, les callbacks que vous passez ici (et tout observateur enregistré via `registerFlowEventsListener`) s'exécutent **en plus** de l'observateur global, et non à sa place — votre callback observe un événement ; il ne remplace pas le comportement global par défaut. Gardez les [valeurs par défaut modifiées](#default-behavior-changes) à l'esprit : par exemple, le comportement global par défaut ne ferme plus la vue après un achat.

### Nouvelles API \{#new-apis\}

- `AdaptyUI.setObserverModeResolver(...)` avec un `AdaptyUIObserverModeResolver` — gère les achats et les restaurations initiés depuis les flows lorsque le SDK fonctionne en [mode Observateur](implement-observer-mode-kmp). Auparavant, cette fonctionnalité n'était disponible que dans les SDK natifs iOS et Android. Voir [Présenter des flows en mode Observateur](kmp-present-flows-in-observer-mode).
- `AdaptyUI.setSystemRequestsHandler(...)` avec un `AdaptyUISystemRequestsHandler` — réservé aux requêtes système d'un flow (invites de permissions OS et demandes d'évaluation de l'application). Les flows ne déclenchent pas encore ces requêtes, vous n'avez donc pas besoin d'enregistrer un handler.
- Le nouveau callback optionnel `flowViewDidReceiveAnalyticEvent` est réservé aux événements analytiques personnalisés provenant d'un flow. Les flows n'émettent pas encore ces événements vers votre code, vous n'avez donc pas besoin de l'implémenter.
- `AdaptyUI.openWebUrl(url, openIn)` et `AdaptyUI.requestAppReview()` — ces méthodes servent la gestion par défaut de `OpenUrlAction` et le `handleAppReviewRequest` par défaut, afin que les URLs et les invites d'évaluation de l'application soient traitées nativement sans configuration supplémentaire. Appelez-les directement uniquement si vous remplacez ces comportements par défaut.
- `AdaptyUIFlowView.locale` — indique la localisation avec laquelle la vue a été construite, vous permettant de savoir quelle langue l'utilisateur voit réellement. Nécessite le SDK 4.0.1-beta.1 ou une version ultérieure.
- `AdaptyConfig.ServerCluster.CN` — une nouvelle option de cluster de serveurs aux côtés de `DEFAULT` et `EU`, pour connecter votre application aux [serveurs Adapty en Chine](china-cluster).

## Changements de comportement par défaut \{#default-behavior-changes\}

Ces changements ne génèrent pas d'erreurs de compilation, testez-les donc à l'exécution :

- **Finalisation d'achat** : En v3, le comportement par défaut de `paywallViewDidFinishPurchase` fermait la vue après tout résultat d'achat autre que `AdaptyPurchaseResult.UserCanceled`. En v4, le comportement par défaut de `flowViewDidFinishPurchase` ne fait rien, donc **un flow reste ouvert après un achat jusqu'à ce que vous le fermiez vous-même** — comme sur iOS. Si vous vous appuyiez sur cette fermeture automatique, appelez `view.dismiss()` une fois l'achat terminé.
- **Bouton retour Android** : En v3, le comportement par défaut de `paywallViewDidPerformAction` fermait la vue pour `CloseAction` et `AndroidSystemBackAction`. En v4, le comportement par défaut ne gère que `CloseAction` — **le bouton retour système ne ferme plus un flow automatiquement**, comme sur iOS où un flow ne peut pas être fermé par un geste système. Donnez aux utilisateurs un moyen explicite de sortir (un bouton **Close** ou une action `on_device_back`), ou fermez la vue vous-même dans `flowViewDidPerformAction`.
- **Erreurs de vue** : En v3, le comportement par défaut de `paywallViewDidFailRendering` ne faisait rien. En v4, le comportement par défaut de `flowViewDidReceiveError` **ferme la vue** — surchargez-le si vous souhaitez garder la vue ouverte ou gérer l'erreur différemment.
- **Les vues sont à usage unique** : Après `dismiss()`, la vue est détruite. Appelez à nouveau `createFlowView` pour afficher le flow une nouvelle fois.

## Dépréciation de l'API onboarding \{#onboarding-api-deprecation\}

L'ancienne API onboarding est dépréciée dans la v4.0 au profit du [Flow Builder](adapty-flow-builder). Elle fonctionne toujours, mais sera supprimée dans une prochaine version — prévoyez donc la migration de vos onboardings vers le Flow Builder.

Symboles dépréciés : `getOnboarding`, `getOnboardingForDefaultAudience`, `AdaptyUI.createOnboardingView`, `AdaptyUI.createNativeOnboardingView` et `AdaptyUIOnboardingsEventsObserver`.