MÉTRIQUES DE CHURNGOOGLE PLAY

Suivre le churn avec les notifications en temps réel de Google Play

Mesurer le churn des abonnements Android avec les notifications en temps réel de Google Play : configuration Pub/Sub, sens de chaque événement, indicateurs.

Publié le 7 min de lecture

Google Play informe votre backend des changements d’abonnement via les notifications en temps réel pour les développeurs (real-time developer notifications, RTDN), publiées sur un topic Google Cloud Pub/Sub. Elles sont la base de tout suivi sérieux du churn pour une appli Android : qui a résilié, qui a un problème de facturation, qui a mis en pause, qui est vraiment parti.

Il y a un piège qui conditionne tout le reste : une notification dit seulement que quelque chose a changé. Ce guide couvre la configuration, le traitement de chaque message, la correspondance entre types de notification et indicateurs de churn, et les erreurs qui faussent les chiffres. Il s’appuie sur la documentation de Google : configurer les RTDN, la référence RTDN, le cycle de vie des abonnements et la référence de l’API pour purchases.subscriptionsv2 (tous consultés en novembre 2026).

Configurer les notifications

Le guide de configuration de Google détaille les étapes :

  1. Créez un topic Pub/Sub dans un projet Google Cloud.
  2. Donnez au compte de service google-play-developer-notifications@system.gserviceaccount.com le rôle Pub/Sub Publisher sur le topic.
  3. Créez un abonnement sur le topic : push vers un endpoint HTTPS de votre backend, ou pull depuis un worker.
  4. Dans la Play Console, saisissez le nom du topic pour votre appli et cliquez sur Send Test Message.
  5. Choisissez les types de notification : abonnements et achats annulés seulement, ou tout, y compris les produits ponctuels.

Accusez réception de chaque message. Pour les abonnements pull, Google indique d’accuser réception des messages récupérés « pour éviter une livraison répétée par Cloud Pub/Sub » ; pour le push, un code de réponse de succès vaut accusé de réception.

Traiter un message

Chaque message Pub/Sub a un champ data en base64. Décodé, il contient version, packageName, eventTimeMillis et exactement un élément parmi subscriptionNotification, oneTimeProductNotification, voidedPurchaseNotification, pendingRefundReviewNotification ou testNotification.

Une notification d’abonnement ne porte qu’un notificationType et un purchaseToken. La référence de Google est explicite : vous « devez appeler la Google Play Developer API après avoir reçu des notifications en temps réel pour obtenir le statut complet », parce que les notifications « ne vous donnent pas d’informations complètes sur l’achat ». Le guide du cycle de vie qualifie purchases.subscriptionsv2.get de « source de vérité pour la gestion des abonnements ».

La chaîne de traitement est donc :

  1. Recevoir, vérifier les doublons sur messageId (Google le recommande), stocker le message brut, accuser réception.
  2. Appeler purchases.subscriptionsv2.get avec le purchase token.
  3. Stocker l’état obtenu sous forme d’instantané, avec le type de notification et eventTimeMillis.
  4. Mettre à jour vos droits d’accès et vos indicateurs à partir de l’instantané, pas de la notification seule.

Gardez en tête que le purchase token ne fonctionne que jusqu’à 60 jours après l’expiration. Récupérez l’état à l’arrivée de la notification, pas des semaines plus tard.

Les types de notification d’abonnement

D’après la référence RTDN :

Code Type Ce qui s’est passé
1 SUBSCRIPTION_RECOVERED Rétabli après un account hold, ou reprise après une pause
2 SUBSCRIPTION_RENEWED Un abonnement actif s’est renouvelé
3 SUBSCRIPTION_CANCELED Résilié, volontairement ou non
4 SUBSCRIPTION_PURCHASED Nouvel abonnement acheté
5 SUBSCRIPTION_ON_HOLD Entré en account hold
6 SUBSCRIPTION_IN_GRACE_PERIOD Entré en grace period
7 SUBSCRIPTION_RESTARTED L’utilisateur a restauré un abonnement résilié pas encore expiré
9 SUBSCRIPTION_DEFERRED Date de renouvellement repoussée
10 SUBSCRIPTION_PAUSED La pause a pris effet
11 SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED Pause programmée ou modifiée
12 SUBSCRIPTION_REVOKED Révoqué avant l’expiration
13 SUBSCRIPTION_EXPIRED Expiré
18 SUBSCRIPTION_CANCELLATION_SCHEDULED Résiliation d’un paiement échelonné programmée pour la fin de l’engagement
20 SUBSCRIPTION_PENDING_PURCHASE_CANCELED Une transaction en attente a été annulée

Il en existe quelques autres (éléments modifiés, mises à jour de changement de prix, consentement à une hausse de prix par paliers). Le code 8 est obsolète.

Les états qui comptent pour le churn

Le champ subscriptionState de l’API est plus fiable que le type de notification pour compter. Le guide du cycle de vie décrit ce que chaque état signifie pour l’accès :

État L’utilisateur a-t-il accès ? Signification pour le churn
SUBSCRIPTION_STATE_ACTIVE Oui Abonné
SUBSCRIPTION_STATE_IN_GRACE_PERIOD Oui À risque : paiement échoué
SUBSCRIPTION_STATE_ON_HOLD Non À risque : paiement échoué, accès bloqué
SUBSCRIPTION_STATE_PAUSED Non En pause, pas parti
SUBSCRIPTION_STATE_CANCELED Jusqu’à expiryTime À risque : renouvellement arrêté
SUBSCRIPTION_STATE_EXPIRED Non Parti

