Cycle de vie des abonnements

Les abonnements peuvent passer par différents états tout au long de leur cycle de vie, en fonction de nombreux facteurs, y compris le comportement du renouvellement automatique, les situations de refus de paiement et les actions de gestion des développeurs.

Gérer le cycle de vie des abonnements à renouvellement automatique

Lorsque l'état de l'abonnement d'un utilisateur change, votre serveur backend reçoit un message SubscriptionNotification.

Figure 1. États du cycle de vie et événements de transition pour les achats d'abonnements à renouvellement automatique

Pour mettre à jour l'état dans le backend, appelez l'API purchases.subscriptionsv2.get avec le jeton d'achat inclus dans la notification. Ce point de terminaison fournit le dernier état d'abonnement à partir d'un jeton d'achat et est considéré comme source de référence pour la gestion des abonnements.

Le jeton d'achat est valide à partir du moment où vous souscrivez un abonnement jusqu'à 60 jours après sa date d'expiration. Au-delà de cette date, il ne pourra plus être utilisé pour appeler l'API Google Play Developer.

Nouveaux achats d'abonnements à renouvellement automatique

Lorsqu'un utilisateur souscrit un abonnement, un message SubscriptionNotification de type SUBSCRIPTION_PURCHASED est envoyé au client RTDN. Que vous receviez cette notification, que vous enregistriez un nouvel achat dans l'application via PurchasesUpdatedListener ou que vous procédiez manuellement à la récupération des achats dans la méthode onResume() de votre application, vous devez traiter le nouvel achat dans le backend sécurisé. Pour ce faire, procédez comme suit :

  1. Interrogez le point de terminaison purchases.subscriptionsv2.get pour obtenir une ressource d'abonnement contenant le dernier état d'abonnement.
  2. Assurez-vous que la valeur du champ subscriptionState est SUBSCRIPTION_STATE_ACTIVE.
  3. Vérifiez l'achat.
  4. Autorisez l'utilisateur à accéder au contenu. Le compte utilisateur associé à l'achat peut être identifié par l'objet ExternalAccountIdentifiers de la ressource d'abonnement si des identifiants ont été définis au moment de l'achat via setObfuscatedAccountId et setObfuscatedProfileId.

La bibliothèque Play Billing inclut également une méthode permettant de confirmer un abonnement, acknowledgePurchase(), ainsi qu'une méthode permettant de vérifier l'état de cette confirmation, isAcknowledged(). Toutefois, nous vous recommandons de gérer le traitement des achats dans le backend afin de renforcer la sécurité.

Voici ce à quoi ressemble la ressource d'abonnement pour les nouveaux achats :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_PENDING", // need to acknowledge new purchases
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

Renouvellement de l'abonnement

Pour les abonnements à renouvellement automatique sans versement, une notification SUBSCRIPTION_RENEWED est envoyée lors du renouvellement de l'abonnement. Pour les abonnements en plusieurs versements, une notification SUBSCRIPTION_RENEWED est envoyée chaque fois que l'abonnement est débité à sa date de facturation. Assurez-vous que l'utilisateur a toujours accès à l'abonnement, puis mettez à jour l'état de l'abonnement avec le nouveau délai d'expiration (expiryTime) fourni dans la ressource d'abonnement renvoyée par l'API Google Play Developer. Voici ce à quoi ressemble la ressource d'abonnement :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ]
}

Vous n'avez pas besoin de confirmer le renouvellement de l'abonnement.

Délai de grâce

En cas de problèmes de paiement lors du renouvellement d'un abonnement, Google en informe l'utilisateur et tente régulièrement de renouveler l'abonnement avant son expiration. Cette période de récupération peut être constituée d'un délai de grâce, suivi d'un blocage de compte. Pendant le délai de grâce, l'utilisateur conserve son droit d'accès à l'abonnement.

La méthode queryPurchasesAsync() continue de renvoyer les achats soumis à un délai de grâce. Si votre application s'appuie uniquement sur queryPurchasesAsync pour vérifier si un utilisateur peut accéder à un abonnement, elle doit gérer automatiquement les délais de grâce, car ces abonnements sont indiqués comme actifs via la bibliothèque Play Billing.

