Alle artikelen
Playbook8 min leestijd

Terugbetalingsafhandeling gaat stil kapot, dus test in-app-aankoop-terugbetalingen in de sandbox voordat een echte klant dat doet

Je terugbetalingsafhandeling draait pas nadat een klant al weg is, dus een bug erin blijft onzichtbaar totdat hij echt geld kost. Beide stores laten je eerst een terugbetaling in een testomgeving activeren. Zo test je in-app-aankoop-terugbetalingen in de App Store en Google Play voordat er een echt is.

Een iPhone en een Android-telefoon onder een vergrootglas op een donker bureau, als beeld voor het testen van in-app-aankoop-terugbetalingen voordat ze echt zijn

Belangrijkste inzichten

  • Met StoreKit-testen in Xcode kun je een aankoop lokaal terugbetalen door op de terugbetaalpijl in Transaction Manager te klikken, wat de Transaction.updates-listener van je app activeert, maar het neemt nooit contact op met Apple, dus er wordt geen App Store Server Notification verzonden.
  • Om de serverkant bij Apple te testen, richt je een sandbox-URL voor App Store Server Notifications V2 op je backend: een sandbox-terugbetaling levert dan een echte REFUND, en een terugbetalingsverzoek levert een CONSUMPTION_REQUEST aan je server.
  • Het Request a Test Notification-endpoint van Apple stuurt een melding van het type TEST naar je geconfigureerde URL en geeft een testNotificationToken terug, zodat je kunt bevestigen dat je webhook bereikbaar is voordat een echte gebeurtenis afgaat.
  • De sandbox van Apple probeert een mislukte melding nooit opnieuw, dus een webhook die plat ligt wanneer de sandbox afgaat, laat de gebeurtenis vallen zonder tweede poging, dezelfde soort misser die je later een echt terugbetalingsvenster kost.
  • Google Play geeft licentietesters een betaalmethode genaamd Test card, approves then charges back, die een PendingRefundReviewNotification afvuurt vlak na de aankoop, zodat je je 24-uurs orders.reviewrefund-antwoord kunt oefenen.
  • Voor een licentietester in Google Play wordt een niet-bevestigde aankoop na 3 minuten automatisch terugbetaald in plaats van de 3 dagen waar productie op wacht, dus een kapot bevestigingspad faalt snel en luid tijdens het testen.
  • Een terugbetalingshandler die je nooit hebt getest, is degene die de betaalde toegang van een terugbetaalde klant actief houdt, en vanaf 3 augustus 2026 kan een ongeteste Google Play-chargeback-respons je de aankoopprijs kosten minus de servicekosten van Play plus de kosten van de bank.

Je terugbetalingsafhandeling is het ene codepad dat pas draait nadat de klant al weg is. Niets in je normale QA raakt het aan, want om er te komen moet je echt terugbetaald worden. Dus het gaat ongetest de deur uit, ligt maandenlang stil, en faalt dan op een echte terugbetaling, waar de storing geld kost in plaats van een rode test. De oplossing is om een terugbetaling niet langer te zien als iets wat jou overkomt en er bewust een te activeren. Zowel Apple als Google laten je een terugbetaling in een testomgeving afvuren en kijken hoe je server reageert. Zo test je in-app-aankoop-terugbetalingen in de App Store en Google Play voordat een betalende klant bewijst dat je handler kapot was.

De drie omgevingen waarin een terugbetaling kan afgaan, en slechts één is productie

Er zijn drie aparte plekken waar een terugbetaling van Apple of Google geactiveerd kan worden terwijl je bouwt, en ze zijn niet uitwisselbaar. Twee ervan kun je op aanvraag activeren. De derde is productie, waar je een terugbetalingsbug nooit voor het eerst wilt tegenkomen. De valkuil is aannemen dat de makkelijke, lokaal testen in Xcode, je hele pijplijn bewijst. Het bewijst je app. Het zegt niets over je server.

StoreKit-testen in Xcode is lokaal, dus het oefent je app en verder niets

