Tous les articles
Playbook8 min de lecture

La gestion des remboursements échoue en silence, alors testez les remboursements d'achats intégrés dans le sandbox avant qu'un vrai client ne le fasse

Votre gestion des remboursements ne s'exécute qu'une fois le client déjà parti, donc un bug dedans reste invisible jusqu'à ce qu'il coûte de l'argent réel. Les deux boutiques vous permettent de déclencher d'abord un remboursement dans un environnement de test. Voici comment tester les remboursements d'achats intégrés sur l'App Store et Google Play avant qu'un remboursement ne soit réel.

Un iPhone et un téléphone Android sous une loupe sur un bureau sombre, représentant le test des remboursements d'achats intégrés avant qu'ils ne soient réels

Points clés

  • Le test StoreKit de Xcode vous permet de rembourser un achat localement en cliquant sur la flèche de remboursement dans le Transaction Manager, ce qui déclenche l'écouteur Transaction.updates de votre app, mais ne contacte jamais Apple, donc aucune App Store Server Notification n'est envoyée.
  • Pour tester le côté serveur chez Apple, pointez une URL App Store Server Notifications V2 de sandbox vers votre backend : un remboursement dans le sandbox délivre alors un REFUND réel, et une demande de remboursement délivre un CONSUMPTION_REQUEST, à votre serveur.
  • L'endpoint Request a Test Notification d'Apple envoie une notification de type TEST à l'URL que vous avez configurée et renvoie un testNotificationToken, ce qui vous permet de confirmer que votre webhook est joignable avant qu'un événement réel ne se déclenche.
  • Le sandbox d'Apple ne réessaie jamais une notification échouée, donc un webhook hors service au moment où le sandbox se déclenche perd l'événement sans seconde tentative, la même catégorie d'échec qui vous coûte plus tard une vraie fenêtre de remboursement.
  • Google Play donne aux license testers un moyen de paiement appelé Test card, approves then charges back, qui déclenche une PendingRefundReviewNotification quelques instants après l'achat afin que vous puissiez répéter votre réponse orders.reviewrefund de 24 heures.
  • Pour un license tester sur Google Play, un achat non confirmé est remboursé automatiquement après 3 minutes au lieu des 3 jours qu'attend la production, donc un chemin de confirmation cassé échoue vite et de façon visible en test.
  • Un gestionnaire de remboursement que vous n'avez jamais testé est celui qui garde actif l'accès payant d'un client remboursé, et à partir du 3 août 2026 une réponse à un chargeback Google Play non testée peut vous coûter le prix de l'achat moins les frais de service de Play plus les frais de la banque.

Votre gestion des remboursements est le seul chemin de code qui ne s'exécute qu'une fois le client déjà parti. Rien dans votre QA habituelle ne le touche, car pour l'atteindre il faut vraiment se faire rembourser. Il part donc en production sans test, reste silencieux pendant des mois, puis échoue sur un vrai remboursement, où l'échec coûte de l'argent au lieu d'un test au rouge. La solution est de cesser de traiter un remboursement comme quelque chose qui vous arrive et de commencer à en déclencher un exprès. Apple et Google vous permettent tous deux de déclencher un remboursement dans un environnement de test et de regarder votre serveur réagir. Voici comment tester les remboursements d'achats intégrés sur l'App Store et Google Play avant qu'un client payant ne prouve que votre gestionnaire était cassé.

Les trois environnements où un remboursement peut se déclencher, et un seul est la production

Il existe trois endroits distincts où un remboursement Apple ou Google peut être déclenché pendant que vous développez, et ils ne sont pas interchangeables. Deux d'entre eux sont à vous, à déclencher à la demande. Le troisième est la production, où vous ne voulez jamais rencontrer un bug de remboursement pour la première fois. Le piège est de supposer que le plus facile, le test local dans Xcode, prouve tout votre pipeline. Il prouve votre app. Il ne dit rien sur votre serveur.