La synchronisation de l'état des abonnements avec le backend vous permet de mieux comprendre les refus de paiement et vous fournit plus de contexte lorsque vous essayez de limiter la perte involontaire d'utilisateurs. Écoutez les messages SubscriptionNotification de type SUBSCRIPTION_IN_GRACE_PERIOD pour être averti lorsque l'utilisateur est soumis à un délai de grâce. Pendant toute la durée du délai de grâce, la ressource d'abonnement contient autoRenewEnabled = true. Google Play étend de manière dynamique la valeur expiryTime jusqu'à la fin du délai de grâce, car le droit d'accès doit perdurer jusqu'à ce que l'utilisateur annule le délai de grâce ou jusqu'à ce que ce délai expire. La valeur du champ subscriptionState pour cette période est SUBSCRIPTION_STATE_IN_GRACE_PERIOD. Voici ce à quoi ressemble la ressource d'abonnement :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_IN_GRACE_PERIOD",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_future,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

Play informe les utilisateurs soumis à un délai de grâce que leur paiement a été refusé et les invite à résoudre les problèmes liés à leur mode de paiement sur le Play Store. Lorsqu'un utilisateur entre dans un délai de grâce, vous devez également l'encourager à corriger son mode de paiement au cas où l'échec serait involontaire. Pour ce faire, un moyen simple consiste à utiliser l'API de messagerie dans l'application. Si vous appelez cette API lorsque l'utilisateur ouvre votre application, un message Play s'affiche dans un snackbar temporaire et lui indique que son paiement a été refusé. Ce message inclut également un lien profond permettant à l'utilisateur de corriger son mode de paiement sur Google Play.

Dès que l'utilisateur corrige son mode de paiement, l'abonnement est renouvelé avec sa date de renouvellement initiale. Vous pouvez gérer le renouvellement comme décrit dans la section Renouvellements.

Si l'utilisateur ne corrige pas son mode de paiement pendant le délai de grâce, l'abonnement est soumis à un blocage de compte, et il perd ses droits d'accès.

Récupération et accès en cas de délai de grâce

La figure 2 présente la chronologie d'un abonnement qui est soumis à un délai de grâce, puis qui est rétabli lorsque l'utilisateur corrige son mode de paiement. À la fin du délai de grâce, l'utilisateur doit perdre tous les avantages de l'abonnement et être soumis à un blocage de compte.

Figure 2 : Chronologie d'un abonnement qui est soumis à un délai de grâce, puis qui est rétabli avant son expiration

Gardez à l'esprit les points suivants :

  • Pendant ce délai de grâce, l'utilisateur doit conserver l'accès aux avantages de l'abonnement.
  • Lorsqu'un abonnement est récupéré au cours d'un délai de grâce, la date de renouvellement n'est pas réinitialisée.
  • Si vous augmentez le délai de grâce (de 7 à 14 jours, par exemple), la période durant laquelle les utilisateurs soumis à un délai de grâce bénéficient des avantages de l'abonnement est prolongée.
  • Si vous réduisez le délai de grâce, les avantages de l'abonnement sont immédiatement révoqués pour les utilisateurs qui sont soumis à un délai de grâce depuis suffisamment longtemps pour dépasser la durée du nouveau délai de grâce. Par exemple, si vous réduisez le délai de grâce de 14 à 7 jours, les avantages de l'abonnement sont immédiatement révoqués pour les utilisateurs soumis à un délai de grâce depuis 8 à 14 jours.
  • L'abonnement reste actif et vous ne recevrez pas de notification RTDN de délai de grâce tant que le délai de grâce silencieux n'est pas terminé.

Délai de grâce silencieux

Vous pouvez définir un délai de grâce de 0 jours, mais Play attendra au moins un jour pour s'assurer de disposer d'un délai suffisant pour les nouvelles tentatives de paiement. Ce délai de grâce silencieux offre une sécurité pour le traitement des paiements. Pendant cette période de 24 heures, l'abonnement reste à l'état ACTIVE.

