Tous les articles
Deep dive7 min de lecture

Votre app peut afficher une feuille de demande de remboursement dans l'app, et voici ce qu'Apple fait après que le client a touché envoyer

La demande de remboursement dans l'app d'Apple permet à un client de demander un remboursement sans quitter votre app, sur une feuille qu'Apple construit et examine. Voici ce que renvoie beginRefundRequest, les horloges du CONSUMPTION_REQUEST et des 48 heures qu'elle déclenche sur votre serveur, et si le bouton vaut la peine d'être publié.

Une main tenant un smartphone qui affiche un écran de réglages de compte à côté d'un reçu papier et d'une pièce, illustrant une demande de remboursement dans l'app qu'un client peut lancer sans quitter l'app

Points clés

  • beginRefundRequest d'Apple est une méthode StoreKit 2 qui présente la propre feuille de remboursement d'Apple à l'intérieur de votre app. Le client voit les détails de son achat et une liste de codes de motif, en choisit un, et la demande part chez Apple. Vous ne construisez pas le formulaire et ne décidez pas du résultat.
  • L'appel renvoie un statut success ou userCancelled, ou lève duplicateRequest ou failed. Un statut success signifie que l'App Store a reçu la demande, pas qu'il l'a approuvée. N'affichez jamais un remboursement confirmé dans votre interface sur success.
  • Après l'envoi par le client, Apple prend jusqu'à 48 heures pour approuver ou refuser. Pour les achats consommables, elle envoie d'abord un CONSUMPTION_REQUEST à votre serveur, et vous disposez des 12 heures habituelles pour répondre avec des données d'usage si le client a donné son consentement.
  • Le résultat arrive sur votre serveur sous forme d'App Store Server Notification, le même flux que vous recevez déjà. L'approbation est une notification REFUND, le refus est REFUND_DECLINED. La demande dans l'app est routée vers ce flux exactement comme un remboursement lancé depuis la page reportaproblem d'Apple.
  • Le bouton est disponible à partir d'iOS 15 et iPadOS 15, Mac Catalyst 15 et visionOS 1, donc toute app ciblant ces versions peut le présenter dès aujourd'hui.
  • L'argument financier est qu'un remboursement que vous pouvez contester vaut mieux qu'un chargeback que vous ne pouvez pas contester. Garder le client dans le flux d'Apple déclenche un CONSUMPTION_REQUEST auquel vous pouvez répondre, au lieu d'un chargeback bancaire qui est définitif et comporte des frais.
  • La recommandation de placement d'Apple est de l'appeler depuis les réglages de compte ou un menu d'aide, pas depuis un écran d'achat, pour qu'un client mécontent le trouve sans annoncer les remboursements à tous les autres.

Apple permet à un client de demander un remboursement sans jamais quitter votre app. Un seul appel StoreKit, beginRefundRequest, présente la propre feuille de remboursement d'Apple directement dans votre interface, le client choisit un motif, et la demande part chez Apple pour examen. Vous ne construisez pas le formulaire, vous ne touchez pas à l'argent, et vous ne décidez pas du résultat. Ce que vous obtenez, c'est un moyen de placer un chemin de remboursement là où le client frustré se trouve déjà, plutôt que de le perdre au profit de sa banque. Voici la demande de remboursement dans l'app, et il vaut la peine de la comprendre avant de décider de publier le bouton.

Voici la partie qui compte pour votre chiffre d'affaires. Le bouton ne rembourse rien de lui-même. Il ouvre une demande, Apple prend jusqu'à 48 heures pour l'approuver ou la refuser, et pour les achats consommables elle déclenche d'abord un CONSUMPTION_REQUEST vers votre serveur. La feuille n'est donc pas un cadeau. C'est un entonnoir vers l'examen de remboursement exact que vous pouvez déjà influencer, et il peut ramener un litige du réseau de cartes avant qu'il ne devienne un chargeback que vous ne pouvez pas contester.

Ce qu'est réellement la feuille de demande de remboursement dans l'app

beginRefundRequest est une méthode StoreKit 2 qui présente la feuille de demande de remboursement pour une transaction dans une scène de fenêtre. La signature est courte : func beginRefundRequest(in scene: UIWindowScene) async throws -> Transaction.RefundRequestStatus. Quand vous l'appelez, le système affiche une feuille avec les détails de l'achat du client et une liste de codes de motif parmi lesquels choisir. Apple construit et contrôle cette interface. Vous fournissez la scène et la transaction, rien de plus.

La recommandation d'Apple sur l'endroit où le placer est explicite. Appelez cette fonction depuis les réglages de compte ou un menu d'aide, pour qu'un client qui veut un remboursement le trouve là où il chercherait de l'aide. Elle est arrivée dans iOS 15 et iPadOS 15, Mac Catalyst 15 et visionOS 1, donc toute app ciblant ces versions peut le présenter dès aujourd'hui.