Le test StoreKit de Xcode est local, donc il exerce votre app et rien d'autre

Le test StoreKit intégré de Xcode s'exécute contre un fichier de configuration sur votre Mac, sans aller-retour vers Apple. Ouvrez le StoreKit Transaction Manager depuis la barre de débogage, sélectionnez une transaction achetée et cliquez sur la flèche courbe de remboursement. La transaction passe à remboursée et l'écouteur Transaction.updates de votre app se déclenche, exactement comme dans la réalité. Vous pouvez aussi appeler beginRefundRequest pour présenter la vraie feuille de remboursement, et dans l'environnement Xcode le problème que vous choisissez correspond un à un à un RevocationReason, le remboursement étant appliqué immédiatement. C'est le moyen le plus rapide de prouver que votre client coupe l'accès à l'instant où revocationDate cesse d'être nul. C'est aussi tout ce que le test local peut vous dire, car rien ici n'atteint jamais les serveurs d'Apple, donc aucune App Store Server Notification n'est envoyée. Votre backend n'apprend rien.

Le sandbox est l'endroit où votre serveur entend enfin parler d'un remboursement

Pour tester la moitié de votre intégration qui décide de l'argent, votre serveur, vous avez besoin du sandbox d'Apple. Configurez une URL App Store Server Notifications V2 de sandbox dans App Store Connect, connectez un testeur sandbox sur un appareil et achetez. Désormais un remboursement dans le sandbox délivre une vraie notification REFUND à votre backend, et une demande de remboursement sur un consommable ou un renouvelable automatique délivre un CONSUMPTION_REQUEST, le même payload signé que recevra votre serveur de production. Avant de déclencher quoi que ce soit, appelez l'endpoint Request a Test Notification. Il indique au serveur de l'App Store d'envoyer une notification de type TEST à l'URL que vous avez configurée et vous remet un testNotificationToken, que vous passez à Get Test Notification Status pour confirmer la livraison. Si cet aller-retour ne fonctionne pas, aucune notification réelle ne fonctionnera non plus.

EnvironnementCe qu'il peut déclencherCe qu'il prouveCe qu'il ne peut pas faire
Test StoreKit de XcodeUn remboursement via le Transaction Manager ou la feuille beginRefundRequestVotre app réagit à un remboursement localement, en quelques secondesNe contacte jamais Apple, donc aucune notification serveur n'est envoyée
SandboxREFUND et CONSUMPTION_REQUEST réels vers votre serveur, plus une notification TEST à la demandeVotre backend reçoit, vérifie et agit sur le payload signéNe réessaie pas une notification que votre endpoint ne parvient pas à recevoir
ProductionChaque remboursement, avec de l'argent réelRien que vous vouliez apprendre ici en premierVous ne pouvez pas annuler le coût d'un bug

Comment tester les remboursements d'achats intégrés sur l'App Store

Exécutez-le dans cet ordre, du contrôle client peu coûteux à l'aller-retour serveur complet. Chaque étape exerce une pièce différente, et les dernières sont celles que la production vous facture réellement.

  • Créez une clé In-App Purchase sous Users and Access, Integrations, In-App Purchase dans App Store Connect, et utilisez-la pour signer vos appels à l'App Store Server API.
  • Pointez votre URL App Store Server Notifications V2 de sandbox vers votre backend, puis appelez Request a Test Notification et confirmez que le payload TEST arrive et se vérifie contre la chaîne de certificats d'Apple.
  • Dans le Transaction Manager de Xcode, remboursez un achat et confirmez que votre app retire le droit à l'instant où revocationDate est défini.
  • Connectez un testeur sandbox, achetez un consommable, demandez un remboursement et confirmez que votre serveur reçoit le CONSUMPTION_REQUEST et peut assembler et envoyer une réponse Send Consumption Information bien avant la fin de la fenêtre de 12 heures.
  • Remboursez un achat sandbox et confirmez que la notification REFUND atteint votre serveur, que vous révoquez l'accès ou déduisez le solde du consommable, et qu'une livraison répétée de la même notification ne s'applique pas deux fois.
