Intégrer la bibliothèque Google Play Billing à votre application

Cet article explique comment intégrer la bibliothèque Google Play Billing à votre application pour commencer à vendre des produits.

Cycle de vie d'un achat

Voici un parcours d'achat standard pour un achat ou un abonnement ponctuels.

  1. Montrez aux utilisateurs ce qu'ils peuvent acheter.
  2. Lancez le parcours d'achat pour que l'utilisateur accepte l'achat.
  3. Vérifiez l'achat sur votre serveur.
  4. Fournissez le contenu à l'utilisateur.
  5. Confirmez la livraison du contenu. Pour les produits consommables, utilisez l'achat afin que l'utilisateur puisse l'acheter à nouveau.

Les abonnements sont renouvelés automatiquement jusqu'à ce qu'ils soient résiliés. Un abonnement peut présenter les états suivants :

  • Actif: l'utilisateur est en règle et a accès à l'abonnement.
  • Annulé: l'utilisateur a résilié l'abonnement, mais a toujours accès jusqu'à sa date d'expiration.
  • En délai de grâce: l'utilisateur a rencontré un problème de paiement, mais a toujours accès à l'élément pendant que Google tente à nouveau le mode de paiement.
  • En attente: l'utilisateur a rencontré un problème de paiement et n'y a plus accès pendant que Google tente à nouveau le mode de paiement.
  • Suspendu: l'utilisateur a suspendu son accès et n'y a pas accès tant qu'il ne l'a pas réactivé.
  • Expiré: l'utilisateur a résilié son abonnement et n'y a plus accès. L'utilisateur est considéré comme perdu après l'expiration.

Initialiser une connexion à Google Play

La première étape pour intégrer le système de facturation de Google Play consiste à ajouter la bibliothèque Google Play Billing à votre application et à initialiser une connexion.

Ajouter la dépendance de la bibliothèque Google Play Billing

Ajoutez la dépendance Google Play Billing au fichier build.gradle de votre application, comme indiqué ci-dessous :

Groovy

dependencies {
    def billing_version = "7.0.0"

    implementation "com.android.billingclient:billing:$billing_version"
}

Kotlin

dependencies {
    val billing_version = "7.0.0"

    implementation("com.android.billingclient:billing:$billing_version")
}

Si vous utilisez Kotlin, le module KTX de la bibliothèque Google Play Billing contient des extensions et des coroutines Kotlin qui vous permettent d'écrire du code Kotlin idiomatique lors de l'utilisation de la bibliothèque Google Play Billing. Pour inclure ces extensions dans votre projet, ajoutez la dépendance suivante au fichier build.gradle de votre application, comme indiqué ci-dessous :

Groovy

dependencies {
    def billing_version = "7.0.0"

    implementation "com.android.billingclient:billing-ktx:$billing_version"
}

Kotlin

dependencies {
    val billing_version = "7.0.0"

    implementation("com.android.billingclient:billing-ktx:$billing_version")
}

Initialiser un BillingClient

Une fois que vous avez ajouté une dépendance à la bibliothèque Google Play Billing, vous devez initialiser une instance BillingClient. BillingClient est l'interface principale de communication entre la bibliothèque Google Play Billing et le reste de votre application. BillingClient fournit des méthodes pratiques, synchrones et asynchrones, utiles pour de nombreuses opérations de facturation courantes. Veuillez noter les points suivants:

  • Nous vous recommandons d'avoir une connexion BillingClient active simultanément pour éviter plusieurs rappels PurchasesUpdatedListener liés à un seul événement.
  • Nous vous recommandons d'établir une connexion pour BillingClient lorsque votre application est lancée ou passe au premier plan pour vous assurer qu'elle traite les achats dans les meilleurs délais. Pour ce faire, utilisez ActivityLifecycleCallbacks enregistré par registerActivityLifecycleCallbacks et écoutez onActivityResumed pour initialiser une connexion lorsque vous détectez pour la première fois une activité reprise. Pour en savoir plus sur la raison pour laquelle vous devez suivre cette bonne pratique, consultez la section sur le traitement des achats. N'oubliez pas non plus de mettre fin à la connexion lorsque votre application est fermée.