Deux façons d'ouvrir la feuille

Il y a deux points d'entrée. Vous pouvez appeler beginRefundRequest(in:) sur une transaction précise que vous détenez déjà, ce qui limite la feuille à cet achat. Vous pouvez aussi ouvrir la feuille par identifiant de produit lorsque vous voulez que le client rembourse l'achat d'un produit donné. Dans les deux cas, la feuille, la liste des motifs et la décision appartiennent à Apple. Votre travail s'arrête à la présenter et à lire le résultat.

Ce que l'appel renvoie, et ce qui peut mal tourner

La méthode est async throws, donc elle renvoie soit un statut soit lève une erreur. Les deux sont des listes courtes, et les deux méritent d'être gérées pour que votre interface dise quelque chose de vrai une fois la feuille fermée.

RésultatTypeCe que cela signifie
successRefundRequestStatusL'App Store a reçu la demande de remboursement. Elle est soumise, pas approuvée
userCancelledRefundRequestStatusLe client a fermé la feuille sans envoyer. Rien n'a été transmis
duplicateRequestRefundRequestErrorL'App Store a déjà une demande de remboursement pour cet achat
failedRefundRequestErrorL'envoi lui-même a échoué. Laissez le client réessayer

Ce qui se passe sur votre serveur après que le client a touché envoyer

La fermeture de la feuille est le début du processus, pas la fin. Apple examine la demande et prend jusqu'à 48 heures pour l'approuver ou la refuser. Pour un achat intégré consommable, avant de décider, l'App Store envoie une notification CONSUMPTION_REQUEST à votre serveur pour demander des données d'usage. Si le client a consenti à partager ces données, vous répondez via l'endpoint Send Consumption Information. S'il n'a pas consenti, l'instruction d'Apple elle-même est de ne pas répondre à la notification du tout.

Une fois qu'Apple tranche, le résultat atterrit sur votre serveur sous forme d'App Store Server Notification. C'est le même flux que vous recevez déjà, et la demande dans l'app y est routée exactement comme un remboursement qu'un client lance depuis la page reportaproblem d'Apple. Rien dans le traitement ne change simplement parce que la demande a commencé à l'intérieur de votre app.

ÉtapeCe qui se déclencheVotre actionHorloge
Le client envoie la feuillebeginRefundRequest renvoie successEnregistrez-le, affichez en attente, pas rembourséInstantané
Consommables uniquement, Apple demande d'abordnotification CONSUMPTION_REQUESTEnvoyez les données de consommation si le client a consenti, sinon gardez le silence12 heures pour répondre
Apple approuvenotification REFUNDRévoquez le droit de cette transactionJusqu'à 48 heures pour décider
Apple refusenotification REFUND_DECLINEDGardez la vente, ne changez rienJusqu'à 48 heures pour décider
Un sablier à côté d'un smartphone et d'un reçu papier, illustrant l'attente pouvant aller jusqu'à 48 heures après qu'un client a envoyé une demande de remboursement dans l'app à Apple

Ce que le bouton vous coûte, et ce qu'il peut vous faire économiser

Un remboursement que vous pouvez contester vaut mieux qu'un chargeback que vous ne pouvez pas

Un client qui ne trouve pas de chemin de remboursement dans votre app n'abandonne pas. Il va à sa banque. Un chargeback de carte est définitif avec la banque, il comporte des frais de litige, et il retire la décision de vos mains comme de celles d'Apple. Une demande de remboursement dans l'app garde ce même client dans le système d'Apple, où un achat consommable déclenche un CONSUMPTION_REQUEST auquel vous pouvez répondre et une décision que vous pouvez influencer. Échanger un chargeback incontestable contre un examen contestable d'Apple, c'est tout l'argument financier en faveur du bouton.

Vous réduisez la friction sur un remboursement

Le contrepoids honnête, c'est qu'un chemin de remboursement visible et en un toucher produit plus de demandes de remboursement qu'un e-mail de support enterré. Certaines n'auraient jamais eu lieu. C'est un coût réel, et c'est pourquoi Apple vous dit de placer le point d'entrée dans les réglages de compte ou un menu d'aide plutôt que sur l'écran d'achat. Vous voulez que le client déjà mécontent le trouve, pas le client qui est simplement curieux.

Le coût qui court tout le temps, c'est servir un compte remboursé

Quel que soit le sens de la décision, le compteur de la livraison continue de tourner jusqu'à ce que vous agissiez sur le résultat. Chaque heure où un droit remboursé reste actif, vous continuez de payer les coûts réels qui le sous-tendent : calcul, appels à l'API du modèle, stockage, et tout paiement à un créateur ou partenaire lié à l'usage de ce client. La demande dans l'app ne change rien à cela. Révoquer promptement sur la notification REFUND, si. Le bouton n'est aussi bon marché que votre traitement de la notification qu'il finit par produire.

