Conseils sur l'intégration dans l'application pour un système de facturation alternatif au choix de l'utilisateur

Ce guide explique comment intégrer les API pour proposer un système de facturation alternatif au choix de l'utilisateur dans votre application.

Configuration de la bibliothèque Play Billing

Ajoutez la dépendance de la bibliothèque Play Billing à votre application Android. Pour pouvoir utiliser les API de facturation alternative, la version 5.2 ou ultérieure est nécessaire. Si vous devez effectuer la migration à partir d'une version antérieure, suivez les instructions du guide de migration avant d'essayer d'implémenter un système de facturation alternatif.

Se connecter à Google Play

Les premières étapes du processus d'intégration sont les mêmes que celles décrites dans le Guide d'intégration de Google Play Billing, avec quelques différences au niveau de l'initialisation du client de facturation :

  • Vous devez appeler une nouvelle méthode pour indiquer que vous souhaitez proposer à l'utilisateur plusieurs options de facturation : enableUserChoiceBilling.
  • Enregistrez un UserChoiceBillingListener pour gérer les cas où l'utilisateur choisit un système de facturation alternatif.

L'exemple suivant illustre l'initialisation d'un objet BillingClient avec ces modifications :

Kotlin

val purchasesUpdatedListener =
   PurchasesUpdatedListener { billingResult, purchases ->
       // Handle new Google Play purchase.
   }

val userChoiceBillingListener =
   UserChoiceBillingListener { userChoiceDetails ->
       // Handle alternative billing choice.
   }

var billingClient = BillingClient.newBuilder(context)
   .setListener(purchasesUpdatedListener)
   .enablePendingPurchases()
   .enableUserChoiceBilling(userChoiceBillingListener)
   .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // Handle new Google Play purchase.
    }
};