La grace period et l’account hold ont des valeurs par défaut à connaître. La grace period est activée par défaut sur tous les forfaits de base à renouvellement automatique. L’account hold est aussi activé par défaut, avec une durée que Google calcule comme 60 jours moins la grace period. Les deux se modifient dans la Play Console. Avant le début de l’account hold, Google fait des tentatives de débit supplémentaires pendant jusqu’à 48 heures.

Des événements aux indicateurs de churn

Compter le churn à l’expiration

SUBSCRIPTION_CANCELED signifie que le renouvellement s’est arrêté, pas que l’utilisateur est parti. Il garde l’accès jusqu’à expiryTime, et peut restaurer son abonnement (SUBSCRIPTION_RESTARTED). Comptez le churn sur SUBSCRIPTION_EXPIRED, et utilisez les résiliations comme indicateur avancé.

Séparer churn volontaire et involontaire

Le canceledStateContext de la ressource d’abonnement indique qui a résilié :

  • userInitiatedCancellation : volontaire. Il peut aussi contenir la réponse de l’utilisateur à l’enquête de résiliation.
  • systemInitiatedCancellation : résilié par le système, « par exemple à cause d’un problème de facturation ». C’est votre churn involontaire.
  • developerInitiatedCancellation : vous avez résilié.
  • replacementCancellation : remplacé par un nouvel abonnement, par exemple après un changement d’offre. Ce n’est pas du churn.

Le chemin de la facturation a une séquence reconnaissable : SUBSCRIPTION_IN_GRACE_PERIOD, puis SUBSCRIPTION_ON_HOLD, puis soit SUBSCRIPTION_RECOVERED, soit, à la fin de l’account hold, SUBSCRIPTION_CANCELED immédiatement suivi de SUBSCRIPTION_EXPIRED.

Ne pas compter les pauses comme du churn

SUBSCRIPTION_RECOVERED est envoyé à la fois quand un abonnement sort de l’account hold et quand il reprend après une pause. Vérifiez l’état précédent avant de le compter comme une récupération de facturation.

Gérer les changements d’offre et les réinscriptions

Les montées en gamme, les passages à une offre inférieure et les réinscriptions dans l’appli avant l’expiration créent un nouvel achat avec un nouveau token. Le nouvel abonnement a un linkedPurchaseToken qui pointe vers l’ancien. Si vous ne suivez pas ces liens, chaque changement d’offre ressemble à un abonné parti et un nouvel abonné.

Les réinscriptions depuis le Play Store après l’expiration sont différentes : Google indique qu’elles ne portent pas de linkedPurchaseToken, mais la réponse de l’API inclut outOfAppPurchaseContext avec le token expiré tant que vous n’avez pas accusé l’achat. Comptez-les comme des réactivations.

Les révocations

SUBSCRIPTION_REVOKED signifie que l’accès a pris fin plus tôt : vous l’avez révoqué, ou l’achat a fait l’objet d’un chargeback. L’état passe à expiré. Rapportez-le à part du churn normal, avec les achats annulés.

Un rapport mensuel

  1. Actifs en début de période : abonnements aux états actif, grace period, ou résilié mais pas encore expiré.
  2. Churn volontaire : expirations dont le contexte est initié par l’utilisateur.
  3. Churn involontaire : expirations dont le contexte est initié par le système.
  4. Taux de récupération de facturation : abonnements entrés en grace period ou en account hold puis rétablis, rapportés à tous ceux qui y sont entrés.
  5. Restaurations : SUBSCRIPTION_RESTARTED.
  6. En pause : nombre, et combien reprennent.
  7. Réactivations : réinscriptions depuis le Play Store et réinscriptions dans l’appli après l’expiration.

Les formules générales se trouvent dans comment calculer le taux de churn.

Erreurs courantes

  • Se fier au seul type de notification. Récupérez toujours l’état de l’abonnement.
  • Compter les résiliations comme du churn. Cela gonfle le churn et masque les restaurations.
  • Ignorer les linked purchase tokens. Les changements d’offre deviennent du faux churn.
  • Appeler l’API trop tard. Les tokens cessent de fonctionner 60 jours après l’expiration.
  • Ne pas accuser réception des messages Pub/Sub. Vous recevez des doublons et gaspillez votre quota d’API.
  • Pas d’ID de compte obfusqué à l’achat. Vous ne pouvez pas croiser les données de Play avec vos propres données utilisateur.

Le faire avec NoChurn

Vous dirigez vos notifications en temps réel Play vers NoChurn et lui donnez un compte de service ayant accès à votre Play Console. NoChurn récupère l’état de l’abonnement pour chaque événement, suit les linked purchase tokens, sépare churn volontaire, churn de facturation et révocations, et tient une chronologie par client, rattachée grâce à l’ID de compte obfusqué que vous définissez à l’achat. Grace period, account hold et résiliations alimentent le score de churn de 0 à 100, et vous pouvez ajouter vos propres attributs par API. Google garde les paiements, les relances et le bouton de résiliation. Voir NoChurn + Google Play.

PROMPT

Read https://www.nochurn.sh/llms.txt,
then follow https://www.nochurn.sh/docs/quickstart/
to add NoChurn to this app. Use a test key
(nc_test_…) until I say we go live.

Arrêtez de perdre du revenu.

  • Gratuit jusqu’à $300 de MRR
  • Sans carte bancaire
  • Prêt en 10 minutes
  • Jamais une commission sur ce que nous récupérons