Le meilleur moyen de rester synchronisé avec les modifications de l'état de l'abonnement est d'écouter et de réagir aux notifications en temps réel pour les développeurs (RTDN). Appelez la méthode purchases.subscriptionsv2.get() à l'heure de la date de fin de validité au lieu de l'heure d'expiration pour obtenir un état plus précis de l'abonnement.

Selon l'état de l'abonnement après la période de grâce silencieuse de 24 heures, vous devriez recevoir l'une des notifications suivantes:

  • SUBSCRIPTION_ON_HOLD (si activé)
  • SUBSCRIPTION_CANCELED (si annulé)
  • SUBSCRIPTION_EXPIRED (si expiré)
  • SUBSCRIPTION_RENEWED (si le renouvellement a réussi)

Vous pouvez également appeler la méthode subscriptionV2.get() à tout moment après le délai de grâce silencieux de 24 heures pour obtenir le dernier état de l'abonnement.

Blocage de compte

En cas de problèmes de paiement lors du renouvellement d'un abonnement, le blocage de compte commence à l'issue du délai de grâce. Lorsqu'un abonnement est soumis à un blocage de compte, vous devez interdire le droit d'accès à l'abonnement.

Pendant le blocage de compte, vous devez continuer à gérer les résiliations, les restaurations ou les rachats d'abonnement comme il se doit, car ces actions restent ouvertes à l'utilisateur durant cette période.

Les notifications en temps réel pour les développeurs, ou RTDN, vous avertissent lorsque l'utilisateur entame la période de blocage de compte. Vous pouvez ainsi l'informer dès que possible de la raison pour laquelle son accès à l'abonnement a été suspendu. Pour ce faire, un moyen simple consiste à utiliser l'API de messagerie dans l'application. Dans ce cas, lorsque l'utilisateur ouvre l'application, un message figurant dans un snackbar temporaire l'informe que son paiement a été refusé. Ce message inclut également un lien profond permettant à l'utilisateur de corriger son mode de paiement sur Google Play.

Si vos utilisateurs peuvent accéder au contenu des abonnements en dehors de votre application, ils peuvent découvrir qu'ils ont perdu l'accès sur différentes surfaces. Vous pouvez leur envoyer une notification push ou un e-mail pour les informer que leur abonnement n'est plus actif en raison d'un refus de paiement.

L'abonnement n'est pas renvoyé par la méthode queryPurchasesAsync() lors du blocage de compte. Par conséquent, si votre application s'appuie sur cette méthode pour afficher les achats existants, vous devez permettre le blocage de compte par défaut.

Avec les notifications en temps réel pour les développeurs, vous recevez un message SubscriptionNotification de type SUBSCRIPTION_ON_HOLD lorsqu'un abonnement passe à l'état "Blocage de compte". Appelez la méthode purchases.subscriptionsv2.get à partir de votre serveur backend sécurisé pour récupérer les nouvelles informations d'abonnement. Lors du blocage de compte, le champ de date d'expiration (expiryTime) de la ressource d'abonnement est défini sur un code temporel passé, et le champ subscriptionState est défini sur SUBSCRIPTION_STATE_ON_HOLD :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ON_HOLD",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_past,
      ...
    }
  ],
}

Pour restaurer l'accès, les utilisateurs doivent corriger leur mode de paiement. Play informe les utilisateurs soumis à un blocage de compte que leur paiement a été refusé. Vous devez les encourager à résoudre les problèmes liés à leur mode de paiement.

Une fois que l'utilisateur a corrigé son mode de paiement, l'abonnement revient à un état actif. Vous devez alors restaurer l'accès au contenu de l'abonnement. Dans ce cas, le jeton d'achat est le même qu'avant le blocage du compte, car le même achat est récupéré, et vous recevez une notification RTDN de type SUBSCRIPTION_RECOVERED.

Pour les abonnements en plusieurs versements, des refus et des récupérations de paiement peuvent se produire pour chaque tentative de paiement.

Après la récupération, la bibliothèque Play Billing renvoie l'abonnement via la méthode queryPurchasesAsync(). Si vous utilisez cette méthode pour déterminer si un utilisateur peut accéder à un abonnement, votre application doit gérer automatiquement la récupération de l'abonnement à la suite du blocage de compte.