Het ingebouwde StoreKit-testen in Xcode draait tegen een configuratiebestand op je Mac, zonder heen-en-weer naar Apple. Open de StoreKit Transaction Manager vanuit de debugbalk, selecteer een gekochte transactie en klik op de gebogen terugbetaalpijl. De transactie schakelt naar terugbetaald en de Transaction.updates-listener van je app gaat af, precies zoals in het echt. Je kunt ook beginRefundRequest aanroepen om het echte terugbetaalvel te tonen, en in de Xcode-omgeving wordt het probleem dat je kiest één op één toegewezen aan een RevocationReason, waarbij de terugbetaling meteen wordt toegepast. Dit is de snelste manier om te bewijzen dat je client de toegang afsnijdt op het moment dat revocationDate niet-nil wordt. Het is ook alles wat lokaal testen je kan vertellen, want niets hier bereikt ooit de servers van Apple, dus er wordt geen App Store Server Notification verzonden. Je backend leert er niets van.

De sandbox is waar je server eindelijk over een terugbetaling hoort

Om de helft van je integratie te testen die over geld beslist, je server, heb je de sandbox van Apple nodig. Configureer een sandbox-URL voor App Store Server Notifications V2 in App Store Connect, log een sandbox-tester in op een apparaat en koop. Nu levert een terugbetaling in de sandbox een echte REFUND-melding aan je backend, en een terugbetalingsverzoek op een verbruiksartikel of automatisch verlengbaar abonnement levert een CONSUMPTION_REQUEST, dezelfde ondertekende payload die je productieserver zal krijgen. Voordat je iets activeert, roep je het Request a Test Notification-endpoint aan. Het vertelt de App Store-server om een melding van het type TEST naar je geconfigureerde URL te sturen en geeft je een testNotificationToken, die je doorgeeft aan Get Test Notification Status om de bezorging te bevestigen. Als die heen-en-weer niet werkt, werkt een echte melding ook niet.

OmgevingWat het kan activerenWat het bewijstWat het niet kan
StoreKit-testen in XcodeEen terugbetaling via de Transaction Manager of het beginRefundRequest-velJe app reageert lokaal op een terugbetaling, in secondenNeemt nooit contact op met Apple, dus er wordt geen servermelding verzonden
SandboxEchte REFUND en CONSUMPTION_REQUEST naar je server, plus een TEST-melding op aanvraagJe backend ontvangt, verifieert en handelt op de ondertekende payloadProbeert een melding die je endpoint niet ontvangt niet opnieuw
ProductieElke terugbetaling, voor echt geldNiets wat je hier als eerste wilt lerenJe kunt de kosten van een bug niet ongedaan maken

Hoe je in-app-aankoop-terugbetalingen test in de App Store

Voer het in deze volgorde uit, van de goedkope clientcheck tot de volledige server-heen-en-weer. Elke stap oefent een ander stuk, en de latere zijn degene waarvoor productie je echt factureert.

  • Maak een In-App Purchase-sleutel aan onder Users and Access, Integrations, In-App Purchase in App Store Connect en gebruik hem om je App Store Server API-aanroepen te ondertekenen.
  • Richt je sandbox-URL voor App Store Server Notifications V2 op je backend, roep dan Request a Test Notification aan en bevestig dat de TEST-payload aankomt en verifieert tegen de certificaatketen van Apple.
  • Betaal in de Transaction Manager van Xcode een aankoop terug en bevestig dat je app de rechten laat vallen op het moment dat revocationDate is ingesteld.
  • Log een sandbox-tester in, koop een verbruiksartikel, vraag een terugbetaling aan en bevestig dat je server de CONSUMPTION_REQUEST ontvangt en een Send Consumption Information-antwoord ruim binnen het 12-uursvenster kan samenstellen en verzenden.
  • Betaal een sandbox-aankoop terug en bevestig dat de REFUND-melding je server bereikt, dat je de toegang intrekt of het verbruikssaldo aftrekt, en dat een herhaalde bezorging van dezelfde melding niet dubbel wordt toegepast.