Pour créer un BillingClient, utilisez newBuilder. Vous pouvez transmettre n'importe quel contexte à newBuilder(), et BillingClient l'utilise pour obtenir un contexte d'application. Vous n'avez donc plus à vous soucier des fuites de mémoire. Pour recevoir des mises à jour pour les achats, vous devez également appeler setListener, en transmettant une référence à PurchasesUpdatedListener. Cet écouteur reçoit des mises à jour pour tous les achats dans votre application.

Kotlin

private val purchasesUpdatedListener =
   PurchasesUpdatedListener { billingResult, purchases ->
       // To be implemented in a later section.
   }

private var billingClient = BillingClient.newBuilder(context)
   .setListener(purchasesUpdatedListener)
   // Configure other settings.
   .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // To be implemented in a later section.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    // Configure other settings.
    .build();

Se connecter à Google Play

Après avoir créé un BillingClient, vous devez établir une connexion à Google Play.

Pour vous connecter à Google Play, appelez startConnection. Le processus de connexion est asynchrone. Vous devez implémenter BillingClientStateListener pour recevoir un rappel une fois que la configuration du client est terminée et est prête à envoyer d'autres requêtes.

Vous devez également mettre en œuvre une logique de nouvelle tentative pour gérer les connexions perdues à Google Play. Pour implémenter une logique de nouvelle tentative, contournez la méthode de rappel onBillingServiceDisconnected() et assurez-vous que BillingClient appelle la méthode startConnection() pour vous reconnecter à Google Play avant d'envoyer d'autres requêtes.

L'exemple suivant montre comment démarrer une connexion et tester si elle est fonctionnelle :

Kotlin

billingClient.startConnection(object : BillingClientStateListener {
    override fun onBillingSetupFinished(billingResult: BillingResult) {
        if (billingResult.responseCode ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    override fun onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
})

Java

billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});

Afficher les produits disponibles à l'achat

Une fois la connexion à Google Play établie, vous pouvez interroger les produits disponibles et les présenter à vos utilisateurs.

L'interrogation des informations détaillées sur un produit est une étape importante avant de présenter vos produits aux utilisateurs, car elle renvoie des informations localisées sur le produit. Pour les abonnements, assurez-vous que l'affichage du produit respecte toutes les règles de Google Play.

Pour interroger les informations sur un produit intégré, appelez queryProductDetailsAsync.

Pour gérer le résultat de l'opération asynchrone, vous devez également spécifier un écouteur qui implémente l'interface ProductDetailsResponseListener. Vous pouvez ensuite contourner onProductDetailsResponse, qui avertit l'écouteur lorsque la requête est terminée, comme illustré dans l'exemple suivant :

Kotlin

val queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build()

billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
    billingResult,
    productDetailsList ->
      // check billingResult
      // process returned productDetailsList
}

Java

QueryProductDetailsParams queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build();

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
        public void onProductDetailsResponse(BillingResult billingResult,
                List<ProductDetails> productDetailsList) {
            // check billingResult
            // process returned productDetailsList
        }
    }
)

Lorsque vous interrogez les informations détaillées sur un produit, transmettez une instance de QueryProductDetailsParams qui spécifie une liste de chaînes d'ID produit créées dans la Google Play Console avec un élément ProductType. ProductType peut être de type ProductType.INAPP pour des produits ponctuels ou de type ProductType.SUBS pour les abonnements.

Interroger avec des extensions Kotlin

Si vous utilisez des extensions Kotlin, vous pouvez interroger les informations détaillées sur un produit intégré en appelant la fonction d'extension queryProductDetails().

queryProductDetails() exploite les coroutines Kotlin. Vous n'avez donc pas besoin de définir un écouteur distinct. Au lieu de cela, la fonction est suspendue jusqu'à la fin de l'interrogation, après quoi vous pouvez traiter le résultat :

suspend fun processPurchases() {
    val productList = listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("product_id_example")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )
    val params = QueryProductDetailsParams.newBuilder()
    params.setProductList(productList)

    // leverage queryProductDetails Kotlin extension function
    val productDetailsResult = withContext(Dispatchers.IO) {
        billingClient.queryProductDetails(params.build())
    }

    // Process the result.
}

