Flutter - Gérer les événements de flow et de paywall
Ce guide couvre la gestion des événements pour les achats, les restaurations, la sélection de produits et le rendu. La fermeture de la vue et l’ouverture des liens sont gérées par l’implémentation par défaut de flowViewDidPerformAction — consultez notre guide sur la gestion des actions de boutons pour les remplacer ou gérer des actions de boutons personnalisés.
Les flows et les paywalls configurés avec le builder n’ont pas besoin de code supplémentaire pour effectuer et restaurer des achats. Cependant, ils génèrent certains événements auxquels votre application peut réagir. Ces événements incluent les appuis sur des boutons (boutons de fermeture, URLs, sélections de produits, etc.) ainsi que des notifications sur les actions liées aux achats effectuées sur le flow ou le paywall. Découvrez ci-dessous comment réagir à ces événements.
Pour contrôler ou surveiller les processus se déroulant sur l’écran du flow ou du paywall dans votre application mobile, implémentez les méthodes AdaptyUIFlowsEventsObserver et définissez l’observateur avant d’afficher n’importe quel écran :
AdaptyUI().setFlowsEventsObserver(this);Trois méthodes d’observateur sont obligatoires — votre classe ne compilera pas sans elles : flowViewDidFinishPurchase, flowViewDidFinishRestore et flowViewDidReceiveError. Toutes les autres méthodes sont facultatives. Pour détacher un observateur précédemment défini, passez null à setFlowsEventsObserver.
Vous souhaitez voir un exemple concret d’intégration du SDK Adapty dans une application mobile ? Découvrez nos applications exemples, qui illustrent la configuration complète, notamment l’affichage des paywalls, la réalisation d’achats et d’autres fonctionnalités de base.
Les exemples d’événements ci-dessous montrent les propriétés disponibles sur chaque objet, avec des valeurs illustratives en commentaires.
Événements générés par l’utilisateur
Vue affichée
Cette méthode est invoquée lorsque la vue du flow ou du paywall s’affiche à l’écran.
Sur iOS, elle est également invoquée lorsqu’un utilisateur appuie sur le bouton de paywall web à l’intérieur d’un paywall, et qu’un paywall web s’ouvre dans un navigateur intégré à l’application.
void flowViewDidAppear(AdaptyUIFlowView view) {
}Vue disparue
Cette méthode est invoquée lorsque la vue du flow ou du paywall est masquée de l’écran.
Sur iOS, également invoqué lorsqu’un paywall web ouvert depuis un paywall dans un navigateur intégré disparaît de l’écran.
void flowViewDidDisappear(AdaptyUIFlowView view) {
}Sélection du produit
Si un produit est sélectionné pour achat (par un utilisateur ou par le système), cette méthode sera invoquée :
void flowViewDidSelectProduct(AdaptyUIFlowView view, String productId) {
}Exemple d’événement (Cliquez pour développer)
void flowViewDidSelectProduct(AdaptyUIFlowView view, String productId) {
// productId is a String:
productId; // 'premium_monthly'
} Achat démarré
Si un utilisateur initie le processus d’achat, cette méthode sera invoquée :
void flowViewDidStartPurchase(AdaptyUIFlowView view, AdaptyPaywallProduct product) {
}Exemple d’événement (cliquez pour développer)
void flowViewDidStartPurchase(AdaptyUIFlowView view, AdaptyPaywallProduct product) {
// product — AdaptyPaywallProduct:
product.vendorProductId; // 'premium_monthly'
product.localizedTitle; // 'Premium Monthly'
product.localizedDescription; // 'Premium subscription for 1 month'
product.price.amount; // 9.99 (double)
product.price.currencyCode; // 'USD'
product.price.localizedString; // '$9.99'
} Achat finalisé
Cette méthode est obligatoire. Elle est invoquée lorsqu’un achat réussit, que l’utilisateur annule son achat, ou que l’achat semble être en attente :
void flowViewDidFinishPurchase(AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchaseResult) {
switch (purchaseResult) {
case AdaptyPurchaseResultSuccess(profile: final profile):
// successful purchase
break;
case AdaptyPurchaseResultPending():
// purchase is pending
break;
case AdaptyPurchaseResultUserCancelled():
// user cancelled the purchase
break;
default:
break;
}
}Exemples d’événements (Cliquez pour développer)
void flowViewDidFinishPurchase(AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchaseResult) {
// product — AdaptyPaywallProduct:
product.vendorProductId; // 'premium_monthly'
switch (purchaseResult) {
case AdaptyPurchaseResultSuccess(profile: final profile):
// profile — AdaptyProfile:
profile.accessLevels['premium']?.isActive; // true
profile.accessLevels['premium']?.expiresAt; // DateTime(2027, 2, 15, 10, 30)
break;
case AdaptyPurchaseResultPending():
// no additional data
break;
case AdaptyPurchaseResultUserCancelled():
// no additional data
break;
}
} Contrairement à la v3, cette méthode n’a pas de comportement par défaut — la vue n’est plus fermée automatiquement après un achat réussi. Décidez vous-même de la suite : poursuivre le flow ou appeler view.dismiss(). Reportez-vous à Répondre aux actions des boutons pour en savoir plus sur la fermeture d’un écran.
Navigation web terminée
Cette méthode est invoquée après une tentative d’ouverture d’un paywall web pour un produit spécifique. Cela inclut les tentatives de navigation réussies comme échouées :
void flowViewDidFinishWebPaymentNavigation(AdaptyUIFlowView view,
AdaptyPaywallProduct? product,
AdaptyError? error) {
}Paramètres :
| Paramètre | Description |
|---|---|
| product | Un AdaptyPaywallProduct pour lequel le paywall web a été ouvert. Peut être null. |
| error | Un objet AdaptyError si la navigation vers le paywall web a échoué ; null si la navigation a réussi. |
Échec de l’achat
Cette méthode est appelée lorsqu’un achat échoue (par exemple, en cas de problème de paiement ou d’erreur réseau). Elle ne se déclenche pas pour les annulations initiées par l’utilisateur ou les transactions en attente — celles-ci sont gérées par flowViewDidFinishPurchase :
void flowViewDidFailPurchase(AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyError error) {
}Restauration démarrée
Si un utilisateur lance le processus de restauration, cette méthode sera appelée :
void flowViewDidStartRestore(AdaptyUIFlowView view) {
}Restauration réussie
Cette méthode est obligatoire. Si la restauration d’un achat réussit, elle sera invoquée :
void flowViewDidFinishRestore(AdaptyUIFlowView view, AdaptyProfile profile) {
}Exemple d’événement (cliquez pour développer)
void flowViewDidFinishRestore(AdaptyUIFlowView view, AdaptyProfile profile) {
// profile — AdaptyProfile:
profile.accessLevels['premium']?.isActive; // true
profile.accessLevels['premium']?.expiresAt; // DateTime(2027, 2, 15, 10, 30)
profile.subscriptions['premium_monthly']?.isActive; // true
profile.subscriptions['premium_monthly']?.expiresAt; // DateTime(2027, 2, 15, 10, 30)
} Nous vous recommandons de fermer l’écran si l’utilisateur dispose du accessLevel requis. Consultez la rubrique Statut de l’abonnement pour savoir comment le vérifier, et la rubrique Répondre aux actions des boutons pour savoir comment fermer un écran.
Échec de la restauration
Si la restauration d’un achat échoue, cette méthode sera invoquée :
void flowViewDidFailRestore(AdaptyUIFlowView view, AdaptyError error) {
}Récupération et affichage des données
Erreurs de chargement des produits
Si vous ne transmettez pas le tableau de produits lors de l’initialisation, AdaptyUI récupérera lui-même les objets nécessaires auprès du serveur. Si cette opération échoue, AdaptyUI signalera l’erreur en appelant cette méthode :
void flowViewDidFailLoadingProducts(AdaptyUIFlowView view, AdaptyError error) {
}Erreurs de vue
Cette méthode est obligatoire. Elle remplace la méthode paywallViewDidFailRendering de la v3 : les erreurs survenant lors du rendu de l’interface, ainsi que les autres erreurs de vue, sont signalées via cet appel. Une fois implémentée, la gestion de la fermeture vous appartient — nous recommandons de fermer la vue en cas d’erreur, ce qui est également le comportement par défaut du SDK lorsqu’aucun observateur n’est défini :
void flowViewDidReceiveError(AdaptyUIFlowView view, AdaptyError error) {
// log the error and dismiss the broken view
view.dismiss();
}Dans une situation normale, les erreurs de rendu ne devraient pas se produire, donc si vous en rencontrez une, veuillez nous en informer.
Événements d’analyse
void flowViewDidReceiveAnalyticEvent(
AdaptyUIFlowView view,
String name,
Map<String, dynamic> params,
) {
}Un flow envoie flow_screen_showed chaque fois qu’un utilisateur ouvre l’un de ses écrans. Adapty comptabilise ces événements dans ses propres analytics de flow et les transmet également à votre application, afin que vous puissiez reconstituer le même funnel dans vos propres analytics.
| Paramètre | Description |
|---|---|
instanceId | L’ID de l’écran que l’utilisateur a ouvert. |
screen_order | La position de l’écran dans le flow. |
is_last_screen | true quand l’écran n’a nulle part où aller ensuite. Un flow avec des embranchements peut se terminer sur plusieurs écrans différents, et chacun d’eux renvoie true. |
isBackendEvent et isCustomerEvent sont tous les deux true pour cet événement : Adapty continue de le comptabiliser, et votre application le reçoit également.
Consultez Suivre les vues d’écran de flow pour savoir comment les utiliser.
Gérer les achats en mode observateur
Si vous avez activé le SDK en mode observateur et que vous affichez un flow ou un paywall rendu par Adapty, le SDK n’effectue pas les achats à votre place. Lorsqu’un utilisateur appuie sur le bouton d’achat ou de restauration, le SDK appelle votre AdaptyUIObserverModeResolver à la place. Consultez Présenter des flows en mode observateur pour la configuration complète.
Gérer les requêtes système
Le AdaptyUISystemRequestsHandler (enregistré via AdaptyUI().setSystemRequestsHandler(...)) est réservé aux requêtes système émises par un flow : demandes de permissions OS (notifications push ou accès à la caméra, par exemple) et demandes d’avis sur l’App Store. Les flows ne déclenchent pas encore ces requêtes, vous n’avez donc pas besoin d’enregistrer de handler.
Si vous en enregistrez un, notez que handlePermission est la méthode requise de la classe — demandez la permission avec votre propre code, puis retournez AdaptyUIPermissionResult.granted() ou AdaptyUIPermissionResult.denied() ; handleAppReviewRequest est optionnel.
Ce guide couvre la gestion des événements liés aux achats, aux restaurations, à la sélection de produits et à l’affichage des paywalls. Vous devez également implémenter la gestion des boutons (fermeture du paywall, ouverture de liens, etc.). Consultez notre guide sur la gestion des actions de boutons pour plus de détails.
Les paywalls configurés avec le Paywall Builder n’ont pas besoin de code supplémentaire pour effectuer et restaurer des achats. Cependant, ils génèrent certains événements auxquels votre application peut réagir. Ces événements incluent des appuis sur des boutons (boutons de fermeture, URLs, sélections de produits, etc.) ainsi que des notifications sur les actions liées aux achats effectuées sur le paywall. Découvrez comment réagir à ces événements ci-dessous.
Ce guide concerne uniquement les paywalls du nouveau Paywall Builder, qui nécessitent le SDK Adapty v3.0 ou une version ultérieure.
Pour contrôler ou surveiller les processus qui se produisent sur l’écran du paywall dans votre application mobile, implémentez les méthodes AdaptyUIPaywallsEventsObserver et définissez l’observateur avant d’afficher un écran :
AdaptyUI().setPaywallsEventsObserver(this);Vous souhaitez voir un exemple concret d’intégration du SDK Adapty dans une application mobile ? Découvrez nos applications exemples, qui illustrent la configuration complète, notamment l’affichage des paywalls, la réalisation d’achats et d’autres fonctionnalités de base.
Les exemples d’événements ci-dessous montrent les propriétés disponibles sur chaque objet, avec des valeurs illustratives dans les commentaires.
Événements générés par l’utilisateur
Paywall apparu
Cette méthode est appelée lorsque la vue du paywall s’affiche à l’écran.
Sur iOS, également appelée lorsqu’un utilisateur appuie sur le bouton de paywall web dans un paywall, et qu’un paywall web s’ouvre dans un navigateur intégré à l’application.
void paywallViewDidAppear(AdaptyUIPaywallView view) {
}Paywall disparu
Cette méthode est appelée lorsque la vue du paywall est fermée depuis l’écran.
Sur iOS, également invoqué lorsqu’un web paywall ouvert depuis un paywall dans un navigateur intégré disparaît de l’écran.
void paywallViewDidDisappear(AdaptyUIPaywallView view) {
}Sélection de produit
Si un produit est sélectionné pour l’achat (par un utilisateur ou par le système), cette méthode sera invoquée :
void paywallViewDidSelectProduct(AdaptyUIPaywallView view, String productId) {
}Exemple d’événement (Cliquez pour développer)
void paywallViewDidSelectProduct(AdaptyUIPaywallView view, String productId) {
// productId is a String:
productId; // 'premium_monthly'
} Achat initié
Si un utilisateur déclenche le processus d’achat, cette méthode sera appelée :
void paywallViewDidStartPurchase(AdaptyUIPaywallView view, AdaptyPaywallProduct product) {
}Exemple d’événement (cliquez pour développer)
void paywallViewDidStartPurchase(AdaptyUIPaywallView view, AdaptyPaywallProduct product) {
// product — AdaptyPaywallProduct:
product.vendorProductId; // 'premium_monthly'
product.localizedTitle; // 'Premium Monthly'
product.localizedDescription; // 'Premium subscription for 1 month'
product.price.amount; // 9.99 (double)
product.price.currencyCode; // 'USD'
product.price.localizedString; // '$9.99'
} Achat terminé
Cette méthode est invoquée lorsqu’un achat réussit, que l’utilisateur annule son achat, ou que l’achat semble être en attente :
void paywallViewDidFinishPurchase(AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchaseResult) {
switch (purchaseResult) {
case AdaptyPurchaseResultSuccess(profile: final profile):
// successful purchase
break;
case AdaptyPurchaseResultPending():
// purchase is pending
break;
case AdaptyPurchaseResultUserCancelled():
// user cancelled the purchase
break;
default:
break;
}
}Exemples d’événements (Cliquez pour développer)
void paywallViewDidFinishPurchase(AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchaseResult) {
// product — AdaptyPaywallProduct:
product.vendorProductId; // 'premium_monthly'
switch (purchaseResult) {
case AdaptyPurchaseResultSuccess(profile: final profile):
// profile — AdaptyProfile:
profile.accessLevels['premium']?.isActive; // true
profile.accessLevels['premium']?.expiresAt; // DateTime(2027, 2, 15, 10, 30)
break;
case AdaptyPurchaseResultPending():
// no additional data
break;
case AdaptyPurchaseResultUserCancelled():
// no additional data
break;
}
} Nous recommandons de fermer l’écran dans ce cas. Consultez Répondre aux actions des boutons pour plus de détails sur la fermeture d’un écran de paywall.
Navigation web terminée
Cette méthode est invoquée après une tentative d’ouverture d’un paywall web pour un produit spécifique. Cela inclut les tentatives de navigation réussies et échouées :
void paywallViewDidFinishWebPaymentNavigation(AdaptyUIPaywallView view,
AdaptyPaywallProduct? product,
AdaptyError? error) {
}Paramètres :
| Paramètre | Description |
|---|---|
| product | Un AdaptyPaywallProduct pour lequel le paywall web a été ouvert. Peut être null. |
| error | Un objet AdaptyError si la navigation dans le paywall web a échoué ; null si la navigation a réussi. |
Exemples d’événements (Cliquer pour développer)
void paywallViewDidFinishWebPaymentNavigation(AdaptyUIPaywallView view,
AdaptyPaywallProduct? product,
AdaptyError? error) {
// product — AdaptyPaywallProduct?:
product?.vendorProductId; // 'premium_monthly'
if (error == null) {
// navigation succeeded
} else {
// error — AdaptyError:
error.code; // AdaptyErrorCode.networkFailed (2005)
error.message; // 'Network request failed'
error.detail; // platform-specific underlying error, or null
}
} Achat échoué
Cette méthode est invoquée lorsqu’un achat échoue (par exemple, en raison de problèmes de paiement ou d’erreurs réseau). Elle ne se déclenche pas pour les annulations initiées par l’utilisateur ni pour les transactions en attente — celles-ci sont gérées par paywallViewDidFinishPurchase :
void paywallViewDidFailPurchase(AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyError error) {
}Exemple d’événement (Cliquez pour développer)
void paywallViewDidFailPurchase(AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyError error) {
// product — AdaptyPaywallProduct:
product.vendorProductId; // 'premium_monthly'
// error — AdaptyError:
error.code; // AdaptyErrorCode.productPurchaseFailed (1006)
error.message; // 'Product purchase failed.'
error.detail; // platform-specific underlying error, or null
} Restauration initiée
Si un utilisateur lance le processus de restauration, cette méthode sera appelée :
void paywallViewDidStartRestore(AdaptyUIPaywallView view) {
}Restauration réussie
Si la restauration d’un achat réussit, cette méthode sera invoquée :
void paywallViewDidFinishRestore(AdaptyUIPaywallView view, AdaptyProfile profile) {
}Exemple d’événement (Cliquez pour développer)
void paywallViewDidFinishRestore(AdaptyUIPaywallView view, AdaptyProfile profile) {
// profile — AdaptyProfile:
profile.accessLevels['premium']?.isActive; // true
profile.accessLevels['premium']?.expiresAt; // DateTime(2027, 2, 15, 10, 30)
profile.subscriptions['premium_monthly']?.isActive; // true
profile.subscriptions['premium_monthly']?.expiresAt; // DateTime(2027, 2, 15, 10, 30)
} Nous recommandons de fermer l’écran si l’utilisateur dispose du accessLevel requis. Consultez la rubrique Statut d’abonnement pour savoir comment le vérifier, et la rubrique Répondre aux actions des boutons pour savoir comment fermer un écran de paywall.
Échec de la restauration
Si la restauration d’un achat échoue, cette méthode sera invoquée :
void paywallViewDidFailRestore(AdaptyUIPaywallView view, AdaptyError error) {
}Exemple d’événement (Cliquez pour agrandir)
void paywallViewDidFailRestore(AdaptyUIPaywallView view, AdaptyError error) {
// error — AdaptyError:
error.code; // AdaptyErrorCode.receiveRestoredTransactionsFailed (1011)
error.message; // 'Error occurred in the process of restoring purchases.'
error.detail; // platform-specific underlying error, or null
} Récupération et rendu des données
Erreurs de chargement des produits
Si vous ne transmettez pas le tableau de produits lors de l’initialisation, AdaptyUI récupère lui-même les objets nécessaires depuis le serveur. Si cette opération échoue, AdaptyUI signale l’erreur en invoquant cette méthode :
void paywallViewDidFailLoadingProducts(AdaptyUIPaywallView view, AdaptyError error) {
}Exemple d’événement (Cliquez pour développer)
void paywallViewDidFailLoadingProducts(AdaptyUIPaywallView view, AdaptyError error) {
// error — AdaptyError:
error.code; // AdaptyErrorCode.productRequestFailed (1002)
error.message; // 'Unable to fetch available In-App Purchase products at the moment.'
error.detail; // platform-specific underlying error, or null
} Erreurs de rendu
Si une erreur survient lors du rendu de l’interface, elle sera signalée en appelant cette méthode. Par défaut (depuis v3.15.2), le paywall est automatiquement fermé en cas d’erreur de rendu, mais vous pouvez remplacer ce comportement si nécessaire.
void paywallViewDidFailRendering(AdaptyUIPaywallView view, AdaptyError error) {
// Default behavior: view.dismiss()
// Override with custom logic if needed, for example:
// - Log the error
// - Show an error message to the user
}Exemple d’événement (Cliquer pour développer)
void paywallViewDidFailRendering(AdaptyUIPaywallView view, AdaptyError error) {
// error — AdaptyError:
error.code; // AdaptyErrorCode.jsException (4105)
error.message; // 'An exception was thrown from JS during AdaptyUI flow execution.'
error.detail; // platform-specific underlying error, or null
// Default behavior: view.dismiss()
} Dans une situation normale, ces erreurs ne devraient pas se produire. Si vous en rencontrez une, merci de nous en informer.