Un smartphone maintenu dans un petit étau d'établi sous une lampe de travail avec une pince à épiler à côté, un appareil sous test représentant la répétition d'un remboursement avant qu'il ne soit réel

Comment répéter un remboursement et un chargeback sur Google Play

Google Play n'a pas de mode local comme celui de Xcode. Tout s'exécute contre les serveurs de Google, mais les license testers gardent cela gratuit et sûr. Ajoutez vos comptes Google de test comme license testers dans Play Console et ils obtiennent un ensemble de moyens de paiement de test qui ne facturent jamais d'argent réel. Google marque chaque achat de test d'un avis au milieu de la boîte de dialogue d'achat, et les taxes ne sont pas calculées. Ce qui compte pour tester les remboursements est l'instrument de test que vous choisissez, car chacun produit un résultat différent.

Moyen de paiement de testCe qu'il simulePourquoi l'utiliser
Test instrument, always approvesUn achat propre et réussiPréparer une commande que vous pouvez ensuite rembourser ou révoquer
Test instrument, always declinesUn paiement échouéConfirmer que vous n'accordez rien en cas de refus
Slow test card, approves after a few minutesUn achat en attente qui réussit ensuiteExercer votre gestion de PENDING avant d'accorder l'accès
Slow test card, declines after a few minutesUn achat en attente qui échoue ensuiteConfirmer qu'un refus en attente ne laisse jamais fuir le droit
Test card, approves then charges backUn chargeback initié par l'utilisateurDéclencher une PendingRefundReviewNotification et répéter votre réponse de 24 heures

Déclenchez un remboursement, un chargeback et le remboursement automatique par non-confirmation

  • Achetez avec la carte de test approve-then-charge-back, et une PendingRefundReviewNotification arrive sur votre topic Real-time Developer Notifications quelques instants plus tard. Répondez-y par un seul appel orders.reviewrefund, car Google ne garde que votre première réponse.
  • Remboursez et révoquez une commande de test depuis l'onglet Orders dans Play Console pour déclencher une VoidedPurchaseNotification, et confirmez que votre serveur retire le droit.
  • Laissez exprès l'achat d'un license tester non confirmé. Google le rembourse automatiquement après 3 minutes au lieu des 3 jours que la production autorise, et vous envoie l'annulation par e-mail, donc un chemin de confirmation cassé apparaît en quelques minutes, pas au quatrième jour en production.

Ce que coûte réellement un chemin de remboursement non testé

Un gestionnaire de remboursement n'est pas de la décoration. C'est le code qui vous évite de payer pour servir quelqu'un qui ne vous paie plus. Quand il échoue en silence, le remboursement passe quand même, mais l'accès, le solde et la dépense derrière eux ne s'arrêtent pas.

Suivez l'argent. Quand Apple ou Google rembourse un achat, vous rendez le prix de vente et la boutique rend sa commission, jusque-là le compte est équilibré. Ce qui ne revient pas, c'est tout ce que vous avez déjà dépensé pour livrer le produit : le calcul derrière un résultat généré, les appels à l'API du modèle, le stockage de ce que l'utilisateur a enregistré, le versement que vous avez déjà envoyé à un créateur. Un gestionnaire de remboursement qui ne révoque jamais l'accès laisse un utilisateur remboursé continuer à dépenser tout cela sur votre budget, sans rien dans le système pour l'arrêter.

Les deux fenêtres de preuve rendent cela plus tranchant. Un CONSUMPTION_REQUEST que vous n'avez jamais exercé dans le sandbox est une réponse que vous envoyez mal formée ou en retard, et Apple accorde souvent le remboursement par défaut quand votre réponse n'arrive pas dans les 12 heures. Une réponse à un chargeback Google Play que vous n'avez jamais déclenchée avec la carte de test est une fenêtre de 24 heures que vous ratez en direct, et à partir du 3 août 2026 un chargeback Play perdu vous coûte le prix de l'achat moins les frais de service de Play plus les frais de chargeback de la banque. Chacun de ces échecs est reproductible gratuitement dans un environnement de test d'abord. Aucun n'est bon marché en production.