Dans de rares cas, certains appareils ne peuvent pas prendre en charge ProductDetails ni queryProductDetailsAsync(), généralement en raison de versions obsolètes des services Google Play. Pour assurer la compatibilité dans ce scénario, découvrez comment utiliser les fonctionnalités de rétrocompatibilité dans le guide de migration de la bibliothèque Play Billing 5.

Traiter le résultat

La bibliothèque Google Play Billing stocke les résultats de la requête dans un List d'objets ProductDetails. Vous pouvez ensuite appeler diverses méthodes sur chaque objet ProductDetails de la liste pour afficher des informations pertinentes sur un produit intégré, telles que son prix ou sa description. Pour afficher des informations détaillées disponibles sur le produit, consultez la liste des méthodes de la classe ProductDetails.

Avant de proposer un article à la vente, vérifiez que l'utilisateur n'en est pas déjà le propriétaire. Si l'utilisateur dispose d'un consommable qui se trouve toujours dans sa bibliothèque d'articles, il doit le consommer avant de pouvoir l'acheter à nouveau.

Avant de proposer un abonnement, vérifiez que l'utilisateur n'est pas déjà abonné. Notez également ce qui suit :

  • queryProductDetailsAsync() renvoie les détails des produits sur abonnement et un maximum de 50 offres par abonnement.
  • queryProductDetailsAsync() renvoie uniquement les offres pour lesquelles l'utilisateur est éligible. Si l'utilisateur tente d'acheter une offre pour laquelle il n'est pas éligible (par exemple, si l'application affiche une liste obsolète d'offres éligibles), Google Play informe l'utilisateur qu'il n'est pas éligible. L'utilisateur peut alors choisir d'acheter le forfait de base à la place.

Lancer le parcours d'achat

Pour démarrer une demande d'achat depuis votre application, appelez la méthode launchBillingFlow() à partir du thread principal de votre application. Cette méthode transmet une référence à un objet BillingFlowParams contenant l'objet ProductDetails approprié obtenu lors de l'appel de queryProductDetailsAsync. Pour créer un objet BillingFlowParams, utilisez la classe BillingFlowParams.Builder.

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;

val productDetailsParamsList = listOf(
    BillingFlowParams.ProductDetailsParams.newBuilder()
        // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
        .setProductDetails(productDetails)
        // For One-time products, "setOfferToken" method shouldn't be called.
        // For subscriptions, to get an offer token, call ProductDetails.subscriptionOfferDetails()
        // for a list of offers that are available to the user
        .setOfferToken(selectedOfferToken)
        .build()
)

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build()

// Launch the billing flow
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

Java

// An activity reference from which the billing flow will be launched.
Activity activity = ...;

ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
             // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // For one-time products, "setOfferToken" method shouldn't be called.
            // For subscriptions, to get an offer token, call
            // ProductDetails.subscriptionOfferDetails() for a list of offers
            // that are available to the user.
            .setOfferToken(selectedOfferToken)
            .build()
    );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

La méthode launchBillingFlow() renvoie l'un des codes de réponse recensés dans BillingClient.BillingResponseCode. Assurez-vous que ce résultat ne comporte aucune erreur lors du lancement du parcours d'achat. Un BillingResponseCode de type OK indique un lancement réussi.

Lors d'un appel réussi à launchBillingFlow(), le système affiche l'écran d'achat Google Play. La figure 1 illustre l'écran d'achat d'un abonnement :

L&#39;écran d&#39;achat Google Play affiche un abonnement disponible à l&#39;achat
Figure 1 : L'écran d'achat de Google Play affiche un abonnement disponible à l'achat.

Google Play appelle onPurchasesUpdated() pour transmettre le résultat de l'opération d'achat à un écouteur qui implémente l'interface PurchasesUpdatedListener. L'écouteur est spécifié à l'aide de la méthode setListener() lors de l'initialisation du BillingClient.

Vous devez implémenter onPurchasesUpdated() pour gérer les éventuels codes de réponse. L'exemple suivant montre comment contourner onPurchasesUpdated() :

Kotlin

override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
   if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) {
       for (purchase in purchases) {
           // Process the purchase as described in the next section.
       }
   } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) {
       // Handle an error caused by a user canceling the purchase flow.
   } else {
       // Handle any other error codes.
   }
}

Java