Écoutez un message SubscriptionNotification de type SUBSCRIPTION_RECOVERED pour être notifié lorsqu'un abonnement est restauré et que l'utilisateur doit en récupérer l'accès. Si vous interrogez un abonnement après avoir reçu cette notification, le champ expiryTime est défini sur un code temporel futur, et le champ subscriptionState est défini à nouveau sur SUBSCRIPTION_STATE_ACTIVE :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      ...
    }
  ],
}

Si l'utilisateur ne corrige pas son mode de paiement avant la fin de la période de blocage de compte, vous recevrez une notification RTDN de type SUBSCRIPTION_CANCELED. Pour découvrir comment gérer une résiliation, consultez la section Résiliations. Lorsque vous interrogez un abonnement résilié de cette manière, le champ expiryTime renvoyé est défini sur un code temporel passé :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_past,
      ...
    }
  ],
}

Juste après avoir reçu la notification de résiliation pendant la période de blocage de compte, vous recevrez également une notification RTDN de type SUBSCRIPTION_EXPIRED, car l'utilisateur a perdu l'accès à l'abonnement payant. Vous pouvez gérer cette expiration comme vous le feriez normalement.

L'utilisateur peut récupérer l'accès en rachetant le même abonnement ou tout autre forfait que vous proposez via l'application pendant la période de blocage de compte associée à son achat initial. Dans ce cas, un nouveau jeton d'achat est émis, et la nouvelle valeur est renvoyée dans le cadre d'un événement SUBSCRIPTION_PURCHASED qui représente cette nouvelle instance.

Accès à l'abonnement et récupération en cas de blocage de compte

La figure 3 présente la chronologie d'un abonnement qui est soumis à un blocage de compte, puis qui est rétabli lorsque l'utilisateur corrige son mode de paiement.

Figure 3 : Chronologie d'un abonnement qui est soumis à un blocage de compte, puis qui est rétabli avant son expiration

Comme dans l'exemple précédent, la figure 4 présente la chronologie d'un abonnement qui est soumis à un délai de grâce avant de passer au blocage de compte, puis qui est récupéré avant expiration du blocage de compte.

Figure 4. Chronologie d'un abonnement qui est soumis à un délai de grâce avant de passer au blocage de compte, puis qui est récupéré avant expiration du blocage de compte

Gardez à l'esprit les points suivants :

  • Avant que l'abonnement ne passe à l'état "Blocage de compte", Google Play essaie une nouvelle fois de débiter le mode de paiement sous 48 heures. Au cours de cette période, l'utilisateur conserve les avantages de l'abonnement. Une fois ce délai écoulé, l'abonnement est soumis à un blocage de compte, et l'utilisateur doit perdre l'accès aux avantages de l'abonnement.
  • L'abonnement passe directement à l'état "Blocage de compte" lorsqu'il reprend après avoir été suspendu et que la nouvelle tentative de paiement échoue.
  • Lorsqu'un abonnement est récupéré après le blocage de compte, la date de renouvellement est réinitialisée.

Expiration

Une fois que l'abonnement expire, l'utilisateur ne doit plus pouvoir y accéder. Dans ce cas, un message SubscriptionNotification de type SUBSCRIPTION_EXPIRED est envoyé. Lorsque vous recevez cette notification, interrogez l'API Google Play Developer pour obtenir la dernière ressource d'abonnement. Après avoir vérifié que subscriptionState est bien SUBSCRIPTION_STATE_EXPIRED, supprimez le droit d'accès et enregistrez l'état d'achat comme non valide dans le backend. Voici ce à quoi ressemble la ressource d'abonnement :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time_in_past,
      ...
    }
  ],
}

Résiliation

Un utilisateur peut résilier volontairement un abonnement depuis le centre d'abonnements Play. Un abonnement peut aussi être résilié automatiquement si l'utilisateur ne le récupère pas après un blocage de compte. Les développeurs peuvent également déclencher une résiliation avec purchases.subscriptions.cancel. Lorsqu'un abonnement est résilié, l'utilisateur conserve l'accès au contenu jusqu'à la fin du cycle de facturation en cours. L'accès doit être révoqué à la fin de ce cycle.

