Report: State of in-app subscriptions in the US 2023 Get a report

Tutoriel : comment implémenter les achats intégrés dans une application Flutter ?

Alexey Goncharov

Updated: mars 20, 2023

Content

62fdf15a5a9626b86649d085 jp android tutorial 1 configuration 6

Flutter est un cadre relativement récent développé par Google qui vous permet de créer rapidement des applications (app) multiplateformes. L’autre cadre populaire est React Native de Facebook. Les applications Flutter sont conçues à la fois pour iOS et Android. Par conséquent, une bibliothèque d’achat doit être compatible à la fois avec StoreKit et avec la bibliothèque de facturation. 

Du point de vue de l’architecture, tout plugin de paiement – y compris notre SDK Adapty Flutter – est une enveloppe autour des bibliothèques natives, StoreKit et Billing Library. Dans notre cas, il s’agit d’une enveloppe autour de nos propres bibliothèques Adapty iOS et  Android SDK

Bibliothèques open source pour les achats intégrés (in-app purchases) dans les applications basées sur Flutter

Les solutions populaires pour les achats dans les applications Flutter sont les plugins open source in_app_purchase (développé par l’équipe derrière Flutter) et flutter_inapp_purchase (plugin non officiel). 

Ces plugins ont été conçus pour réaliser des achats côté client. Ils ne disposent pas de la validation des reçus (receipt validation) côté serveur (server side). Vous devrez mettre en place votre propre infrastructure côté serveur pour valider les reçus et recueillir des données analytiques sur les paiements concernant les renouvellements, les remboursements, les essais, les annulations, etc. 

De plus, ces bibliothèques sont généralement lentes à prendre en charge les nouvelles fonctionnalités des magasins. Pour n’en citer que quelques-uns, ils ne proposent pas d’offres promotionnelles, ne proposent pas de fonctions de paiement à l’utilisation et ne proposent pas de fonctions de paiement anticipé (pay upfront) pour iOS.

Comme notre bibliothèque communique avec notre serveur, elle présente toutes ces caractéristiques :

  • Validation du serveur d’achat ; 
  • Prise en charge complète des fonctions de paiement natives ; 
  • Syntaxe DRY ;
  • Analyse des abonnements et des achats et collecte de certaines autres données ;
  • Les tests A/B, ainsi que l’expérimentation rapide des achats, des prix et des périodes de promotion ;
  • Paywalls et offres promotionnelles (promo offer).

Pour que cet article soit bref et facile à lire, nous allons mettre en lien quelques articles que nous avons rédigés précédemment sur les étapes à suivre avant de commencer à travailler sur les achats pour votre application Flutter.

Création d’achats sur iOS et Android

Tout d’abord, vous devez créer un compte de développeur si vous n’en avez pas. Ensuite, vous devrez créer un achat hebdomadaire pour iOS et Android. Nous avons expliqué comment procéder dans nos articles précédents :

Création des achats pour iOS

Création des achats pour Android

Une fois que vous avez terminé, vous pouvez commencer à créer et à configurer votre projet.

Créer et configurer le projet

Pour que vos achats fonctionnent à la fois dans votre mise en œuvre et dans notre système, vous devrez remplir ces détails techniques.

61dbfcadde3e1409fe5f8314 iy6l5yif4wtrzqfjzaek9s70lntdy9bul 7h6homozvwghjkvrzry8ohu9pva

Pour iOS, vous aurez besoin de :

  • Spécifiez l’ID du Bundle pour lier votre projet Adapty à votre application ;
  • Configurez les notifications du serveur App Store dans App Store Connect, afin d’être informé des événements relatifs aux abonnements ;
  • Indiquez le secret partagé de l’App Store, que le serveur Adapty utilisera pour établir une connexion avec les serveurs d’Apple et valider les reçus.

Pour Android, le nom du paquet et le fichier clé du compte de service doivent tous deux être spécifiés. Le nom du paquet est l’ID du Bundle iOS pour Android. Vous devez utiliser le même que celui qui est utilisé dans le code. Il se trouve dans le fichier /android/app/build.gradle, qui est situé dans le répertoire android.defaultConfig.applicationId.

Configuration des produits et des paywalls

Un produit Adapty encapsule ceux de différents magasins. Pour l’instant, il n’y a que l’App Store et Google Play, mais nous introduirons d’autres magasins à l’avenir. L’idée derrière cette approche est de faciliter la collecte de statistiques multi-plateformes et de vous permettre de travailler avec des entités de haut niveau, par opposition aux identifiants.

Paywall est une entité abstraite qui contient un tableau de produits et un fichier de configuration distant (qui est un fichier JSON contenant les métadonnées que vous avez spécifiées dans votre tableau de bord). Vous devez coder en dur l’ID du paywall dans votre application – cet ID est utilisé pour récupérer le fichier de configuration et les données du produit. Vous pouvez modifier ces deux éléments sans avoir à mettre à jour l’application. Dans le scénario habituel, vous concevez le paywall et le remplissez avec les données reçues de notre part.