@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
    if (billingResult.getResponseCode() == BillingResponseCode.OK
        && purchases != null) {
        for (Purchase purchase : purchases) {
            // Process the purchase as described in the next section.
        }
    } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
        // Handle an error caused by a user canceling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

Un achat réussi génère un écran de confirmation d'achat Google Play semblable à la figure 2.

Écran de confirmation d&#39;achat de Google Play
Figure 2 : Écran de confirmation d'achat de Google Play.

Un achat réussi génère également un jeton d'achat, c'est-à-dire un identifiant unique qui représente l'utilisateur et l'ID du produit intégré qu'il a acheté. Vos applications peuvent stocker le jeton d'achat localement, mais nous vous recommandons vivement de le transmettre à votre serveur backend sécurisé, où vous pourrez ensuite vérifier l'achat et vous protéger contre la fraude. Ce processus est décrit plus en détail dans la section Détecter et traiter les achats.

L'utilisateur reçoit également un reçu par e-mail contenant un ID de commande ou un ID unique de la transaction. Les utilisateurs reçoivent un e-mail contenant un ID de commande unique pour chaque achat de produit ponctuel, ainsi que pour l'achat initial de l'abonnement et les renouvellements automatiques récurrents ultérieurs. Vous pouvez utiliser cet ID de commande pour gérer les remboursements dans la Google Play Console.

Indiquer un prix personnalisé

Si votre application peut être distribuée aux utilisateurs de l'Union européenne, utilisez la méthode setIsOfferPersonalized() lorsque vous appelez launchBillingFlow pour indiquer aux utilisateurs que le prix d'un article a été personnalisé à l'aide de la prise de décision automatisée.

Écran d&#39;achat Google Play indiquant que le prix a été personnalisé pour l&#39;utilisateur
Figure 3 : Écran d'achat Google Play indiquant que le prix a été personnalisé pour l'utilisateur.

Vous devez consulter Art. 6 (1) (ea) de la directive sur les droits des consommateurs (2011/83/UE) pour déterminer si le prix que vous proposez aux utilisateurs est personnalisé.

setIsOfferPersonalized() accepte une entrée booléenne. Si true, l'interface utilisateur Google Play indique que le prix a été personnalisé. Si false, l'interface utilisateur omet ce message. La valeur par défaut est false.

Pour obtenir plus d'informations, consultez le Centre d'aide consommateur.

Associer des identifiants utilisateur

Lorsque vous lancez le parcours d'achat, votre application peut associer tous les identifiants utilisateur dont vous disposez pour l'utilisateur effectuant l'achat à l'aide de obfuscatedAccountId ou obfuscatedProfileId. Un exemple d'identifiant peut être une version obscurcie de la connexion de l'utilisateur dans votre système. Définir ces paramètres peut aider Google à détecter les fraudes. De plus, cela peut vous aider à vous assurer que les achats sont attribués au bon utilisateur, comme indiqué dans la section Accorder des droits d'accès aux utilisateurs.

Détecter et traiter les achats

La détection et le traitement d'un achat décrits dans cette section s'appliquent à tous les types d'achats, y compris les achats hors application tels que l'utilisation d'offres promotionnelles.

Votre application détecte les nouveaux achats et les achats en attente finalisés de l'une des manières suivantes:

  1. Lorsque onPurchasesUpdated est appelé en raison de l'appel de launchBillingFlow par votre application (comme indiqué dans la section précédente) ou si votre application s'exécute avec une connexion active à la bibliothèque Billing lorsqu'un achat est effectué en dehors de votre application ou qu'un achat en attente est finalisé. Par exemple, un membre de la famille approuve un achat en attente sur un autre appareil.
  2. Lorsque votre application appelle queryPurchasesAsync pour interroger les achats de l'utilisateur.

Pour le cas 1, onPurchasesUpdated est automatiquement appelé pour les nouveaux achats ou les achats terminés tant que votre application est en cours d'exécution et qu'elle dispose d'une connexion active à la bibliothèque de facturation Google Play. Si votre application n'est pas en cours d'exécution ou si elle n'a pas de connexion active à la bibliothèque Google Play Billing, onPurchasesUpdated ne sera pas appelé. N'oubliez pas qu'il est recommandé que votre application essaie de maintenir une connexion active tant qu'elle est au premier plan pour s'assurer qu'elle reçoit les mises à jour d'achats en temps opportun.