La résiliation d'un abonnement à renouvellement automatique sans versement déclenche une notification SUBSCRIPTION_CANCELED. Lorsque vous recevez cette notification, le champ subscriptionState de la ressource d'abonnement renvoyée par l'API Google Play Developer indique SUBSCRIPTION_STATE_CANCELED, et le champ expiryTime contient la date à laquelle l'utilisateur doit perdre l'accès à l'abonnement. Si cette date est passée, l'utilisateur doit perdre immédiatement ses droits d'accès. Cela peut se produire, par exemple, si un utilisateur résilie un abonnement alors qu'il est soumis à un blocage de compte en raison d'un refus de paiement.

La ressource d'abonnement pour un achat résilié se présente comme suit :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ],
}

Pour les abonnements en plusieurs versements, une notification SUBSCRIPTION_CANCELLATION_SCHEDULED est envoyée en cas de résiliation à l'initiative de l'utilisateur lorsque des paiements restent dus pour la période d'engagement. La résiliation est en attente et prend effet à la fin de la période d'engagement en cours. Lorsque vous recevez cette notification, le champ subscriptionState de la ressource d'abonnement renvoyée par l'API Google Play Developer est défini sur SUBSCRIPTION_STATE_ACTIVE, car l'abonnement par versements est toujours actif jusqu'à la fin de la période d'engagement. Cependant, un objet pendingCancellation vide est présent. Une notification SUBSCRIPTION_CANCELED est envoyée, suivie d'une SUBSCRIPTION_EXPIRED à la fin de la période d'engagement.

La ressource d'abonnement pour un achat d'abonnement par versement en attente de résiliation se présente comme suit:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_plan01",
      "expiryTime": expiration_time,
      "autoRenewingPlan": {
        "autoRenewEnabled": true,
        "recurringPrice": {
          "currencyCode": "USD",
          "units": "1",
          "nanos": 990000000
        },
        "installmentDetails": {
          "initialCommittedPaymentsCount": 6,
          "remainingCommittedPaymentsCount": 5,
          "pendingCancellation": {}
      ...
        }
      }
    }
  ],
}

Vous pouvez consulter le champ canceledStateContext dans la ressource d'abonnement pour savoir pourquoi l'abonnement a été résilié (par exemple, pour déterminer si l'abonnement a été résilié par l'utilisateur, par le système ou par vous-même). Si l'abonnement a été résilié par l'utilisateur, vous pouvez consulter le champ userInitiatedCancellation pour en découvrir la raison. Cela peut vous aider à élaborer des stratégies de communication.

Lorsqu'un abonnement est résilié, mais qu'il n'a pas encore expiré, il est toujours renvoyé par queryPurchasesAsync(). Vous pouvez afficher un message dans votre application pour informer l'utilisateur que son abonnement a été résilié et lui indiquer la date d'expiration.

Révocation

Un abonnement peut être révoqué pour diverses raisons, y compris lorsque votre backend le révoque à l'aide de purchases.subscriptionsv2.revoke ou en cas de refus de paiement de l'achat. Dans ce cas, révoquez immédiatement le droit d'accès de l'utilisateur. Un message SubscriptionNotification de type SUBSCRIPTION_REVOKED est envoyé lorsque cette situation se produit. Lorsque vous recevez cette notification, le champ subscriptionState est défini sur SUBSCRIPTION_STATE_EXPIRED pour la ressource d'abonnement renvoyée par l'API Google Play Developer.

La ressource d'abonnement pour un achat révoqué se présente comme suit :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ]
}

Abonnements différés

Il peut être utile de prolonger les droits d'accès d'un utilisateur pour diverses raisons. Par exemple, vous pouvez offrir aux utilisateurs un accès sans frais en guise de promotion spéciale, par exemple en leur offrant une semaine pour l'achat d'un film, ou à titre de geste commercial. Vous pouvez utiliser la méthode purchases.subscriptions.defer de l'API Play Developer pour anticiper la date de facturation d'un abonnement à renouvellement automatique. Lors de cette opération, un message SubscriptionNotification de type SUBSCRIPTION_DEFERRED est envoyé. Pendant la période de report, l'utilisateur reste abonné à votre contenu avec un accès complet, mais n'est pas facturé. La date de renouvellement de l'abonnement est mise à jour pour refléter la nouvelle date.