Een smartphone in een kleine bankschroef onder een werklamp met een pincet ernaast, een apparaat onder test als beeld voor het oefenen van een terugbetaling voordat hij echt is

Hoe je een terugbetaling en een chargeback oefent in Google Play

Google Play heeft geen lokale modus zoals Xcode. Alles draait tegen de servers van Google, maar licentietesters houden het gratis en veilig. Voeg je test-Google-accounts toe als licentietesters in Play Console en ze krijgen een set testbetaalmethoden die nooit echt geld afschrijven. Google markeert elke testaankoop met een melding midden in het aankoopdialoogvenster, en belastingen worden niet berekend. Wat telt voor terugbetalingstesten is welk testinstrument je kiest, want elk leidt tot een andere uitkomst.

TestbetaalmethodeWat het simuleertWaarom je het zou gebruiken
Test instrument, always approvesEen schone geslaagde aankoopZet een bestelling op die je daarna kunt terugbetalen of intrekken
Test instrument, always declinesEen mislukte betalingBevestig dat je bij een weigering niets toekent
Slow test card, approves after a few minutesEen lopende aankoop die later slaagtOefen je PENDING-afhandeling voordat je toegang verleent
Slow test card, declines after a few minutesEen lopende aankoop die later misluktBevestig dat een lopende weigering nooit rechten lekt
Test card, approves then charges backEen door de gebruiker gestarte chargebackVuur een PendingRefundReviewNotification af en oefen je 24-uurs-antwoord

Activeer een terugbetaling, een chargeback en de bevestigings-auto-terugbetaling

  • Koop met de approve-then-charge-back-testkaart, en een PendingRefundReviewNotification landt even later op je Real-time Developer Notifications-topic. Beantwoord hem met één enkele orders.reviewrefund-aanroep, want Google bewaart alleen je eerste antwoord.
  • Betaal een testbestelling terug en trek hem in vanuit het tabblad Orders in Play Console om een VoidedPurchaseNotification af te vuren, en bevestig dat je server de rechten intrekt.
  • Laat de aankoop van een licentietester met opzet niet-bevestigd. Google betaalt hem na 3 minuten automatisch terug in plaats van de 3 dagen die productie toestaat, en mailt je de annulering, dus een kapot bevestigingspad komt in minuten aan het licht, niet op dag vier in productie.

Wat een ongetest terugbetalingspad echt kost

Een terugbetalingshandler is geen versiering. Het is de code die voorkomt dat je betaalt om iemand te bedienen die jou niet meer betaalt. Als hij stil faalt, gaat de terugbetaling nog steeds door, maar de toegang, het saldo en de uitgaven erachter stoppen niet.

Volg het geld. Wanneer Apple of Google een aankoop terugbetaalt, geef jij de verkoopprijs terug en geeft de store zijn commissie terug, tot zover staat het grootboek gelijk. Wat niet terugkomt is alles wat je al hebt uitgegeven om het product te leveren: de rekenkracht achter een gegenereerd resultaat, de model API-aanroepen, de opslag voor wat de gebruiker heeft bewaard, de uitbetaling die je al naar een maker hebt gestuurd. Een terugbetalingshandler die de toegang nooit intrekt, laat een terugbetaalde gebruiker die dingen op jouw budget blijven uitgeven, terwijl er niets in het systeem overblijft om hem af te snijden.

De twee bewijsvensters maken het scherper. Een CONSUMPTION_REQUEST die je nooit in de sandbox hebt geoefend, is een antwoord dat je misvormd of te laat verstuurt, en Apple kent de terugbetaling vaak standaard toe wanneer je antwoord niet binnen 12 uur binnenkomt. Een Google Play-chargeback-respons die je nooit met de testkaart hebt afgevuurd, is een 24-uursvenster dat je live verprutst, en vanaf 3 augustus 2026 kost een verloren Play-chargeback je de aankoopprijs minus de servicekosten van Play plus de chargebackkosten van de bank. Elk van die storingen is gratis reproduceerbaar in een testomgeving eerst. Geen ervan is goedkoop in productie.