Pour le point 2, vous devez appeler BillingClient.queryPurchasesAsync() pour vous assurer que votre application traite tous les achats. Nous vous recommandons de le faire lorsque votre application établit une connexion avec la bibliothèque Google Play Billing (ce qui est recommandé lorsque votre application est lancée ou passe au premier plan, comme indiqué dans la section Initialiser un BillingClient). Pour ce faire, appelez queryPurchasesAsync lorsque vous recevez un résultat positif pour onServiceConnected. Il est essentiel de suivre cette recommandation pour gérer les événements et les situations suivants:

  • Problèmes de réseau lors de l'achat: un utilisateur peut effectuer un achat et recevoir la confirmation de Google, mais son appareil perd la connectivité réseau avant que son appareil et votre application ne reçoivent une notification de l'achat via PurchasesUpdatedListener.
  • Plusieurs appareils: un utilisateur peut acheter un article sur un appareil, puis s'attendre à pouvoir le voir lorsqu'il change d'appareil.
  • Gérer les achats effectués en dehors de votre application: certains achats, par exemple l'utilisation d'offres promotionnelles, peuvent être effectués en dehors de votre application.
  • Gestion des transitions d'état des achats: un utilisateur peut effectuer le paiement d'un achat EN ATTENTE lorsque votre application n'est pas en cours d'exécution et s'attendre à recevoir une confirmation de l'achat lorsqu'il ouvre votre application.

Une fois que votre application détecte un nouvel achat ou un achat terminé, elle doit:

  • Vérifier l'achat.
  • Accordez du contenu à l'utilisateur pour les achats effectués.
  • Informez l'utilisateur.
  • Informer Google que votre application a traité les achats finalisés

Ces étapes sont décrites en détail dans les sections suivantes, suivies d'une section récapitulative.

Valider l'achat

Votre application doit toujours vérifier les achats pour s'assurer qu'ils sont légitimes avant d'accorder des avantages à un utilisateur. Pour ce faire, suivez les consignes décrites dans la section Vérifier les achats avant d'accorder des droits. Votre application ne doit continuer à traiter l'achat et accorder des droits d'accès à l'utilisateur qu'après avoir vérifié l'achat, comme indiqué dans la section suivante.

Accorder un droit d'accès à l'utilisateur

Une fois que votre application a validé un achat, elle peut continuer à accorder le droit d'accès à l'utilisateur et l'en informer. Avant d'accorder un droit d'accès, assurez-vous que votre application vérifie que l'état de l'achat est PURCHASED. Si l'achat est en attente, votre application doit avertir l'utilisateur qu'il doit encore effectuer des actions pour finaliser l'achat avant que le droit d'accès ne lui soit accordé. N'accordez des droits d'accès que lorsque l'état de l'achat passe de "PENDING" (En attente) à "SUCCESS" (Réussi). Pour en savoir plus, consultez Gérer les transactions en attente.

Si vous avez associé des identifiants utilisateur à l'achat, comme indiqué dans la section Associer des identifiants utilisateur, vous pouvez les récupérer et les utiliser pour les attribuer à l'utilisateur approprié dans votre système. Cette technique est utile pour rapprocher les achats pour lesquels votre application a peut-être perdu le contexte de l'utilisateur concerné. Notez que ces identifiants ne seront pas définis pour les achats effectués en dehors de votre application. Dans ce cas, votre application peut accorder le droit d'accès à l'utilisateur connecté ou inviter l'utilisateur à sélectionner un compte de son choix.

Informer l'utilisateur

