Gérer les événements de flow et de paywall - Unity
Ce guide couvre la gestion des événements pour les achats, les restaurations, la sélection de produits et le rendu des flows. Vous devez également implémenter la gestion des boutons (fermeture du flow, ouverture de liens, etc.). Consultez notre guide sur la gestion des actions de flow pour plus de détails.
Les flows et paywalls configurés avec le Flow Builder ou 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 comprennent les pressions sur des boutons (boutons de fermeture, URLs, sélections de produits, etc.) ainsi que des notifications sur les actions liées aux achats. Découvrez ci-dessous comment réagir à ces événements.
Vous souhaitez voir un exemple concret d’intégration du SDK Adapty dans une application mobile ? Consultez nos exemples d’applications, qui illustrent la configuration complète, notamment l’affichage des paywalls, les achats et d’autres fonctionnalités de base.
Gestion des événements
Pour contrôler ou surveiller les processus qui se déroulent sur l’écran du flow dans votre application mobile, implémentez l’interface IAdaptyFlowsEventsListener et enregistrez-la avec Adapty.SetFlowsEventsListener() :
using UnityEngine;
using AdaptySDK;
public class FlowEventsHandler : MonoBehaviour, IAdaptyFlowsEventsListener
{
void Start()
{
Adapty.SetFlowsEventsListener(this);
}
// Implement all interface methods below
}Ces méthodes sont l’endroit où vous ajoutez votre logique personnalisée pour répondre aux événements du flow. Le SDK n’applique aucun comportement par défaut : un achat réussi ou une erreur ne ferme pas la vue automatiquement — appelez view.Dismiss(...) vous-même au moment opportun.
Événements générés par l’utilisateur
Flow apparu
Invoqué lorsque la vue du flow s’affiche à l’écran.
Sur iOS, également invoqué lorsqu’un utilisateur appuie sur le bouton de paywall web dans un flow, et qu’un paywall web s’ouvre dans un navigateur intégré.
public void FlowViewDidAppear(AdaptyUIFlowView view) { }Flow disparu
Invoqué lorsque la vue du flow est fermée depuis l’écran.
Sur iOS, également invoqué lorsqu’un paywall web ouvert depuis un flow dans un navigateur intégré disparaît de l’écran.
public void FlowViewDidDisappear(AdaptyUIFlowView view) { }Sélection de produit
Invoqué lorsqu’un produit est sélectionné pour achat (par l’utilisateur ou par le système).
public void FlowViewDidSelectProduct(
AdaptyUIFlowView view,
string productId
) { }Exemple d’événement (cliquer pour développer)
{
"productId": "premium_monthly"
}Achat démarré
Invoqué lorsqu’un utilisateur lance le processus d’achat.
public void FlowViewDidStartPurchase(
AdaptyUIFlowView view,
AdaptyPaywallProduct product
) { }En mode Observer, les achats démarrés depuis un flow sont transmis à votre IAdaptyUIObserverModeResolver à la place.
Exemple d’événement (Cliquer pour développer)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}Achat réussi, annulé ou en attente
Si l’achat réussit, que l’utilisateur annule son achat, ou que l’achat est en attente, cette méthode sera invoquée. Les annulations de l’utilisateur et les paiements en attente (par exemple, approbation parentale requise) déclenchent cette méthode, et non FlowViewDidFailPurchase.
Le flow reste ouvert après l’achat jusqu’à ce que vous le fermiez vous-même, alors appelez view.Dismiss(...) dès que l’utilisateur obtient l’accès :
public void FlowViewDidFinishPurchase(
AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchasedResult
) {
switch (purchasedResult.Type) {
case AdaptyPurchaseResultType.Success:
// Check if user has access to premium features
if (purchasedResult.Profile != null
&& purchasedResult.Profile.AccessLevels.TryGetValue("premium", out var premium)
&& premium.IsActive) {
view.Dismiss(null);
}
break;
case AdaptyPurchaseResultType.Pending:
// Handle pending purchase (e.g., user will pay offline with cash)
break;
case AdaptyPurchaseResultType.UserCancelled:
// Handle user cancellation
break;
default:
break;
}
}Exemples d’événements (cliquez pour développer)
// Successful purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "Success",
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
}
}
}
}
// Cancelled purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "UserCancelled"
}
}
// Pending purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "Pending"
}
}Nous recommandons de fermer l’écran du flow en cas d’achat réussi.
Échec d’achat
Si un achat échoue en raison d’une erreur, cette méthode sera appelée. Cela inclut les erreurs StoreKit/Google Play Billing (restrictions de paiement, produits invalides, échecs réseau), les échecs de vérification de transaction et les erreurs système. Notez que les annulations par l’utilisateur déclenchent FlowViewDidFinishPurchase avec un résultat annulé, et les paiements en attente ne déclenchent pas cette méthode.
public void FlowViewDidFailPurchase(
AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyError error
) { }Exemple d’événement (Cliquez pour développer)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "purchase_failed",
"message": "Purchase failed due to insufficient funds",
"details": {
"underlyingError": "Insufficient funds in account"
}
}
}Restauration démarrée
Déclenché lorsqu’un utilisateur lance le processus de restauration :
public void FlowViewDidStartRestore(AdaptyUIFlowView view) { }Restauration réussie
Appelé lorsque la restauration des achats réussit. Le flow reste ouvert après la restauration jusqu’à ce que vous le fermiez :
public void FlowViewDidFinishRestore(
AdaptyUIFlowView view,
AdaptyProfile profile
) {
// Check if user has access to premium features
if (profile.AccessLevels.TryGetValue("premium", out var premium) && premium.IsActive) {
view.Dismiss(null);
}
}Exemple d’événement (cliquer pour développer)
{
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
},
"subscriptions": [
{
"vendorProductId": "premium_monthly",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
]
}
}Nous recommandons de fermer l’écran si l’utilisateur possède le accessLevel requis. Consultez la rubrique Statut de l’abonnement pour savoir comment le vérifier.
Échec de la restauration
Invoqué lorsque la restauration des achats échoue :
public void FlowViewDidFailRestore(
AdaptyUIFlowView view,
AdaptyError error
) { }Exemple d’événement (Cliquez pour développer)
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}Navigation de paiement web terminée
Après une tentative d’ouverture d’un paywall web pour un achat (qu’elle ait réussi ou échoué), cette méthode sera invoquée :
public void FlowViewDidFinishWebPaymentNavigation(
AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyError error
) { }Paramètres :
product: Le produit pour lequel le paywall web a été ouvert (ou tenté), ounullerror:nullsi le paywall web s’est ouvert avec succès, ou unAdaptyErroren cas d’échec
Exemples d’événements (Cliquez pour développer)
// Successful navigation
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": null
}
// Failed navigation
{
"product": null,
"error": {
"code": "wrong_param",
"message": "Current method is not available for this product",
"details": {
"underlyingError": "Product not configured for web purchases"
}
}
}Récupération et rendu des données
Erreurs de chargement des produits
Déclenché quand le chargement des produits échoue et fournit une AdaptyError. Si vous n’avez pas passé le tableau de produits lors de l’initialisation, AdaptyUI récupérera lui-même les objets nécessaires auprès du serveur. Cette opération peut échouer, et AdaptyUI signalera l’erreur en appelant cette méthode :
public void FlowViewDidFailLoadingProducts(
AdaptyUIFlowView view,
AdaptyError error
) { }Exemple d’événement (Cliquer pour agrandir)
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}Erreurs de rendu et d’exécution
Si une erreur survient lors du rendu de l’interface, ou qu’une autre erreur d’exécution non liée à un achat se produit, elle sera signalée par cette méthode. La vue n’est pas fermée automatiquement — appelez view.Dismiss(...) vous-même si nécessaire :
public void FlowViewDidReceiveError(
AdaptyUIFlowView view,
AdaptyError error
) { }Exemple d’événement (Cliquez pour développer)
{
"error": {
"code": "rendering_failed",
"message": "Failed to render flow interface",
"details": {
"underlyingError": "Invalid flow configuration"
}
}
}En situation normale, ces erreurs ne devraient pas se produire. Si vous en rencontrez une, merci de nous en informer.
Événements analytiques
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, donc laissez le corps de la méthode vide — IAdaptyFlowsEventsListener est une interface C#, la méthode doit tout de même être présente :
public void FlowViewDidReceiveAnalyticEvent(
AdaptyUIFlowView view,
string name,
IDictionary<string, object> @params
) { }Gérer les requêtes système
Le IAdaptyUISystemRequestsHandler (enregistré via Adapty.SetSystemRequestsHandler(...)) est réservé aux requêtes système provenant d’un flow : invites de permission OS (comme les notifications push ou l’accès à la caméra) 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.
Navigation
Bouton retour système Android
Le bouton retour système Android (ou le geste de retour) est transmis à FlowViewDidPerformAction sous forme d’action SystemBack et ne ferme pas le flow par lui-même — l’utilisateur quitte le flow via un chemin que vous définissez, comme un bouton Close ou une action on_device_back dans le builder. Si vous souhaitez que le bouton retour système ferme le flow, gérez l’action vous-même :
public void FlowViewDidPerformAction(
AdaptyUIFlowView view,
AdaptyUIUserAction action
) {
switch (action.Type) {
case AdaptyUIUserActionType.Close:
case AdaptyUIUserActionType.SystemBack:
view.Dismiss(null);
break;
default:
// handle other events
break;
}
}Consultez le guide sur la gestion des actions de flow pour la liste complète des actions.
Ce guide couvre la gestion des événements liés aux achats, aux restaurations, à la sélection de produits et au rendu 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 des événements auxquels votre application peut réagir. Ces événements incluent les appuis sur des boutons (boutons de fermeture, URL, sélections de produits, etc.) ainsi que des notifications sur les actions liées aux achats effectuées sur le paywall. Découvrez ci-dessous comment réagir à ces événements.
Ce guide s’adresse uniquement aux paywalls du nouveau Paywall Builder, qui nécessitent le SDK Adapty v3.3.0 ou ultérieur.
Vous souhaitez voir un exemple concret d’intégration du SDK Adapty dans une application mobile ? Consultez nos exemples d’applications, qui illustrent la configuration complète, notamment l’affichage des paywalls, les achats et d’autres fonctionnalités de base.
Gestion des événements
Pour contrôler ou surveiller les processus qui se déroulent sur l’écran du paywall dans votre application mobile, implémentez l’interface AdaptyPaywallsEventsListener :
using UnityEngine;
using AdaptySDK;
public class PaywallEventsHandler : MonoBehaviour, AdaptyPaywallsEventsListener
{
void Start()
{
Adapty.SetPaywallsEventsListener(this);
}
// Implement all required interface methods below
}Événements générés par l’utilisateur
Paywall apparu
Déclenché lorsque la vue du paywall s’affiche à l’écran.
Sur iOS, également déclenché 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.
public void PaywallViewDidAppear(AdaptyUIPaywallView view) { }Paywall disparu
Déclenché lorsque la vue du paywall est fermée et disparaît de l’écran.
Sur iOS, également invoqué lorsqu’un web paywall ouvert depuis un paywall dans un navigateur intégré disparaît de l’écran.
public void PaywallViewDidDisappear(AdaptyUIPaywallView view) { }Sélection de produit
Invoqué lorsqu’un produit est sélectionné pour achat (par l’utilisateur ou par le système).
public void PaywallViewDidSelectProduct(
AdaptyUIPaywallView view,
string productId
) { }Exemple d’événement (Cliquer pour développer)
{
"productId": "premium_monthly"
}Achat démarré
Invoqué lorsqu’un utilisateur lance le processus d’achat.
public void PaywallViewDidStartPurchase(
AdaptyUIPaywallView view,
AdaptyPaywallProduct product
) { }Exemple d’événement (Cliquez pour développer)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}Achat réussi, annulé ou en attente
Si l’achat réussit, si l’utilisateur l’annule, ou si l’achat est en attente, cette méthode sera invoquée. Les annulations par l’utilisateur et les paiements en attente (par exemple, approbation parentale requise) déclenchent cette méthode, et non PaywallViewDidFailPurchase.
public void PaywallViewDidFinishPurchase(
AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchasedResult
) { }Exemples d’événements (cliquez pour développer)
// Successful purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "Success",
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
}
}
}
}
// Cancelled purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "UserCancelled"
}
}
// Pending purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "Pending"
}
}Nous vous recommandons de fermer l’écran dans ce cas.
Échec d’achat
Si un achat échoue en raison d’une erreur, cette méthode sera invoquée. Cela inclut les erreurs StoreKit/Google Play Billing (restrictions de paiement, produits invalides, échecs réseau), les échecs de vérification des transactions et les erreurs système. Notez que les annulations de l’utilisateur déclenchent PaywallViewDidFinishPurchase avec un résultat annulé, et les paiements en attente ne déclenchent pas cette méthode.
public void PaywallViewDidFailPurchase(
AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyError error
) { }Exemple d’événement (Cliquez pour développer)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "purchase_failed",
"message": "Purchase failed due to insufficient funds",
"details": {
"underlyingError": "Insufficient funds in account"
}
}
}Restauration démarrée
Déclenché lorsqu’un utilisateur lance le processus de restauration :
public void PaywallViewDidStartRestore(AdaptyUIPaywallView view) { }Restauration réussie
Invoqué lorsque la restauration des achats réussit :
public void PaywallViewDidFinishRestore(
AdaptyUIPaywallView view,
AdaptyProfile profile
) { }Exemple d’événement (Cliquez pour développer)
{
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
},
"subscriptions": [
{
"vendorProductId": "premium_monthly",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
]
}
}Nous vous recommandons de fermer l’écran si l’utilisateur possède le accessLevel requis. Consultez la rubrique Statut de l’abonnement pour savoir comment le vérifier.
Échec de la restauration
Déclenché en cas d’échec de la restauration des achats :
public void PaywallViewDidFailRestore(
AdaptyUIPaywallView view,
AdaptyError error
) { }Exemple d’événement (cliquer pour développer)
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}Navigation web de paiement terminée
Après avoir tenté d’ouvrir un paywall web pour un achat (qu’il ait réussi ou échoué), cette méthode sera invoquée :
public void PaywallViewDidFinishWebPaymentNavigation(
AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyError error
) { }Paramètres :
product: Le produit pour lequel le paywall web a été ouvert (ou tenté)error:nullsi le paywall web s’est ouvert avec succès, ou uneAdaptyErroren cas d’échec
Exemples d’événements (Cliquez pour développer)
// Successful navigation
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": null
}
// Failed navigation
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "wrong_param",
"message": "Current method is not available for this product",
"details": {
"underlyingError": "Product not configured for web purchases"
}
}
}Récupération et rendu des données
Erreurs de chargement des produits
Déclenché quand le chargement des produits échoue et fournit une AdaptyError. Si vous n’avez pas transmis le tableau de produits lors de l’initialisation, AdaptyUI récupèrera lui-même les objets nécessaires depuis le serveur. Cette opération peut échouer, et AdaptyUI signalera l’erreur en invoquant cette méthode :
public void PaywallViewDidFailLoadingProducts(
AdaptyUIPaywallView view,
AdaptyError error
) { }Exemple d’événement (Cliquez pour développer)
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}Erreurs de rendu
Invoqué lorsqu’une erreur survient pendant le rendu de l’interface et fournit AdaptyError :
public void PaywallViewDidFailRendering(
AdaptyUIPaywallView view,
AdaptyError error
) { }Exemple d’événement (Cliquez pour développer)
{
"error": {
"code": "rendering_failed",
"message": "Failed to render paywall interface",
"details": {
"underlyingError": "Invalid paywall configuration"
}
}
}Dans une situation normale, de telles erreurs ne devraient pas se produire, donc si vous en rencontrez une, veuillez nous en informer.