Pour les forfaits prépayés, vous pouvez utiliser l'API de facturation différée pour reporter la date d'expiration.

Voici ce à quoi ressemble la ressource d'abonnement pour un abonnement différé :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_future,
      ...
    }
  ],
}

Abonnements suspendus

Pour éviter la perte volontaire d'utilisateurs, vous pouvez les autoriser à suspendre leur abonnement. Lorsque vous activez cette fonctionnalité, les utilisateurs peuvent choisir de suspendre leur abonnement pour une période allant d'une semaine à trois mois, en fonction de la période récurrente.

Récurrence de l'abonnement Toutes les semaines Tous les mois Trois mois Six mois Par an
Durée de pause disponible* 1 semaine
2 semaines
3 semaines
4 semaines
1 mois
2 mois
3 mois
1 mois
2 mois
3 mois
1 mois
2 mois
3 mois
N/A
* Offre susceptible d'être modifiée à tout moment.

La suspension d'un abonnement ne prend effet qu'à la fin de la période de facturation en cours. Lorsque l'abonnement est suspendu, l'utilisateur n'y a pas accès et ne paie pas le prix de renouvellement. À l'issue de la période de suspension, l'abonnement reprend, et Google tente de le renouveler. Si la réactivation aboutit, l'abonnement est réactivé. Si elle échoue en raison d'un problème de paiement, l'utilisateur est soumis à un blocage de compte, comme illustré dans les figures 5 et 6 :

Figure 5 : Un utilisateur suspend son abonnement, puis le réactive
Figure 6. Un utilisateur suspend son abonnement, puis est soumis à un blocage de compte

Un utilisateur peut également choisir de réactiver manuellement un abonnement à tout moment au cours de la période de suspension, comme illustré dans la figure 6. Dans ce cas, la date de facturation est remplacée par la date de réactivation manuelle.

Lorsque l'abonnement d'un utilisateur est suspendu, la bibliothèque Play Billing ne le renvoie pas via la méthode queryPurchasesAsync(). Si l'abonnement est réactivé, la méthode queryPurchasesAsync() le renvoie à nouveau.

Écoutez les notifications RTDN pour savoir quand un utilisateur suspend son abonnement. Ces notifications vous permettent également d'informer les utilisateurs de votre application qu'ils ont suspendu leur abonnement et qu'ils n'y ont pas accès. Vous devez également leur permettre de réactiver manuellement l'abonnement à tout moment via un lien profond vers Google Play.

Un message SubscriptionNotification de type SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED est envoyé lorsque l'utilisateur suspend son abonnement. À ce stade, l'utilisateur doit conserver l'accès à son abonnement jusqu'à la prochaine date de renouvellement, et la ressource d'abonnement contient autoRenewEnabled = true. À ce stade, la valeur du champ subscriptionState est SUBSCRIPTION_STATE_ACTIVE.

Un message SubscriptionNotification de type SUBSCRIPTION_PAUSED est envoyé lorsque la suspension prend effet. Dans ce cas, l'utilisateur doit perdre l'accès à son abonnement. La ressource d'abonnement contient autoRenewEnabled = true, et le champ subscriptionState est défini sur SUBSCRIPTION_STATE_PAUSED. Pour voir la date de renouvellement prévue de l'abonnement, consultez l'objet PausedStateContext.

Un message SubscriptionNotification de type SUBSCRIPTION_RENEWED est envoyé si l'abonnement est réactivé automatiquement à la fin de la période de suspension ou si l'utilisateur choisit de réactiver manuellement l'abonnement. Cette opération doit être gérée comme décrit dans la section Renouvellements.

Un message SubscriptionNotification de type SUBSCRIPTION_ON_HOLD est envoyé en cas d'échec du paiement lors de la réactivation de l'abonnement après une suspension. Cette opération doit être effectuée comme décrit dans la section Blocage de compte.

Se réabonner

Pour les forfaits de base à renouvellement automatique, le Google Play Store peut afficher un bouton Resubscribe (Se réabonner). Ce bouton permet aux utilisateurs de récupérer l'accès à un abonnement. Il peut ne pas s'afficher pour diverses raisons, par exemple lorsqu'un abonnement a expiré depuis longtemps.