Une fois les droits d'accès accordés à l'utilisateur, votre application doit afficher une notification pour confirmer l'achat. Cela permet à l'utilisateur de savoir si l'achat a bien été effectué, ce qui pourrait l'amener à cesser d'utiliser votre application, à contacter l'assistance utilisateur ou à s'en plaindre sur les réseaux sociaux. Sachez que votre application peut détecter des mises à jour d'achats à tout moment pendant le cycle de vie de votre application. Par exemple, un parent approuve un achat en attente sur un autre appareil. Dans ce cas, votre application peut retarder l'envoi de la notification à l'utilisateur à un moment opportun. Voici quelques exemples de cas où un délai est approprié:

  • En plein milieu d'un jeu ou de cinématiques, l'affichage d'un message peut distraire l'utilisateur. Dans ce cas, vous devez prévenir l'utilisateur une fois la partie terminée.
  • Au cours du tutoriel de départ et de la configuration d'un jeu. Par exemple, un utilisateur peut avoir effectué un achat en dehors de votre application avant de l'installer. Nous vous recommandons d'informer immédiatement les nouveaux utilisateurs de la récompense reçue dès qu'ils ouvrent le jeu ou lors de la configuration initiale de l'utilisateur. Si votre application nécessite que l'utilisateur crée un compte ou se connecte avant de lui accorder des droits d'accès, nous vous recommandons de lui indiquer les étapes à suivre pour réclamer son achat. Cette étape est essentielle, car les achats sont remboursés au bout de trois jours si votre application ne les a pas traités.

Lorsque vous informez l'utilisateur d'un achat, Google Play recommande les mécanismes suivants:

  • Afficher une boîte de dialogue dans l'application.
  • Transmettre le message dans une zone de message dans l'application et indiquer clairement qu'un nouveau message s'y trouve.
  • Utiliser un message de notification de l'OS.

La notification doit informer l'utilisateur du bénéfice qu'il a reçu. (par exemple, "Vous avez acheté 100 pièces d'or !"). De plus, si l'achat est le résultat d'un avantage d'un programme tel que Play Pass, votre application le communique à l'utilisateur. (par exemple, "Articles reçus ! Vous venez de recevoir 100 gemmes avec Play Pass. Continuer." Chaque programme peut fournir des conseils sur le texte recommandé à afficher aux utilisateurs pour communiquer les avantages.

Informer Google que l'achat a été traité

Une fois que votre application a accordé des droits d'accès à l'utilisateur et l'a informé de la réussite de la transaction, elle doit informer Google que l'achat a bien été traité. Pour ce faire, vous devez confirmer l'achat dans un délai de trois jours pour vous assurer qu'il n'est pas automatiquement remboursé et que le droit d'accès n'est pas révoqué. Le processus de confirmation des différents types d'achats est décrit dans les sections suivantes.

Produits consommables

Pour les consommables, si votre application dispose d'un backend sécurisé, nous vous recommandons d'utiliser Purchases.products:consume pour consommer de manière fiable les achats. Assurez-vous que l'achat n'a pas déjà été consommé en vérifiant le consumptionState à partir du résultat de l'appel de Purchases.products:get. Si votre application est côté client uniquement sans backend, utilisez consumeAsync() à partir de la bibliothèque Google Play Billing. Les deux méthodes répondent aux exigences de confirmation et indiquent que votre application a accordé des droits à l'utilisateur. Ces méthodes permettent également à votre application de proposer à nouveau à la vente le produit ponctuel correspondant au jeton d'achat indiqué. Avec consumeAsync(), vous devez également transmettre un objet qui implémente l'interface ConsumeResponseListener. Cet objet gère le résultat de l'opération de consommation. Vous pouvez contourner la méthode onConsumeResponse(), que la bibliothèque Google Play Billing appelle une fois l'opération terminée.

L'exemple suivant illustre la consommation d'un produit avec la bibliothèque Google Play Billing à l'aide du jeton d'achat associé :

Kotlin

    val consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build()
    val consumeResult = withContext(Dispatchers.IO) {
        client.consumePurchase(consumeParams)
    }

Java

    ConsumeParams consumeParams =
            ConsumeParams.newBuilder()
                .setPurchaseToken(purchase.getPurchaseToken())
                .build();

    ConsumeResponseListener listener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                // Handle the success of the consume operation.
            }
        }
    };

    billingClient.consumeAsync(consumeParams, listener);

Produits non consommables

Pour confirmer les achats de produits non consommables, si votre application dispose d'un backend sécurisé, nous vous recommandons d'utiliser Purchases.products:acknowledge pour confirmer de manière fiable les achats. Assurez-vous que l'achat n'a pas déjà été confirmé en vérifiant le acknowledgementState à partir du résultat de l'appel de Purchases.products:get.