Créer un produit

Utilisons Google Play Console et App Store Connect pour créer un produit correspondant à un abonnement hebdomadaire. Remplissez l’ID des produits correspondants, que vous pouvez récupérer auprès des systèmes de paiement. Il est important de noter que, App Store Connect ne disposant pas d’API, vous devrez effectuer cette opération manuellement. Juste une fois, cependant. 

61dbfcadc56e16884ceeda5a 34mxwyuolr8iv5x2uec0mz6

Création d’un paywall

Lors de la création d’un paywall, l’essentiel est de spécifier son ID dans un format pratique. Cet identifiant sera ensuite utilisé par le SDK pour demander les données du paywall. Nous pensons qu’il s’agit d’une bonne approche : Avec cette architecture, il n’est pas nécessaire de coder en dur vos produits du côté client. Vous pouvez être flexible avec la gestion de vos produits, le versionnage, les tests, etc. L’autre option serait Firebase JSON avec un ensemble de produits intégrés. Cette méthode ne permet pas de valider les erreurs et n’est pas aussi conviviale.

61dbfcae9d2b62d615559378 zn55mgmaz86h7qtmlow pxcwlspih63ifgswsurxtydhjlqyj3gm jqtzo vk8bvb3txn29f7g2oe6o2voyadhruy1lhyyvqvuo6ms5ytfq

Voila! Après avoir créé un produit et un paywall, vous êtes maintenant prêt pour votre premier achat. Procédons à l’installation du SDK.

Comment utiliser le SDK

Examinons les principales fonctions dont nous aurons besoin pour configurer et utiliser les abonnements.

Installation de la bibliothèque

Tout d’abord, vous devez ajouter la bibliothèque adapty_flutter à votre projet. Pour ce faire, ajoutez la dépendance suivante à votre fichier pubspec.yaml :

dependencies:
  adapty_flutter: ^1.0.4

Après ça, executez :

flutter pub get

De là, vous pouvez importer Adapty SDK dans votre application comme ceci :

import 'package:adapty_flutter/adapty_flutter.dart';

Configuration

Vous devrez configurer votre application pour qu’elle fonctionne avec Adapty. Pour ce faire, ajoutez le drapeau AdaptyPublicSdkKey avec votre clé publique SDK dans Info.plist (pour iOS) ou dans AndroidManifest.xml (pour Android).

Vous pouvez trouver votre clé SDK dans Paramètres Adapty:

61dbfcaef59c49d11e233082 lsazt3ucjsc79arcgsxqdhss6j5t7gzc1ozj9kcwzet3 ouvcwuj

Info.plist:

&ltdict&gt
	...     
		&ltkey&gtAdaptyPublicSdkKey&lt/key&gt

AndroidManifest.xml:

&ltapplication ...&gt
        ...
        &ltmeta-data
               android:name="AdaptyPublicSdkKey"
               android:value="PUBLIC_SDK_KEY" /&gt
 &lt/application&gt

Ensuite, activez le SDK en invoquant ce code du côté de Flutter – par exemple, dans la méthode main() de votre projet :

void main() {
   runZoned(() async {
     Adapty.activate();
     final installId = await Service.getOrCreateInstallId();
     await Adapty.identify(***customer-user-id***);
     await Adapty.setLogLevel(AdaptyLogLevel.verbose);
     runApp(MyApp());
  });
 }

La fonction void Adapty.activate() active la bibliothèque Adapty_Flutter :

Future&ltbool&gt Adapty.identify(String customerUserId)

Adapty.identify vous permet de récupérer l’identifiant de l’utilisateur. Adapty le transmet aux systèmes d’abonnement et d’analyse pour attribuer des événements à ce profil. Vous pourrez également retrouver vos clients par customerUserId dans  Profiles.

Adapty enregistre les messages d’erreur et d’autres données importantes pour vous aider à comprendre ce qui se passe.

Future&ltvoid&gt Adapty.identify(AdaptyLogLevel value)

La fonction vous permet de choisir l’une des trois valeurs possibles :

  • fonction vous permet de choisir l’une des trois valeurs possibles :
  • AdaptyLogLevel.errors : seuls les messages d’erreur seront enregistrés. 
  • AdaptyLogLevel.verbose : les appels de méthode, les demandes et réponses API et les messages d’erreur seront consignés. 

Récupérer les paywalls

Pour récupérer la liste des paywalls, exécutez ce code :

try {
  final GetPaywallsResult getPaywallsResult = await Adapty.getPaywalls(forceUpdate: Bool);
  final List&ltAdaptyPaywall&gt paywalls = getPaywallsResult.paywalls;
 } on AdaptyError(adaptyError) {}
  catch(e) {}