Ongetest padHoe het faalt in productieWat het je kost
REFUND-handlerEen terugbetaalde gebruiker houdt toegangDe rekenkracht, API-aanroepen, opslag en uitbetalingen die je aan hem blijft uitgeven
CONSUMPTION_REQUEST-antwoordMisvormd, of verzonden na 12 uurApple kent de terugbetaling standaard toe, dus je verliest de verkoop en de uitgave
orders.reviewrefund-responsGemist of fout binnen 24 uurVanaf 3 augustus 2026, de aankoopprijs minus de servicekosten van Play, plus de chargebackkosten van de bank

Een korte checklist voordat je terugbetalingsafhandeling uitrolt

Je hebt geen lab nodig. Je moet elke gebeurtenis één keer je code hebben zien raken.

  • Je app laat de toegang vallen op het moment dat een StoreKit-transactie een revocationDate toont, bevestigd in de Transaction Manager van Xcode.
  • Je sandbox-server-URL ontvangt een TEST-melding en verifieert die tegen de certificaten van Apple.
  • Een sandbox-REFUND trekt de toegang in of trekt het saldo af, en een herhaalde bezorging telt niet dubbel.
  • Een sandbox-CONSUMPTION_REQUEST produceert een geldig Send Consumption Information-antwoord ruim binnen 12 uur.
  • Een Google-PendingRefundReviewNotification van de chargeback-testkaart produceert precies één orders.reviewrefund-aanroep.
  • Een niet-bevestigde Google Play-testaankoop wordt in 3 minuten automatisch terugbetaald en je reconciliatie merkt het op.

Loop die lijst één keer door en terugbetalingsafhandeling houdt op de code te zijn waarvan je hoopt dat hij werkt. Het wordt de code die je hebt zien werken.

Veelgestelde vragen

Kan ik een App Store-terugbetaling testen zonder een echte aankoop?
Ja. Met StoreKit-testen in Xcode kun je een aankoop lokaal terugbetalen via de Transaction Manager, zonder echt geld en zonder App Store-account, wat de Transaction.updates-listener van je app activeert. Het stuurt geen servermelding, dus het test alleen je app, niet je backend.
Stuurt lokaal StoreKit-testen App Store Server Notifications?
Nee. StoreKit-testen in Xcode draait volledig op je Mac tegen een lokale configuratie en neemt nooit contact op met de servers van Apple, dus er wordt nooit een App Store Server Notification verzonden, inclusief REFUND of CONSUMPTION_REQUEST. Gebruik de sandbox om je server te testen.
Hoe test ik een Google Play-chargeback-respons?
Gebruik de licentietester-betaalmethode genaamd Test card, approves then charges back. Hij vuurt een PendingRefundReviewNotification af vlak na de aankoop, dezelfde melding die een echte bankchargeback stuurt, zodat je je 24-uurs orders.reviewrefund-antwoord kunt oefenen.
Waarom wordt mijn Google Play-testaankoop na een paar minuten terugbetaald?
Voor licentietesters betaalt Google een aankoop na 3 minuten automatisch terug als je app hem niet heeft bevestigd, en mailt je de annulering. Productie wacht 3 dagen, maar testers krijgen de versnelde versie, zodat een kapot bevestigingspad snel aan het licht komt.
Probeert de sandbox van Apple een mislukte terugbetalingsmelding opnieuw?
Nee. De sandbox probeert App Store Server Notifications niet opnieuw, dus als je endpoint plat ligt wanneer een sandbox-terugbetaling afgaat, wordt de melding zonder tweede poging losgelaten. Bevestig eerst dat je URL bereikbaar is met Request a Test Notification.

Bronnen en verder lezen

RefundHalt

De terugbetalingsautopiloot voor de App Store en Google Play

Lees verder

Het volgende terugbetalingsverzoek is al onderweg.

Stel RefundHalt in binnen de tijd die het kost om nog een supportmail te lezen over een terugbetaling die je niet kon betwisten.