Si votre application est côté client uniquement, utilisez BillingClient.acknowledgePurchase() depuis la bibliothèque Google Play Billing. Avant de confirmer un achat, votre application doit vérifier s'il a déjà été confirmé à l'aide de la méthode isAcknowledged() dans la bibliothèque Google Play Billing.

L'exemple suivant montre comment confirmer un achat à l'aide de la bibliothèque Google Play Billing :

Kotlin

val client: BillingClient = ...
val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ...

val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
    .setPurchaseToken(purchase.purchaseToken)
val ackPurchaseResult = withContext(Dispatchers.IO) {
     client.acknowledgePurchase(acknowledgePurchaseParams.build())
}

Java

BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...

AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
 client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);

Abonnements

Les abonnements sont traités de la même manière que les produits non consommables. Si possible, utilisez Purchases.subscriptions.acknowledge depuis l'API Google Play Developer pour confirmer l'achat de manière fiable à partir de votre backend sécurisé. Vérifiez si l'achat n'a pas déjà été confirmé en vérifiant le acknowledgementState dans la ressource d'achat de Purchases.subscriptions:get. Sinon, vous pouvez confirmer un abonnement à l'aide de BillingClient.acknowledgePurchase() dans la bibliothèque Google Play Billing après avoir vérifié isAcknowledged(). Tous les achats initiaux d'abonnements doivent être confirmés. Il n'est pas nécessaire de confirmer le renouvellement de l'abonnement. Pour en savoir plus sur la confirmation des abonnements, consultez la rubrique Vendre des abonnements.

Récapitulatif

L'extrait de code suivant récapitule ces étapes.

Kotlin

fun handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify
.
    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

Java

void handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify

    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

Pour vérifier que votre application a correctement implémenté ces étapes, vous pouvez suivre le guide de test.

Gérer les transactions en attente

Google Play accepte les transactions en attente ou celles nécessitant une ou plusieurs étapes supplémentaires entre le moment où l'utilisateur effectue un achat et le traitement du mode de paiement associé. Votre application ne doit pas accorder de droit à ces types d'achats tant que Google ne vous a pas informé que le mode de paiement de l'utilisateur a été débité.

Par exemple, un utilisateur peut lancer une transaction en choisissant un magasin physique dans lequel il paiera plus tard en espèces. L'utilisateur reçoit un code par notification et par e-mail. Lorsque l'utilisateur arrive au magasin physique, il peut passer par le caissier pour utiliser le code et payer en espèces. Google vous informe ensuite, vous et l'utilisateur, qu'un paiement a été effectué. Votre application peut alors accorder des droits à l'utilisateur.

Appelez enablePendingPurchases() lors de l'initialisation de BillingClient pour activer les transactions en attente pour votre application. Votre application doit activer et prendre en charge les transactions en attente pour les produits uniques. Avant d'ajouter une assistance, assurez-vous de bien comprendre le cycle de vie des achats pour les transactions en attente.

Lorsque votre application reçoit un nouvel achat, via votre PurchasesUpdatedListener ou suite à un appel queryPurchasesAsync, utilisez la méthode getPurchaseState() pour déterminer si l'état d'achat est PURCHASED ou PENDING. Vous ne devez accorder des droits d'accès que lorsque l'état est PURCHASED.

Si votre application est en cours d'exécution et que vous disposez d'une connexion active à la bibliothèque Play Billing lorsque l'utilisateur effectue l'achat, votre PurchasesUpdatedListener est appelé à nouveau et PurchaseState est désormais PURCHASED. À ce stade, votre application peut traiter l'achat à l'aide de la méthode standard de détection et de traitement des achats. Votre application doit également appeler queryPurchasesAsync() dans la méthode onResume() de votre application pour gérer les achats qui sont passés à l'état PURCHASED lorsque votre application n'était pas en cours d'exécution.

Lorsque l'achat passe de PENDING à PURCHASED, votre client real_time_developer_notifications reçoit une notification ONE_TIME_PRODUCT_PURCHASED ou SUBSCRIPTION_PURCHASED. Si l'achat est annulé, vous recevrez une notification ONE_TIME_PRODUCT_CANCELED ou SUBSCRIPTION_PENDING_PURCHASE_CANCELED. Cela peut se produire si votre client n'effectue pas le paiement dans le délai requis. Notez que vous pouvez toujours utiliser l'API Google Play Developer pour vérifier l'état actuel d'un achat.