Figure 7 : Section Account > Subscriptions (Compte > Abonnements) de l'application Google Play Store affichant un abonnement résilié avec le bouton Resubscribe (Se réabonner).

Bien que le bouton soit toujours intitulé Resubscribe (Se réabonner), son fonctionnement dépend de l'état de l'abonnement.

Si un abonnement a été résilié, mais qu'il n'a pas encore expiré, l'utilisateur reste abonné et bénéficie des avantages de l'abonnement. Si l'utilisateur appuie sur "Resubscribe" (Se réabonner), la résiliation est effectivement annulée et l'abonnement se renouvelle. Dans la documentation pour les développeurs et dans les API Google Play, cette action est appelée restauration.

Une fois qu'un abonnement à renouvellement automatique a expiré, vous pouvez autoriser les utilisateurs à souscrire le même forfait de base. Dans la documentation pour les développeurs et dans les API Google Play, cette action est appelée resubscribe (réabonnement). Vous pouvez configurer cette option pour chaque forfait de base dans la Play Console ou à l'aide de l'API.

Restaurer avant expiration

Si votre application repose uniquement sur la méthode queryPurchasesAsync() pour déterminer si un utilisateur peut accéder à un abonnement, elle doit gérer automatiquement les restaurations, car la méthode queryPurchasesAsync() continue de renvoyer des achats annulés avant leur date d'expiration. Un abonnement restauré continue à être renouvelé comme s'il n'avait pas été résilié.

Si votre application synchronise l'état de l'abonnement avec un backend, vous devez écouter un message SubscriptionNotification de type SUBSCRIPTION_RESTARTED. Une fois que vous avez reçu cette notification RTDN, votre application peut répondre à la notification, enregistrer que l'abonnement est sur le point d'être renouvelé et cesser d'afficher des messages de restauration dans votre application. Voici ce à quoi ressemble la ressource d'abonnement :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date
      ...
    }
  ],
}

Se réabonner après expiration

Si un forfait de base à renouvellement automatique est configuré à l'aide de la Google Play Console ou de l'API pour autoriser le réabonnement, les utilisateurs peuvent racheter un abonnement expiré sur le Google Play Store.

Il s'agit de nouveaux achats. Google Play émet un tout nouveau jeton d'achat, et votre backend reçoit une notification RTDN de type SUBSCRIPTION_PURCHASED. Dans ce cas, l'état de ce type d'achat hors application n'inclut pas de linkedPurchaseToken associé à l'achat d'origine, car l'abonnement d'origine a expiré complètement. Il s'agit de nouveaux achats que votre backend doit traiter et confirmer comme tout autre achat.

Changements de niveau d'abonnement et réabonnements

Lorsqu'un utilisateur passe à un forfait supérieur ou inférieur, ou lorsqu'il se réinscrit à partir de votre application avant l'expiration de l'abonnement, l'ancien abonnement est annulé, tandis qu'un autre abonnement est créé avec un nouveau jeton d'achat.

De plus, la ressource d'abonnement renvoyée par l'API Google Play Developer contient un champ linkedPurchaseToken, qui indique l'ancien achat à partir duquel l'utilisateur a changé de niveau d'abonnement ou s'est réabonné. Vous pouvez utiliser le jeton d'achat dans ce champ pour rechercher l'ancien abonnement et identifier le compte utilisateur existant afin d'associer le nouvel achat au même compte.

Avant de proposer à un utilisateur des options de changement de niveau d'abonnement ou de réabonnement dans votre application, vous devez confirmer l'abonnement existant. Toute modification de forfait ou réabonnement est bloqué si l'abonnement existant est toujours en attente de confirmation.

Si l'utilisateur achète des changements de niveau d'abonnement ou se réabonne, il s'agit d'un nouvel achat que vous devez confirmer. Pour ce faire, nous vous recommandons d'utiliser l'API Google Play Developer. Voici ce à quoi ressemble la ressource d'abonnement :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "linkedPurchaseToken": old_purchase_token,
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

Changements de prix