private UserChoiceBillingListener userChoiceBillingListener = new UserChoiceBillingListener() {
    @Override
    public void userSelectedAlternativeBilling(
        UserChoiceDetails userChoiceDetails) {
        // Handle new Google Play purchase.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .enableUserChoiceBilling(userChoiceBillingListener)
    .build();

Après avoir initialisé BillingClient, vous devez établir une connexion à Google Play, comme décrit dans le guide d'intégration.

Afficher les produits disponibles

Vous pouvez présenter les produits disponibles à l'utilisateur de la même manière qu'une intégration du système de facturation Google Play. Lorsque l'utilisateur a vu les produits disponibles à la vente et qu'il en a sélectionné un, lancez le parcours de facturation au choix de l'utilisateur, comme décrit dans la section suivante.

Lancer le parcours de facturation au choix de l'utilisateur

Pour lancer le parcours de facturation au choix de l'utilisateur, appelez launchBillingFlow(). Cette opération s'apparente au lancement d'un parcours d'achat avec l'intégration d'un système de facturation Google Play : vous fournissez une instance ProductDetails et un offerToken correspondant au produit et à l'offre que l'utilisateur souhaite acquérir. Si l'utilisateur choisit le système de facturation de Google Play, ces informations sont utilisées pour poursuivre le parcours d'achat.

Lorsque les développeurs appellent launchBillingFlow(), le système de facturation Google Play exécute la vérification suivante :

  • Le système vérifie si le pays de l'utilisateur Google Play est un pays qui propose un système de facturation alternatif au choix de l'utilisateur (c'est-à-dire un pays accepté). Si tel est le cas, Google Play vérifie si un système de facturation alternatif a été activé, en fonction de la configuration du BillingClient.
    • Si un système de facturation alternatif au choix de l'utilisateur a été activé, le parcours d'achat affiche l'expérience utilisateur au choix de l'utilisateur.
    • Si un système de facturation alternatif au choix de l'utilisateur n'est pas activé, le parcours d'achat affiche l'expérience utilisateur standard du système de facturation Google Play, sans choix pour l'utilisateur.
  • Si le pays de l'utilisateur sur Google Play n'est pas pris en charge, le parcours d'achat affiche l'expérience utilisateur standard du système de facturation Google Play, sans choix pour l'utilisateur.

Le pays de l'utilisateur sur Google Play est un pays pris en charge

Le pays de l'utilisateur sur Google Play n'est pas pris en charge

enableUserChoiceBilling est appelé lors de la configuration de BillingClient

L'utilisateur voit le choix de l'utilisateur dans l'expérience utilisateur

L'utilisateur voit l'expérience utilisateur standard du système de facturation Google Play

enableUserChoiceBilling n'est pas appelé lors de la configuration de BillingClient

L'utilisateur voit l'expérience utilisateur standard du système de facturation Google Play

L'utilisateur voit l'expérience utilisateur standard du système de facturation Google Play

Gérer la sélection de l'utilisateur

La manière dont vous gérez le reste du parcours d'achat varie selon que l'utilisateur a sélectionné le système de facturation de Google Play ou un système de facturation alternatif.

Lorsque l'utilisateur sélectionne un système de facturation alternatif

Si l'utilisateur choisit un système de facturation alternatif, Google Play appelle la méthode UserChoiceBillingListener pour avertir l'application qu'elle doit lancer le parcours d'achat dans ce système. Plus spécifiquement, la méthode userSelectedAlternativeBilling() est appelée.

Le jeton de transaction externe fourni dans l'objet UserChoiceDetails représente une signature permettant à l'utilisateur d'indiquer un parcours de facturation alternatif. Utilisez ce jeton pour enregistrer toute transaction résultant de ce choix, comme expliqué dans le guide d'intégration du backend.

Le UserChoiceBillingListener devrait effectuer les actions suivantes :

  • Obtenez le ou les produits achetés par l'utilisateur afin qu'ils puissent être présentés dans le parcours d'achat dans le système de facturation alternatif.
  • Collectez la chaîne reçue en tant que jeton de transaction externe et envoyez-la à votre backend pour la conserver. Elle sera utilisée ultérieurement pour enregistrer la transaction externe dans Google Play si l'utilisateur effectue cet achat spécifique.
  • Lancez le parcours d'achat alternatif du développeur.

Si l'utilisateur finalise l'achat via le système de facturation alternatif, vous devez enregistrer la transaction dans Google Play en appelant l'API Google Play Developer depuis votre backend dans les 24 heures, en veillant à fournir l'externalTransactionToken et des informations supplémentaires sur la transaction. Consultez le guide d'intégration du backend pour plus d'informations.

L'exemple suivant montre comment implémenter l'UserChoiceBillingListener :

Kotlin

private val userChoiceBillingListener =
    UserChoiceBillingListener { userChoiceDetails ->
        // Get the products being purchased by the user.
        val products = userChoiceDetails.products

        // Send external transaction token to developer backend server
        // this devBackend object is for demonstration purposes,
        // developers can implement this step however best fits their
        // app to backend communication.
        devBackend.sendExternalTransactionStarted(
            userChoiceDetails.externalTransactionToken,
            user
        )

        // Launch alternative billing
        // ...
        // The developer backend handles reporting the transaction
        // to Google Play's backend once the alternative billing
        // purchase is completed.
    }

Java

private userChoiceBillingListener userChoiceBillingListener = new UserChoiceBillingListener() {
    @Override
    public void userSelectedAlternativeBilling(
           UserChoiceDetails userChoiceDetails) {
       // Get the products being purchased by the user.
       List<Product> products =
              userChoiceDetails.getProducts();

       // Send external transaction token to developer backend server
       // this devBackend object is for demonstration purposes,
       // developers can implement this step however best fits their
       // app to backend communication.
       devBackend.sendExternalTransactionStarted(
              userChoiceDetails.getExternalTransactionToken(),
              user
       );

       // Launch alternative billing
       // ...
       // The developer backend handles reporting the transaction
       // to Google Play's backend once the alternative billing
       // purchase is completed.
    }
};

Lorsque l'utilisateur sélectionne le système de facturation de Google Play

Si l'utilisateur choisit le système de facturation de Google Play, il continue l'achat via Google Play.

  • Pour en savoir plus sur la gestion des nouveaux achats via une application via le système de facturation de Google Play, consultez la section Traitement des achats du guide d'intégration de la bibliothèque.
  • Pour obtenir des conseils supplémentaires sur les achats d'abonnements, consultez la section Nouveaux abonnements dans le guide de gestion des abonnements.

Gérer les modifications liées aux abonnements

Pour les développeurs qui utilisent un système de facturation alternatif au choix de l'utilisateur, les achats doivent être traités via le système de facturation de Google Play ou signalés avec un externalTransactionId, selon le choix de l'utilisateur. Les modifications apportées aux abonnements existants et qui ont été traitées via le parcours impliquant un choix de l'utilisateur peuvent être effectuées via le même système de facturation jusqu'à expiration.

Cette section explique comment gérer certains scénarios courants liés à la modification d'un abonnement.

Parcours de mise à niveau et de rétrogradation

Les modifications apportées à l'abonnement, y compris les parcours de mise à niveau et de rétrogradation, doivent être gérées différemment selon que l'abonnement a été initialement souscrit via le système de facturation de Google Play ou via un système de facturation alternatif.

Les modules complémentaires qui dépendent d'un abonnement existant, qui partagent le même mode de paiement et qui correspondent à des frais récurrents sont traités comme des mises à niveau. Pour les autres modules complémentaires, les utilisateurs doivent pouvoir choisir le système de facturation qu'ils souhaitent utiliser. Initiez une nouvelle expérience d'achat à l'aide de launchBillingFlow(), comme décrit dans la section Lancer le parcours de facturation au choix de l'utilisateur.

Abonnements souscrits via un système de facturation alternatif

Pour les abonnements initialement souscrits via le système de facturation alternatif du développeur après le choix de l'utilisateur, les personnes qui demandent une mise à niveau ou une rétrogradation doivent passer par le système de facturation alternatif du développeur. Elles n'ont pas à repasser par le le parcours de facturation au choix de l'utilisateur.

Pour ce faire, appelez launchBillingFlow() lorsque l'utilisateur demande une mise à niveau ou une rétrogradation. Au lieu de spécifier un objet SubscriptionUpdateParams dans les paramètres, utilisez setOriginalExternalTransactionId en fournissant l'ID de transaction externe pour l'achat d'origine. Cela n'affichera pas l'écran de choix de l'utilisateur, car le choix de l'utilisateur pour l'achat d'origine est conservé pour les mises à niveau et les rétrogradations. Dans ce cas, l'appel de launchBillingFlow() génère un nouveau jeton de transaction externe que vous pouvez récupérer à partir du rappel.

Kotlin

// The external transaction ID from the current
// alternative billing subscription.
val externalTransactionId = //... ;

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        listOf(
            BillingFlowParams.ProductDetailsParams.newBuilder()
                // Fetched via queryProductDetailsAsync.
                .setProductDetails(productDetailsNewPlan)
                // offerIdToken can be found in
                // ProductDetails=>SubscriptionOfferDetails.
                .setOfferToken(offerTokenNewPlan)
                .build()
        )
    )
    .setSubscriptionUpdateParams(
        BillingFlowParams.SubscriptionUpdateParams.newBuilder()
            .setOriginalExternalTransactionId(externalTransactionId)
            .build()

val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

// When the user selects the alternative billing flow,
// the UserChoiceBillingListener is triggered.

Java

// The external transaction ID from the current
// alternative billing subscription.
String externalTransactionId = //... ;

BillingFlowParams billingFlowParams =
        BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(
                ImmutableList.of(
                    ProductDetailsParams.newBuilder()
                        // Fetched via queryProductDetailsAsync.
                        .setProductDetails(productDetailsNewPlan)
                        // offerIdToken can be found in
                        // ProductDetails=>SubscriptionOfferDetails
                        .setOfferToken(offerTokenNewPlan)
                    .build()
                )
            )
            .setSubscriptionUpdateParams(
                SubscriptionUpdateParams.newBuilder()
                    .setOriginalExternalTransactionId(externalTransactionId)
                    .build()
            )
            .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

// When the user selects the alternative billing flow,
// the UserChoiceBillingListener is triggered.

Une fois la mise à niveau ou la rétrogradation effectuée dans le système de facturation alternatif, vous devez enregistrer une nouvelle transaction à l'aide du jeton de transaction externe obtenu via l'appel précédent pour l'achat du nouvel abonnement.

Abonnements souscrits via le système de facturation de Google Play

De même, les utilisateurs ayant choisi de souscrire leur abonnement via le système de facturation de Google Play devraient voir le parcours de mise à niveau ou de rétrogradation dans ce système. Les instructions suivantes décrivent comment lancer le parcours d'achat pour une mise à niveau ou une rétrogradation via le système de facturation de Google Play :

  1. Identifiez l'offerToken de l'offre sélectionnée pour le nouveau forfait :

val offerTokenNewPlan = productDetailsNewPlan
             .getSubscriptionOfferDetails(selectedOfferIndex)
             .getOfferToken()

String offerTokenNewPlan = productDetailsNewPlan
                     .getSubscriptionOfferDetails(selectedOfferIndex)
                     .getOfferToken();

  1. Envoyez les informations correctes au système de facturation de Google Play pour traiter le nouvel achat, y compris le jeton d'achat de l'abonnement existant :

val billingFlowParams =
    BillingFlowParams.newBuilder().setProductDetailsParamsList(
        listOf(
            BillingFlowParams.ProductDetailsParams.newBuilder()
                .setProductDetails(productDetailsNewPlan)
                .setOfferToken(offerTokenNewPlan)
                .build()
        )
    )
    .setSubscriptionUpdateParams(
        BillingFlowParams.SubscriptionUpdateParams.newBuilder()
            .setOldPurchaseToken(oldToken)
            .setReplaceProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
            .build()
        )
        .build()

BillingClient.launchBillingFlow(activity, billingFlowParams)

BillingFlowParams billingFlowParams =
        BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(
                ImmutableList.of(
                    ProductDetailsParams.newBuilder()
                        // Fetched via queryProductDetailsAsync
                        .setProductDetails(productDetailsNewPlan)
                        // offerIdToken can be found in
                        // ProductDetails=>SubscriptionOfferDetails.
                        .setOfferToken(offerTokenNewPlan)
                        .build()
                )
            )
            .setSubscriptionUpdateParams(
                SubscriptionUpdateParams.newBuilder()
                    // purchaseToken can be found in
                    // Purchase#getPurchaseToken
                    .setOldPurchaseToken("old_purchase_token")
                    .setReplaceProrationMode(ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
                    .build()
            )
            .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

Cet achat est effectué dans le système de facturation de Google Play, et votre application reçoit l'appel PurchasesUpdatedListener.onPurchaseUpdated avec le résultat de l'achat. Si l'achat a abouti, la méthode onPurchaseUpdated() reçoit également les nouvelles informations d'achat, et votre backend reçoit une notification en temps réel pour les développeurs, SUBSCRIPTION_PURCHASED. Lorsque l'état du nouvel achat est généré, un attribut linkedPurchaseToken est associé à l'ancien abonnement afin que vous puissiez le supprimer comme recommandé.

Résiliations d'abonnement et restaurations

Les utilisateurs doivent pouvoir résilier leur abonnement à tout moment. Lorsqu'un utilisateur résilie un abonnement, la résiliation du droit d'accès peut être reportée jusqu'à la fin de la période de facturation. Par exemple, si un utilisateur résilie un abonnement mensuel en milieu de mois, il peut continuer à profiter du service pendant encore environ deux semaines jusqu'à ce que son accès soit supprimé. Pendant cette période, l'abonnement est toujours techniquement actif. L'utilisateur peut donc utiliser le service.

Il n'est pas rare que les utilisateurs reviennent sur leur décision pendant cette période activité. Dans ce guide, c'est ce que nous appelons la restauration d'un abonnement. Les sections suivantes expliquent comment gérer les scénarios de restauration dans une intégration avec une API de facturation alternative.

Abonnements souscrits via un système de facturation alternatif

Si vous disposez d'un ID de transaction externe pour un abonnement résilié, il n'est pas nécessaire d'appeler launchBillingFlow() afin de le restaurer. Vous ne devriez pas avoir à l'utiliser pour ce type d'activation. Si un utilisateur restaure son abonnement pendant la période active avant la résiliation effective, aucune transaction n'est effectuée à ce moment-là. Vous pouvez continuer à enregistrer les renouvellements lorsque le cycle de facturation en cours expire et que la prochaine période de renouvellement commence. Cela inclut les cas où l'utilisateur reçoit un crédit ou un tarif de renouvellement spécial dans le cadre de la restauration (par exemple, une promotion pour l'encourager à poursuivre son abonnement).

Abonnements souscrits via le système de facturation de Google Play

En règle générale, les utilisateurs peuvent restaurer les abonnements via le système de facturation de Google Play. Pour les abonnements résiliés qui ont été souscrits à l'origine via le système de facturation de Google Play, l'utilisateur peut revenir sur sa décision tant que l'abonnement est actif via la fonctionnalité de réabonnement de Google Play. Dans ce cas, vous recevez une notification en temps réel pour les développeurs SUBSCRIPTION_RESTARTED dans votre backend, et aucun nouveau jeton d'achat n'est émis. Le jeton d'origine est utilisé pour poursuivre l'abonnement. Pour découvrir comment gérer la restauration dans le système de facturation de Google Play, consultez la section Restaurations du guide de gestion des abonnements.

Vous pouvez également appeler launchBillingFlow() pour déclencher une restauration dans le système de facturation de Google Play à partir de l'application. Pour découvrir comment procéder, consultez la section Avant l'expiration de l'abonnement (dans l'application). Dans le cas des utilisateurs qui ont suivi le parcours de facturation au choix de l'utilisateur pour l'achat d'origine (qui a été résilié, mais qui reste actif), le système détecte automatiquement leur choix et affiche l'interface utilisateur permettant de restaurer ces achats. Ils sont invités à confirmer le rachat de l'abonnement via Google Play, mais il n'est pas nécessaire de recommencer le parcours utilisateur. Dans ce cas, un nouveau jeton d'achat est émis pour chaque utilisateur. Votre backend recevra une notification en temps réel pour les développeurs, SUBSCRIPTION_PURCHASED, et la valeur linkedPurchaseToken correspondant à l'état du nouvel achat sera définie comme pour une mise à niveau ou une rétrogradation, où le jeton de l'ancien achat d'abonnement est résilié.

Réabonnements

Si un abonnement expire complètement, que ce soit en raison d'une résiliation ou d'un refus de paiement sans récupération (blocage d'un compte arrivé à expiration), l'utilisateur doit se réabonner s'il souhaite réactiver le droit d'accès.

Vous pouvez également activer le réabonnement via l'application de la même manière qu'une inscription standard. Les utilisateurs doivent pouvoir choisir le système de facturation par lequel ils souhaitent passer. Dans ce cas, launchBillingFlow() peut être appelé, comme décrit dans la section Lancer le parcours de facturation au choix de l'utilisateur.

Tester un système de facturation alternatif

Les testeurs de licence doivent être utilisés pour tester l'intégration de votre système de facturation alternatif. Vous ne serez pas facturé pour les transactions lancées par des comptes de testeurs de licence. Pour en savoir plus sur la configuration des testeurs de licence, consultez Tester la facturation des achats in-app avec les licences d'application.

Étapes suivantes

Une fois que vous avez terminé l'intégration dans l'application, vous pouvez intégrer le backend.