Gérer les achats de quantités multiples

Compatible avec les versions 4.0 et ultérieures de la bibliothèque Google Play Billing, Google Play permet aux clients d'acheter plus d'un produit intégré dans l'application en une seule transaction en spécifiant une quantité dans le panier d'achat. Votre application doit gérer les achats de quantités multiples et accorder des droits en fonction de la quantité d'achats spécifiée.

Pour respecter les achats de quantités multiples, la logique de provisionnement de votre application doit vérifier une quantité d'articles. Vous pouvez accéder à un champ quantity à partir de l'une des API suivantes :

Une fois que vous avez ajouté une logique pour gérer les achats de quantités multiples, vous devez activer la fonctionnalité de quantités multiples pour le produit correspondant sur la page de gestion des produits intégrés à l'application de la Google Play Console.

Interroger la configuration de facturation de l'utilisateur

getBillingConfigAsync() indique le pays de l'utilisateur sur Google Play.

Vous pouvez interroger la configuration de facturation de l'utilisateur après avoir créé un BillingClient. L'extrait de code suivant explique comment appeler getBillingConfigAsync(). Gérez la réponse en implémentant le BillingConfigResponseListener. Cet écouteur reçoit des mises à jour pour toutes les requêtes de configuration de facturation lancées à partir de votre application.

Si le BillingResult renvoyé ne contient aucune erreur, vous pouvez vérifier le champ countryCode dans l'objet BillingConfig pour obtenir le pays de l'utilisateur dans Google Play.

Kotlin

// Use the default GetBillingConfigParams.
val getBillingConfigParams = GetBillingConfigParams.newBuilder().build()
billingClient.getBillingConfigAsync(getBillingConfigParams,
    object : BillingConfigResponseListener {
        override fun onBillingConfigResponse(
            billingResult: BillingResult,
            billingConfig: BillingConfig?
        ) {
            if (billingResult.responseCode == BillingResponseCode.OK
                && billingConfig != null) {
                val countryCode = billingConfig.countryCode
                ...
            } else {
                // TODO: Handle errors
            }
        }
    })

Java

// Use the default GetBillingConfigParams.
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build();
billingClient.getBillingConfigAsync(getBillingConfigParams,
    new BillingConfigResponseListener() {
      public void onBillingConfigResponse(
          BillingResult billingResult, BillingConfig billingConfig) {
        if (billingResult.getResponseCode() == BillingResponseCode.OK
            && billingConfig != null) {
            String countryCode = billingConfig.getCountryCode();
            ...
         } else {
            // TODO: Handle errors
        }
      }
    });

Rappels d'abandon de panier sur la page d'accueil de Google Play Jeux (activés par défaut)

Pour les développeurs de jeux qui monétisent leurs applications via des achats intégrés, la fonctionnalité de rappel d'abandon du panier, qui incite les utilisateurs à finaliser les achats précédemment abandonnés lorsqu'ils parcourent le Google Play Store, est un moyen de vendre des SKU (unités de stock) actives dans la Play Console en dehors de votre application. Ces achats sont effectués en dehors de votre application, depuis la page d'accueil de Google Play Jeux dans le Google Play Store.

Cette fonctionnalité est activée par défaut pour aider les utilisateurs à reprendre là où ils s'étaient arrêtés et les développeurs à maximiser leurs ventes. Toutefois, vous pouvez désactiver cette fonctionnalité dans votre application en envoyant le formulaire de désactivation de la fonctionnalité de rappel d'abandon du panier. Pour connaître les bonnes pratiques de gestion des codes SKU dans la Google Play Console, consultez la section Créer un produit intégré à l'application.

Les images suivantes montrent le rappel d'abandon de panier sur le Google Play Store:

L&#39;écran du Google Play Store affiche une invite d&#39;achat pour un achat précédemment abandonné
Figure 2. L'écran du Google Play Store affiche une invite d'achat pour un achat précédemment abandonné.

L&#39;écran du Google Play Store affiche une invite d&#39;achat pour un achat précédemment abandonné
Figure 3. L'écran du Google Play Store affiche une invite d'achat pour un achat précédemment abandonné.