Consultez le guide des bonnes pratiques pour le changement de prix afin de découvrir comment modifier le prix de l'abonnement à renouvellement automatique et comment informer les utilisateurs, le cas échéant.

Lorsque vous appliquez des changements de prix nécessitant l'acceptation des abonnés existants, vous recevrez une notification RTDN s'ils confirment ou refusent le nouveau prix.

Gérer la confirmation de l'utilisateur en cas de changement de prix

Lorsqu'un utilisateur accepte l'augmentation du prix de votre abonnement, vous recevez un message SubscriptionNotification de type SUBSCRIPTION_PRICE_CHANGED_CONFIRMED. En cas de baisse de prix ne nécessitant pas de confirmation ou en cas de renouvellement après une augmentation du prix de l'abonnement, vous recevez un message SubscriptionNotification de type SUBSCRIPTION_RENEWED. Traitez cette notification comme tout autre renouvellement.

Gérer les cas où une augmentation de prix n'est pas acceptée

Si l'utilisateur n'accepte pas la hausse du prix avant le renouvellement, il est automatiquement désabonné, et vous recevez un message SubscriptionNotification de type SUBSCRIPTION_CANCELED. Gérez cet événement comme décrit dans la section Résiliations.

Les utilisateurs peuvent également résilier leur abonnement en cas d'augmentation du prix, en suivant le même mécanisme.

Gérer le cycle de vie des forfaits prépayés

Comme pour les abonnements à renouvellement automatique, vous devez confirmer les forfaits prépayés après chaque nouvel achat. Dans le cas des forfaits prépayés, vous devez traiter entièrement l'achat initial et les prolongations de l'abonnement, car l'utilisateur doit effectuer le parcours d'achat à chaque fois.

En raison de la courte durée des forfaits prépayés, il est important de confirmer l'achat dès que possible. Les forfaits prépayés d'une durée minimale d'une semaine doivent être confirmés dans un délai de trois jours. Les forfaits prépayés d'une durée inférieure à une semaine doivent être confirmés dans un délai correspondant à la moitié de la durée du forfait. Par exemple, les développeurs ont 1,5 jour pour confirmer l'achat d'un forfait prépayé de trois jours.

Figure 8. États du cycle de vie et événements de transition pour les achats d'abonnement

Un message SubscriptionNotification de type SUBSCRIPTION_PURCHASED est envoyé à votre client RTDN chaque fois qu'un abonnement prépayé est souscrit, y compris pour toute prolongation de cet abonnement. Appelez la méthode purchases.subscriptionsv2.get pour vérifier le dernier état de l'abonnement prépayé.

Un nouveau jeton d'achat est émis pour chaque achat de prolongation d'abonnement prépayé, et vous recevez le jeton d'achat précédent dans le champ linkedPurchaseToken dans le cadre de l'achat du nouvel abonnement. Le jeton d'achat est valide à partir du moment où vous souscrivez un abonnement jusqu'à 60 jours après sa date d'expiration. Au-delà de cette date, il ne pourra plus être utilisé pour appeler l'API Google Play Developer.

Voici ce à quoi ressemble la ressource d'abonnement pour un abonnement prépayé :

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
  "lineItems": [
    {
      "productId": "prepaid_plan01",
      "expiryTime": expiry_date,
      "prepaidPlan": {
        "allowExtendAfterTime": timestamp_after_which_topups_are_allowed
      }
    }
  ]
}

Vous pouvez consulter la date de fin du droit d'accès dans le champ expiryTime. Les achats de prolongation d'abonnement prépayé prolongent la durée de l'abonnement en conséquence. Cela signifie que si l'utilisateur crédite son compte avant que ses droits d'accès d'origine expirent, le nouveau délai est ajouté à la date d'expiration précédente.

Vous pouvez afficher un message dans votre application pour informer l'utilisateur que son abonnement prépayé peut être prolongé. Pour déterminer quand un utilisateur sera en mesure d'acheter une prolongation d'abonnement, consultez le champ allowExtendAfterTime dans la ressource d'abonnement.

Les forfaits prépayés ne peuvent pas être résiliés, car ils ne sont pas renouvelés automatiquement. Si un utilisateur souhaite résilier un forfait prépayé, il peut le laisser arriver à expiration.