La fonction Adapty.getPaywalls() renvoie l’objet GetPaywallsResult qui contient :

  • les Paywalls : Un tableau de paywall ( AdaptyPaywall ). Le modèle contient la liste des produits, l’ID du paywall, la charge utile personnalisée et quelques autres valeurs.

Faire des achats 

Dans l’étape précédente, vous avez récupéré le tableau du paywall. Maintenant, nous allons chercher celui dont vous avez besoin pour afficher ces produits dans votre interface utilisateur. Supposons que ce paywall s’appelle your_paywall_id :

final List<AdaptyPaywall>? paywalls = getPaywallsResult.paywalls;
    myPaywall = paywalls?.firstWhere((paywall) => paywall.developerId == "your_paywall_id", orElse: null);

Ensuite, en utilisant le tableau de produits du champ produits, affichez tous ses éléments. Supposons que l’utilisateur veuille acheter le premier produit. Par souci de simplicité, nous supposerons qu’il s’agit du premier élément du tableau des produits. 

final AdaptyProduct? product = myPaywall?.products?.first;

Pour lancer l’achat, invoquez la fonction makePurchaseResult. (N’oubliez pas d’envelopper cette opération dans un bloc try-catch pour continuer à recevoir tous les messages d’erreur du SDK).

final MakePurchaseResult makePurchaseResult = await Adapty.makePurchase(product);

Une fois que la fonction a été exécutée avec succès, la variable makePurchaseResult prendra le résultat comme valeur. Voici comment vérifier le niveau d’accès une fois l’achat effectué :

final isPremium = makePurchaseResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false;

Notez que AdaptyErrorCode.paymentCancelled signifie que l’utilisateur a annulé l’achat lui-même, ce qui signifie que ce n’est pas un message d’erreur réel. 

Pour renouveler les achats, utilisez la méthode .restorePurchases() :

try {
	final RestorePurchasesResult restorePurchasesResult = await Adapty.restorePurchases();
// "premium" is an identifier of default access level
  if (restorePurchasesResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false) {
  	// grant access to premium features
  }
} on AdaptyError catch (adaptyError) {}
catch (e) {}

Tenez compte du fait que les objets MakePurchaseResult et RestorePurchasesResult comprennent tous deux purchaserInfo. Cet objet contient des données sur les niveaux d’accès, les abonnements et les achats. En général, il suffit de vérifier le niveau d’accès de l’utilisateur pour savoir s’il peut accéder aux fonctions Premium de votre application.

Statut d’abonnement

Pour éviter de devoir vérifier toute la chaîne des transactions précédentes, nous introduisons le terme « niveau d’accès ». Le niveau d’accès est un indicateur qui explique la part des fonctionnalités de l’application à laquelle l’utilisateur a accès. S’ils n’ont pas encore effectué d’achats, leur niveau d’accès sera nul. Sinon, ce sera ce que vous avez spécifié pour votre produit.

Par exemple, vous pouvez avoir deux niveaux d’accès, à savoir, argent et or. Des achats différents débloqueront différents niveaux d’accès et fonctionnalités. La plupart des applications n’ont qu’un seul niveau d’accès.

Pour voir si l’abonnement est actif, il suffit de vérifier si l’utilisateur a un niveau d’accès actif. Vous pouvez utiliser la méthode.getPurchaserInfo() pour cela :

try {
	AdaptyPurchaserInfo purchaserInfo = await Adapty.getPurchaserInfo();
   // "premium" is an identifier of default access level
  if (purchaserInfo.accessLevels['premium']?.isActive ?? false) {
  	// grant access to premium features
  }
} on AdaptyError catch (adaptyError) {}
catch (e) {}

Vous pouvez également vous abonner au flux .purchaserInfoUpdateStream pour être informé en temps utile de toute modification du niveau d’accès de l’abonné. Voici comment faire :

Adapty.purchaserInfoUpdateStream.listen((purchaserInfo) {
  print('#Adapty# Purchaser Info Updated');
	if (purchaserInfo.accessLevels['premium'].isActive) {
  	// grant access to premium features
  }
});

Subscribe to Adapty newsletter

Get fresh paywall ideas, subscription insights, and mobile app news every month!

Conclusion

Nous avons conçu notre SDK de manière à vous aider à intégrer rapidement les paiements dans votre application.  De plus, nous avons également essayé de simplifier toutes les autres étapes que vous pourriez avoir à franchir, comme les tests AB, les analyses et les intégrations supplémentaires.

Nous vous fournirons gratuitement toutes les fonctionnalités d’achat si vos revenus sont inférieurs à 10 000 $ par mois. Épargnez-vous des mois de travail et concentrez-vous sur le plus important : votre produit.