La Retention Messaging API d'Apple place vos mots sur l'écran de résiliation, mais les demandes de remboursement n'y passent jamais
La Retention Messaging API d'Apple vous permet d'afficher un message, un changement de formule ou une offre promotionnelle quand un abonné touche Annuler. Voici comment elle fonctionne, ce qu'elle coûte à faire tourner et pourquoi une demande de remboursement arrive chez Apple sans jamais passer par cet écran.

Points clés
- La Retention Messaging API d'Apple permet au développeur de choisir le message qu'un abonné iPhone voit après avoir touché Cancel Subscription (Résilier l'abonnement), parmi quatre types : texte, texte avec image, suggestion de changement de formule ou offre promotionnelle.
- La documentation d'Apple décrit toujours la Retention Messaging API comme une préversion que les développeurs demandent à rejoindre. La version 1.0 est sortie le 16 juillet 2025, suivie de la version 1.5 le 27 avril 2026.
- Dans le flux en temps réel, Apple appelle l'endpoint Get Retention Message du développeur quand un abonné actif consulte une page de détails d'abonnement comportant un bouton Annuler. L'endpoint doit répondre en 700 ms en production, sinon Apple se rabat sur un message par défaut.
- Un message de rétention n'agit que sur les renouvellements futurs. Une demande de remboursement parvient à Apple via reportaproblem.apple.com ou la fiche de remboursement dans l'app, et l'écran de résiliation où s'affichent les messages de rétention ne fait pas partie de ce parcours.
- Quand un client demande un remboursement dans une app via l'API de demande de remboursement de StoreKit, Apple désactive elle-même le renouvellement automatique et envoie DID_CHANGE_RENEWAL_STATUS avec le sous-type AUTO_RENEW_DISABLED, soit le même type et le même sous-type qu'une résiliation depuis la page de réglages Abonnements.
- La seule contribution du développeur à un remboursement Apple est le CONSUMPTION_REQUEST, auquel il répond dans les 12 heures avec Send Consumption Information, et seulement si le client a consenti au partage de ces données.
- Google Play n'a pas d'équivalent documenté d'un message choisi par le développeur sur l'écran de résiliation. Les développeurs reçoivent ensuite une notification SUBSCRIPTION_CANCELED, et le champ userInitiatedCancellation leur indique pourquoi l'abonné est parti.
Les abonnés qui touchent Annuler sur un iPhone peuvent désormais voir un message que vous avez choisi, une formule moins chère ou une remise, avant de confirmer. C'est la Retention Messaging API d'Apple, et c'est la première fois qu'un développeur a son mot à dire sur l'écran de résiliation d'Apple lui-même. Elle reste une préversion à laquelle il faut demander l'accès. Elle a aussi une limite nette qui compte si les remboursements vous concernent : elle s'adresse aux personnes qui s'apprêtent à arrêter de payer, pas à celles qui réclament leur argent. Ces demandes arrivent chez Apple par un autre chemin.
Ce que fait la Retention Messaging API d'Apple
La Retention Messaging API est un service de serveur à serveur. Vous envoyez à l'avance à Apple les textes et les images de vos messages, Apple les examine, puis vous choisissez quel message approuvé un abonné voit au moment de résilier un abonnement à renouvellement automatique. La documentation d'Apple liste quatre types de message :
- Un message texte, qui peut contenir des puces.
- Un message texte avec une image.
- Un message de changement de formule, qui suggère un autre abonnement du même groupe d'abonnements.
- Un message d'offre promotionnelle, qui propose un prix réduit au même niveau ou à un autre, à l'aide d'une offre promotionnelle que vous configurez dans App Store Connect et signez sur votre serveur.
Le message apparaît après que le client a touché Cancel Subscription sur une page de détails d'abonnement. Apple affiche ensuite une page Confirm Cancellation (Confirmer la résiliation). Le client peut toujours résilier, toucher Keep Subscription (Conserver l'abonnement) ou accepter l'offre ou la formule que vous avez suggérée. Vous ne pouvez pas masquer la sortie, et Apple demande aux développeurs de ne pas envoyer de contenu trompeur ou inexact.
Messages par défaut et flux en temps réel
Il y a deux façons de l'utiliser. La plus simple, ce sont les messages par défaut : du texte, avec ou sans image ou puces, attribué à chaque produit et à chaque langue. La plus riche est le flux en temps réel, où Apple appelle un endpoint Get Retention Message sur votre serveur et où vous répondez avec un identifiant de message. Seul le flux en temps réel peut afficher les messages de changement de formule et d'offre promotionnelle.
En pratique, les messages par défaut ne sont pas facultatifs. Apple s'en sert comme solution de repli chaque fois qu'un appel en temps réel échoue, et n'affiche aucun message de rétention pour un produit dans une langue qui n'a pas de message par défaut.
| Élément | Ce que dit la documentation d'Apple |
|---|---|
| Statut | Préversion, les développeurs manifestent leur intérêt pour y participer |
| Produits | Abonnements à renouvellement automatique |
| Types de message | Texte, texte avec image, changement de formule, offre promotionnelle |
| Délai de réponse en temps réel | 700 ms en production |
| Accès à la production | Réussir d'abord un test de performance en sandbox, d'environ 700 ms |
| Texte d'en-tête et des puces | 66 caractères chacun, jusqu'à cinq puces |
| Texte principal | 144 caractères |
| Texte alternatif de l'image | 150 caractères |
| Messages par app | 2 000 |
| Validation | Les nouveaux messages démarrent en PENDING et ne s'affichent qu'une fois APPROVED |
| Appareils | iOS 15.1, iPadOS 15.1, visionOS 1, macOS 14 ou version ultérieure |
Ce qu'Apple transmet à votre serveur lors de l'appel en temps réel
La requête est un JWS signé par l'App Store. Une fois décodée, elle contient originalTransactionId, appAppleId, productId, userLocale, un requestIdentifier UUID, l'environnement et signedDate. Apple vous demande de vérifier que appAppleId correspond à votre app et de ne pas répondre si ce n'est pas le cas. L'élément utile est originalTransactionId, car il vous permet de retrouver ce que cet abonné a réellement fait dans votre app avant de choisir quoi lui dire.
Où le message de rétention apparaît, et où il n'apparaît pas
Apple place le message sur un seul écran, l'étape Confirm Cancellation après que le client a touché Cancel Subscription, par exemple depuis Apple Account > Subscriptions ou depuis la page d'un abonnement sur l'App Store. Cet écran porte sur le fait que le prochain renouvellement ait lieu ou non. Il ne touche pas à l'argent déjà encaissé.
Une demande de remboursement est un acte distinct. La page d'assistance d'Apple renvoie les clients vers reportaproblem.apple.com, où ils choisissent « Request a refund » (Demander un remboursement), sélectionnent un motif et un article, puis attendent 24 à 48 heures une mise à jour. Dans votre app, beginRefundRequest de StoreKit ouvre la fiche de remboursement d'Apple, et Apple indique que l'App Store met jusqu'à 48 heures pour accepter ou refuser. Aucun de ces deux chemins ne passe par l'écran Confirm Cancellation.
| Moment | Où cela se passe | Ce qui est en jeu | Qui décide | Votre contribution |
|---|---|---|---|---|
| Résiliation | Page de détails de l'abonnement, puis Confirm Cancellation | Renouvellements futurs | Le client | Un message de rétention que vous choisissez, renvoyé en 700 ms |
| Demande de remboursement | reportaproblem.apple.com ou la fiche de remboursement de votre app | Argent déjà payé | Apple | Données du CONSUMPTION_REQUEST sous 12 heures, si le client a donné son consentement |
Un message de rétention peut-il bloquer une demande de remboursement ?
Non. La demande de remboursement n'atteint jamais l'écran où se trouve le message. Un détail de la documentation des notifications d'Apple le rend concret. Quand un client demande un remboursement depuis votre app avec l'API de demande de remboursement, Apple désactive elle-même le renouvellement automatique et envoie DID_CHANGE_RENEWAL_STATUS avec le sous-type AUTO_RENEW_DISABLED. Un client qui résilie depuis la page de réglages Abonnements produit le même type et le même sous-type. Votre serveur voit une seule notification pour deux clients très différents, et un seul d'entre eux a vu votre message de rétention.
Si la demande de remboursement se poursuit, le canal de preuves est le CONSUMPTION_REQUEST. Apple l'envoie pour les demandes de remboursement sur tout type de produit, et vous avez 12 heures pour répondre avec Send Consumption Information. Vous ne pouvez répondre que si le client a donné son consentement. Ensuite, la décision d'Apple arrive sous forme de notification REFUND, ou REFUND_DECLINED si Apple refuse un remboursement que le client a lancé dans votre app.
Google Play propose-t-il une API de message de résiliation ?
Pas dans la documentation de Google sur le cycle de vie des abonnements. Un abonné Google Play résilie depuis le centre des abonnements de Play, garde l'accès jusqu'à la fin de la période de facturation en cours et peut toucher Resubscribe (Se réabonner) pour annuler sa résiliation avant cette date, ce que Google appelle une restauration. Vous l'apprenez après coup par une notification SUBSCRIPTION_CANCELED, et le champ userInitiatedCancellation de la ressource d'abonnement vous indique pourquoi l'utilisateur est parti. La mise en pause, activée par défaut pour tous les abonnements selon Google, est son principal outil intégré pour réduire la résiliation volontaire.
Côté remboursements, Google Play a son propre canal de preuves. Une PendingRefundReviewNotification arrive quand une rétrofacturation nécessite l'examen du développeur, et vous avez 24 heures pour répondre via orders.reviewrefund. Pour les commandes passées après le 3 août 2026, lorsqu'une rétrofacturation aboutit, Google répercute sur le développeur le prix d'achat, moins les frais de service de Play, plus les frais de rétrofacturation de la banque.
Ce que l'écran de résiliation vous coûte en argent
Les messages de rétention semblent gratuits. Ils ne le sont pas, et la facture arrive de trois côtés.
Du calcul à chaque affichage de page
Apple appelle votre endpoint quand un abonné actif consulte une page de détails d'abonnement comportant un bouton Annuler, pas seulement quand il résilie. Chaque visite est une requête que votre serveur doit authentifier, traiter et à laquelle il doit répondre en 700 ms, sinon Apple se rabat sur le message par défaut. Cela exclut une fonction à démarrage à froid qui met parfois deux secondes. Vous payez une capacité qui reste toujours disponible, plus les lectures en base de données et les appels payants à des API tierces que votre logique de décision effectue à chaque requête.