Devriez-vous publier la demande de remboursement dans l'app ?

Placez-la là où vit le support, pas là où vivent les ventes

Suivez la recommandation de placement d'Apple. Les réglages de compte et un menu d'aide sont les bons foyers. Un lien de remboursement à côté d'un paywall entraîne les gens à s'attendre à récupérer leur argent, et invite le remboursement de curiosité que vous n'aviez jamais eu besoin d'offrir.

Testez le flux complet dans le sandbox avant de lui faire confiance

Vous pouvez simuler tout le parcours dans le sandbox et dans le test StoreKit de Xcode, en faisant passer une demande de en attente à approuvée ou refusée. Une approbation livre une notification REFUND à votre serveur, et un refus livre REFUND_DECLINED, vous pouvez donc prouver que votre gestionnaire réagit correctement avant qu'un vrai client ne touche envoyer.

Gérez chaque résultat, et ne surenchérissez jamais

Affichez en attente sur success, proposez un réessai sur failed, dites que rien n'a changé sur userCancelled, et traitez duplicateRequest comme une note discrète indiquant que la demande antérieure du client tient toujours. La seule erreur qui fait mal, c'est de dire à un client que son remboursement est fait alors que tout ce que vous détenez est une demande soumise.

Comment RefundHalt gère la suite

La feuille dans l'app appartient à Apple. Ce qui vient après vous appartient, et c'est la partie que RefundHalt exécute. Quand un client envoie un remboursement depuis l'intérieur de votre app, RefundHalt attrape le CONSUMPTION_REQUEST pour les achats consommables et y répond dans la fenêtre de 12 heures avec la preuve d'usage qui aide Apple à décider. Quand Apple tranche, il révoque sur REFUND et laisse l'accès intact sur REFUND_DECLINED, chacun rattaché à la transaction exacte. Vous pouvez offrir le chemin de remboursement plus accueillant dans l'app sans laisser l'examen, la preuve ou la révocation à une course manuelle.

Questions fréquentes

Que fait beginRefundRequest ?
Il présente la feuille de demande de remboursement d'Apple dans votre app pour une transaction précise. Le client voit les détails de son achat et une liste de codes de motif, en choisit un, et la demande part chez Apple. La méthode renvoie un statut success ou userCancelled, ou lève duplicateRequest ou failed. Elle ne rembourse pas l'achat lui-même, car Apple examine la demande et prend jusqu'à 48 heures pour décider.
Une demande de remboursement dans l'app rembourse-t-elle l'argent tout de suite ?
Non. Un résultat success signifie que l'App Store a reçu la demande, pas qu'il l'a approuvée. Apple prend jusqu'à 48 heures pour approuver ou refuser, et pour les consommables elle demande d'abord à votre serveur des données d'usage via une notification CONSUMPTION_REQUEST. Montrez au client un état en attente sur success, jamais un remboursement confirmé.
Quelle version d'iOS prend en charge la demande de remboursement dans l'app ?
iOS 15 et iPadOS 15, Mac Catalyst 15 et visionOS 1. La méthode StoreKit 2 beginRefundRequest(in:) est disponible à partir de ces versions, donc toute app ciblant iOS 15 ou ultérieur peut présenter la feuille de remboursement d'Apple depuis l'intérieur de l'app.
Où devrais-je placer le bouton de remboursement dans l'app ?
La recommandation d'Apple est de l'appeler depuis les réglages de compte ou un menu d'aide, pas depuis un écran d'achat ou un paywall. Cela place le chemin de remboursement là où un client mécontent cherche de l'aide, sans annoncer les remboursements à des clients qui n'allaient pas en demander.
Un remboursement dans l'app vaut-il mieux qu'un client contactant sa banque ?
En général oui, pour votre chiffre d'affaires. Un chargeback bancaire est définitif et comporte des frais, et il retire à la fois Apple et vous de la décision. Une demande de remboursement dans l'app garde le client dans le flux d'Apple, où un achat consommable déclenche un CONSUMPTION_REQUEST auquel vous pouvez répondre et un examen que vous pouvez influencer. Un remboursement contestable vaut mieux qu'un chargeback incontestable.

Sources et lectures complémentaires

RefundHalt

Le pilote automatique des remboursements pour l'App Store et Google Play

Poursuivre la lecture

La prochaine demande de remboursement est déjà en route.

Configurez RefundHalt dans le temps qu'il vous faudrait pour lire un nouvel e-mail d'assistance au sujet d'un remboursement que vous n'avez pas pu contester.