Chemin non testéComment il échoue en productionCe qu'il vous coûte
Gestionnaire REFUNDUn utilisateur remboursé garde l'accèsLe calcul, les appels API, le stockage et les versements que vous continuez à dépenser pour lui
Réponse CONSUMPTION_REQUESTMal formée, ou envoyée après 12 heuresApple accorde le remboursement par défaut, donc vous perdez la vente et la dépense
Réponse orders.reviewrefundManquée ou erronée dans les 24 heuresÀ partir du 3 août 2026, le prix de l'achat moins les frais de service de Play, plus les frais de chargeback de la banque

Une courte checklist avant de livrer la gestion des remboursements

Vous n'avez pas besoin d'un laboratoire. Vous avez besoin d'avoir vu chaque événement atteindre votre code une fois.

  • Votre app retire l'accès à l'instant où une transaction StoreKit affiche un revocationDate, confirmé dans le Transaction Manager de Xcode.
  • L'URL de votre serveur sandbox reçoit une notification TEST et la vérifie contre les certificats d'Apple.
  • Un REFUND sandbox révoque l'accès ou déduit le solde, et une livraison répétée ne compte pas deux fois.
  • Un CONSUMPTION_REQUEST sandbox produit une réponse Send Consumption Information valide bien avant la fin des 12 heures.
  • Une PendingRefundReviewNotification Google issue de la carte de test de chargeback produit exactement un appel orders.reviewrefund.
  • Un achat de test Google Play non confirmé est remboursé automatiquement en 3 minutes et votre réconciliation le remarque.

Exécutez cette liste une fois et la gestion des remboursements cesse d'être le code dont vous espérez qu'il fonctionne. Elle devient le code que vous avez vu fonctionner.

Questions fréquentes

Puis-je tester un remboursement App Store sans achat réel ?
Oui. Le test StoreKit de Xcode vous permet de rembourser un achat localement via le Transaction Manager, sans argent réel et sans compte App Store, ce qui déclenche l'écouteur Transaction.updates de votre app. Il n'envoie pas de notification serveur, donc il ne teste que votre app, pas votre backend.
Le test StoreKit local envoie-t-il des App Store Server Notifications ?
Non. Le test StoreKit de Xcode s'exécute entièrement sur votre Mac contre une configuration locale et ne contacte jamais les serveurs d'Apple, donc aucune App Store Server Notification, y compris REFUND ou CONSUMPTION_REQUEST, n'est jamais envoyée. Utilisez le sandbox pour tester votre serveur.
Comment tester une réponse à un chargeback Google Play ?
Utilisez le moyen de paiement de license tester appelé Test card, approves then charges back. Il déclenche une PendingRefundReviewNotification quelques instants après l'achat, la même notification qu'envoie un vrai chargeback bancaire, ce qui vous permet de répéter votre réponse orders.reviewrefund de 24 heures.
Pourquoi mon achat de test Google Play est-il remboursé après quelques minutes ?
Pour les license testers, Google rembourse automatiquement un achat après 3 minutes si votre app ne l'a pas confirmé, et vous envoie l'annulation par e-mail. La production attend 3 jours, mais les testeurs obtiennent la version accélérée afin qu'un chemin de confirmation cassé remonte vite.
Le sandbox d'Apple réessaie-t-il une notification de remboursement échouée ?
Non. Le sandbox ne réessaie pas les App Store Server Notifications, donc si votre endpoint est hors service quand un remboursement sandbox se déclenche, la notification est perdue sans seconde tentative. Confirmez d'abord que votre URL est joignable avec Request a Test Notification.

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.