La remise est un revenu que vous avez choisi de ne pas encaisser
Une offre promotionnelle qui retient un abonné, c'est de l'argent réellement conservé. Une offre qui va à quelqu'un qui serait resté de toute façon, c'est une remise pure. Voici une illustration, pas une référence. Une formule mensuelle à 9,99 $ proposée à moitié prix pendant trois mois abandonne 14,99 $ par offre acceptée. Si une personne sur trois qui acceptent serait restée au plein tarif, mille acceptations coûtent environ 5 000 $ de remises accordées à des gens qui n'en avaient pas besoin. L'autre côté du bilan, ce sont les abonnés qui partaient vraiment.
Le remboursement qu'une sortie pénible encourage
Apple laisse le bouton Cancel Subscription sur la page, vous ne pouvez donc piéger personne, mais vous pouvez quand même être agaçant. Un client qui se sent poussé a une autre option : demander à Apple de lui rendre le dernier prélèvement. Quand un remboursement a lieu, l'argent repart, et le calcul, le stockage, les appels d'API et les éventuelles commissions d'affiliation liés à cet abonné restent dépensés. Ce sont des coûts qu'aucun message de rétention ne récupère.
Utiliser les messages de rétention sans faire monter votre taux de remboursement
Considérez l'écran de résiliation comme un endroit où être exact, pas habile. Quelques règles le maintiennent du bon côté de la ligne des remboursements :
- Décidez abonné par abonné. Utilisez l'originalTransactionId de la requête d'Apple pour consulter l'usage récent. Proposez une remise ou une formule moins chère à ceux qui utilisent le produit. Affichez un message court et honnête à ceux qui ne l'ont pas ouvert depuis des semaines.
- Répondez vite. Calculez la décision à l'avance quand vos données d'usage changent, pour que la requête elle-même se résume à une seule lecture qui tient largement dans 700 ms.
- Rédigez un message par défaut pour chaque produit et chaque langue. Sans lui, un appel qui échoue signifie aucun message.
- Surveillez de près AUTO_RENEW_DISABLED. Si un CONSUMPTION_REQUEST suit pour le même originalTransactionId, vous avez affaire à une demande de remboursement, pas à une résiliation, et le compte à rebours de 12 heures a commencé.
- Répondez à chaque CONSUMPTION_REQUEST auquel vous en avez le droit. RefundHalt envoie à Apple des données de consommation exactes dans le délai de 12 heures et répond à l'examen des rétrofacturations de Google Play sous 24 heures, car ce sont les deux seuls moments où l'un ou l'autre store demande votre version des faits.
Vaut-il la peine de demander l'accès à Apple ?
Si vous vendez des abonnements à renouvellement automatique et que vous traitez déjà les App Store Server Notifications V2, probablement oui. L'écran de résiliation est le dernier endroit où vous pouvez toucher un abonné avant son départ, et un changement de formule vous coûte moins cher que de le perdre complètement. Prévoyez simplement le budget d'un endpoint qui répond à chaque affichage de page d'abonnement, et gardez vos défenses contre les remboursements là où les remboursements se produisent vraiment.
Questions fréquentes
- Qu'est-ce que la Retention Messaging API d'Apple ?
- C'est une API de serveur à serveur qui permet au développeur de choisir le message qu'un abonné voit après avoir touché Cancel Subscription sur un abonnement à renouvellement automatique. Apple prend en charge quatre types : texte, texte avec image, suggestion de changement de formule et offre promotionnelle. La documentation d'Apple la décrit toujours comme une préversion que les développeurs demandent à rejoindre.
- En combien de temps mon endpoint Get Retention Message doit-il répondre ?
- En 700 ms en production. Si votre serveur est plus lent ou échoue, Apple affiche le message par défaut configuré pour ce produit et cette langue, et n'affiche rien s'il n'en existe pas. Vous devez aussi réussir un test de performance en sandbox, d'environ 700 ms, avant qu'Apple vous laisse définir une URL de production.
- Un message de rétention apparaît-il quand un client demande un remboursement ?
- Non. Apple affiche les messages de rétention sur l'écran Confirm Cancellation après que le client a touché Cancel Subscription. Les demandes de remboursement passent par reportaproblem.apple.com ou par la fiche de remboursement dans l'app ouverte par beginRefundRequest, et la seule contribution du développeur à ce stade est le CONSUMPTION_REQUEST, auquel il répond dans les 12 heures si le client a donné son consentement.
- Comment distinguer une demande de remboursement d'une résiliation dans les App Store Server Notifications ?
- Pas avec la seule notification de renouvellement. Une résiliation depuis la page de réglages Abonnements et une demande de remboursement faite depuis votre app produisent toutes deux DID_CHANGE_RENEWAL_STATUS avec le sous-type AUTO_RENEW_DISABLED. Un CONSUMPTION_REQUEST pour la même transaction, puis une notification REFUND ou REFUND_DECLINED, montrent qu'une demande de remboursement est en cours.
- Google Play permet-il aux développeurs d'afficher un message quand les utilisateurs résilient ?
- La documentation de Google sur le cycle de vie des abonnements n'en décrit aucun. Les développeurs reçoivent une notification SUBSCRIPTION_CANCELED après coup et peuvent lire le champ userInitiatedCancellation pour savoir pourquoi l'utilisateur a résilié. La mise en pause, activée par défaut pour tous les abonnements, est le principal outil intégré de Google Play contre la résiliation volontaire.
Sources et lectures complémentaires
- Apple Developer Documentation: Retention Messaging API
- Apple Developer Documentation: Setting up your Get Retention Message endpoint
- Apple Developer Documentation: Upload Message
- Apple Developer Documentation: Retention Messaging API changelog
- Apple Developer Documentation: notificationType
- Apple Developer Documentation: Send Consumption Information
- Apple Support: Request a refund for apps or content that you bought from Apple
- Google Play Billing: Subscription lifecycle
- Google Play Billing: Real-time developer notifications reference
- Google Play Console Help: Updates to refund protection and chargeback cost responsibility
RefundHalt
Le pilote automatique des remboursements pour l'App Store et Google Play
Poursuivre la lecture
Le ROAS de votre app compte encore les achats qu'Apple et Google ont remboursés, alors enchérissez sur le ROAS net
Les remboursements remontent rarement aux plateformes publicitaires, si bien que le ROAS continue de créditer des achats qu'Apple et Google ont déjà remboursés. Voici où Firebase, Google Ads et AdAttributionKit perdent les remboursements, ce que cela coûte et comment construire le ROAS net d'une app.
L'order ID sur le reçu App Store d'un client vous dit ce qu'il a acheté et si Apple l'a déjà remboursé
Le endpoint Look Up Order ID d'Apple transforme l'order ID du reçu App Store d'un client en transactions signées, avec les dates et motifs de remboursement. Comment l'utiliser face aux e-mails de remboursement, ce qu'il ne fait pas, et la comparaison avec l'order ID de Google Play.