Je app kan een in-app formulier voor terugbetalingsverzoeken tonen, en dit doet Apple nadat een klant op verzenden tikt
Met Apples in-app terugbetalingsverzoek kan een klant om een terugbetaling vragen zonder je app te verlaten, via een formulier dat Apple bouwt en beoordeelt. Hier lees je wat beginRefundRequest teruggeeft, welke CONSUMPTION_REQUEST- en 48-uursklokken het op je server start, en of de knop het waard is om uit te brengen.

Belangrijkste inzichten
- Apples beginRefundRequest is een StoreKit 2 methode die Apples eigen terugbetalingsformulier binnen je app toont. De klant ziet zijn aankoopgegevens en een lijst met redencodes, kiest er een, en het verzoek gaat naar Apple. Je bouwt het formulier niet en beslist niet over de uitkomst.
- De aanroep geeft een status success of userCancelled terug, of werpt duplicateRequest of failed. Een status success betekent dat de App Store het verzoek heeft ontvangen, niet dat die het heeft goedgekeurd. Toon bij success nooit een bevestigde terugbetaling in je UI.
- Nadat de klant heeft verzonden, neemt Apple tot 48 uur om goed te keuren of te weigeren. Bij verbruiksaankopen stuurt Apple eerst een CONSUMPTION_REQUEST naar je server, en je hebt de gebruikelijke 12 uur om met gebruiksgegevens te antwoorden, als de klant toestemming gaf.
- De uitkomst arriveert op je server als een App Store Server Notification, dezelfde feed die je al ontvangt. Goedkeuring is een REFUND melding, weigering is REFUND_DECLINED. Het in-app verzoek loopt precies zo in die feed als een terugbetaling die op Apples reportaproblem pagina is gestart.
- De knop is beschikbaar vanaf iOS 15 en iPadOS 15, Mac Catalyst 15 en visionOS 1, dus elke app die op die versies richt kan hem vandaag tonen.
- Het financiële argument is dat een terugbetaling die je kunt betwisten beter is dan een terugboeking die je niet kunt betwisten. De klant binnen Apples proces houden triggert een CONSUMPTION_REQUEST die je kunt beantwoorden, in plaats van een bankterugboeking die definitief is en kosten met zich meebrengt.
- Apples plaatsingsadvies is om hem aan te roepen vanuit de accountinstellingen of een helpmenu, niet vanaf een aankoopscherm, zodat een ontevreden klant hem vindt zonder terugbetalingen bij iedereen te promoten.
Apple laat een klant een terugbetaling aanvragen zonder ooit je app te verlaten. Eén StoreKit aanroep, beginRefundRequest, toont Apples eigen terugbetalingsformulier direct in je interface, de klant kiest een reden, en het verzoek gaat ter beoordeling naar Apple. Je bouwt het formulier niet, je raakt het geld niet aan, en je beslist niet over de uitkomst. Wat je krijgt is een manier om een terugbetalingspad te plaatsen waar een gefrustreerde klant al is, in plaats van hem aan zijn bank te verliezen. Dit is het in-app terugbetalingsverzoek, en het is de moeite waard om het te begrijpen voordat je beslist of je de knop uitbrengt.
Hier komt het deel dat telt voor je omzet. De knop betaalt uit zichzelf niets terug. Hij opent een verzoek, Apple neemt tot 48 uur om het goed te keuren of te weigeren, en bij verbruiksaankopen vuurt Apple eerst een CONSUMPTION_REQUEST af op je server. Het formulier is dus geen weggevertje. Het is een trechter naar precies die terugbetalingsbeoordeling die je al kunt beïnvloeden, en het kan een geschil terughalen bij het kaartnetwerk voordat het een terugboeking wordt die je niet kunt betwisten.
Wat het in-app formulier voor terugbetalingsverzoeken werkelijk is
beginRefundRequest is een StoreKit 2 methode die het formulier voor terugbetalingsverzoeken voor een transactie in een window scene toont. De signatuur is klein: func beginRefundRequest(in scene: UIWindowScene) async throws -> Transaction.RefundRequestStatus. Wanneer je hem aanroept, toont het systeem een formulier met de aankoopgegevens van de klant en een lijst met redencodes om uit te kiezen. Apple bouwt en beheert die UI. Jij levert de scene en de transactie, verder niets.
Apples advies over waar je hem plaatst is expliciet. Roep deze functie aan vanuit de accountinstellingen of een helpmenu, zodat een klant die een terugbetaling wil hem vindt waar hij naar ondersteuning zou zoeken. Hij verscheen in iOS 15 en iPadOS 15, Mac Catalyst 15 en visionOS 1, dus elke app die op die versies richt kan hem vandaag tonen.
Twee manieren om het formulier te openen
Er zijn twee ingangen. Je kunt beginRefundRequest(in:) aanroepen op een specifieke transactie die je al hebt, wat het formulier beperkt tot die ene aankoop. Je kunt het formulier ook openen op productidentificatie wanneer je wilt dat de klant een aankoop van een bepaald product laat terugbetalen. Hoe dan ook horen het formulier, de redenlijst en de beslissing bij Apple. Jouw taak eindigt bij het tonen ervan en het uitlezen van het resultaat.
Wat de aanroep teruggeeft, en wat er mis kan gaan
De methode is async throws, dus hij geeft ofwel een status terug ofwel werpt hij een fout. Beide zijn korte lijsten, en beide zijn de moeite waard om af te handelen zodat je UI iets waars zegt nadat het formulier sluit.
| Resultaat | Type | Wat het betekent |
|---|---|---|
| success | RefundRequestStatus | De App Store heeft het terugbetalingsverzoek ontvangen. Het is ingediend, niet goedgekeurd |
| userCancelled | RefundRequestStatus | De klant sloot het formulier zonder te verzenden. Er is niets verstuurd |
| duplicateRequest | RefundRequestError | De App Store heeft al een terugbetalingsverzoek voor deze aankoop |
| failed | RefundRequestError | Het verzenden zelf is mislukt. Laat de klant het opnieuw proberen |
Wat er op je server gebeurt nadat de klant op verzenden tikt
Het sluiten van het formulier is het begin van het proces, niet het einde. Apple beoordeelt het verzoek en neemt tot 48 uur om het goed te keuren of te weigeren. Bij een verbruiksgebonden in-app aankoop stuurt de App Store, voordat die beslist, een CONSUMPTION_REQUEST melding naar je server met de vraag om gebruiksgegevens. Als de klant toestemming gaf om die gegevens te delen, antwoord je via het Send Consumption Information endpoint. Gaf hij geen toestemming, dan luidt Apples eigen instructie om helemaal niet op de melding te reageren.
Zodra Apple beslist, landt de uitkomst op je server als een App Store Server Notification. Dat is dezelfde feed die je al ontvangt, en het in-app verzoek loopt er precies zo in als een terugbetaling die een klant op Apples reportaproblem pagina start. Er verandert niets aan de afhandeling alleen omdat het verzoek in je app begon.
| Fase | Wat er afgaat | Jouw actie | Klok |
|---|---|---|---|
| Klant verzendt het formulier | beginRefundRequest geeft success terug | Registreer het, toon in behandeling, niet terugbetaald | Direct |
| Alleen verbruiksaankopen, Apple vraagt eerst | CONSUMPTION_REQUEST melding | Stuur verbruiksgegevens als de klant toestemming gaf, blijf anders stil | 12 uur om te antwoorden |
| Apple keurt goed | REFUND melding | Trek het recht voor die transactie in | Tot 48 uur om te beslissen |
| Apple weigert | REFUND_DECLINED melding | Behoud de verkoop, verander niets | Tot 48 uur om te beslissen |

Wat de knop je kost, en wat hij kan besparen
Een terugbetaling die je kunt betwisten is beter dan een terugboeking die je niet kunt betwisten
Een klant die binnen je app geen terugbetalingspad vindt, geeft niet op. Hij gaat naar zijn bank. Een kaartterugboeking is bij de bank definitief, brengt geschilkosten met zich mee, en haalt de beslissing zowel uit jouw handen als die van Apple. Een in-app terugbetalingsverzoek houdt diezelfde klant binnen Apples systeem, waar een verbruiksaankoop een CONSUMPTION_REQUEST triggert die je kunt beantwoorden en een beslissing die je kunt beïnvloeden. Een onbetwistbare terugboeking ruilen voor een betwistbare Apple-beoordeling is het hele financiële argument voor de knop.
Je verlaagt de drempel voor een terugbetaling
Het eerlijke tegenwicht is dat een zichtbaar terugbetalingspad met één tik meer terugbetalingsverzoeken oplevert dan een verstopte support-e-mail. Sommige daarvan waren nooit gebeurd. Dat is een echte kostenpost, en daarom zegt Apple je om de ingang in de accountinstellingen of een helpmenu te plaatsen in plaats van op het aankoopscherm. Je wilt dat de klant die al ontevreden is hem vindt, niet de klant die slechts nieuwsgierig is.
De kostenpost die de hele tijd doorloopt is het bedienen van een terugbetaald account
Hoe de beslissing ook uitvalt, de meter op levering blijft lopen totdat je op de uitkomst reageert. Elk uur dat een terugbetaald recht actief blijft, betaal je de echte kosten erachter door: rekenkracht, model-API-aanroepen, opslag, en elke uitbetaling aan makers of partners die aan het gebruik van die klant is gekoppeld. Het in-app verzoek verandert dat niet. Prompt intrekken bij de REFUND melding wel. De knop is alleen zo goedkoop als jouw afhandeling van de melding die hij uiteindelijk oplevert.
Moet je het in-app terugbetalingsverzoek uitbrengen
Zet hem waar de ondersteuning woont, niet waar de verkoop woont
Volg Apples plaatsingsadvies. De accountinstellingen en een helpmenu zijn de juiste plekken. Een terugbetalingslink naast een paywall leert mensen hun geld terug te verwachten, en nodigt uit tot de nieuwsgierigheidsterugbetaling die je nooit had hoeven aanbieden.
Test de volledige flow in de sandbox voordat je erop vertrouwt
Je kunt het hele pad simuleren in de sandbox en in Xcodes StoreKit testing, door een verzoek van in behandeling naar goedgekeurd of geweigerd te bewegen. Een goedkeuring levert een REFUND melding aan je server, en een weigering levert REFUND_DECLINED, zodat je kunt aantonen dat je handler correct reageert voordat een echte klant ooit op verzenden tikt.
Handel elk resultaat af, en beweer nooit te veel
Toon in behandeling bij success, bied een nieuwe poging bij failed, zeg dat er niets veranderde bij userCancelled, en behandel duplicateRequest als een stille notitie dat het eerdere verzoek van de klant nog steeds staat. De ene fout die pijn doet is een klant vertellen dat zijn terugbetaling rond is terwijl je alleen een ingediend verzoek in handen hebt.
Hoe RefundHalt de nasleep afhandelt
Het in-app formulier is van Apple. Wat erna komt is van jou, en dat is het deel dat RefundHalt runt. Wanneer een klant een terugbetaling vanuit je app verzendt, vangt RefundHalt de CONSUMPTION_REQUEST voor verbruiksaankopen op en beantwoordt die binnen het 12-uursvenster met het gebruiksbewijs dat Apple helpt beslissen. Wanneer Apple beslist, trekt het in bij REFUND en laat het toegang onaangeroerd bij REFUND_DECLINED, elk gekoppeld aan de exacte transactie. Jij kunt het vriendelijkere in-app terugbetalingspad aanbieden zonder de beoordeling, het bewijs of de intrekking aan een handmatig geploeter over te laten.
Veelgestelde vragen
- Wat doet beginRefundRequest?
- Het toont Apples formulier voor terugbetalingsverzoeken binnen je app voor een specifieke transactie. De klant ziet zijn aankoopgegevens en een lijst met redencodes, kiest er een, en het verzoek gaat naar Apple. De methode geeft een status success of userCancelled terug, of werpt duplicateRequest of failed. Ze betaalt de aankoop zelf niet terug, want Apple beoordeelt het verzoek en neemt tot 48 uur om te beslissen.
- Betaalt een in-app terugbetalingsverzoek het geld meteen terug?
- Nee. Een resultaat success betekent dat de App Store het verzoek heeft ontvangen, niet dat die het heeft goedgekeurd. Apple neemt tot 48 uur om goed te keuren of te weigeren, en bij verbruiksaankopen vraagt het eerst via een CONSUMPTION_REQUEST melding aan je server om gebruiksgegevens. Toon de klant bij success een status in behandeling, nooit een bevestigde terugbetaling.
- Welke iOS versie ondersteunt het in-app terugbetalingsverzoek?
- iOS 15 en iPadOS 15, Mac Catalyst 15 en visionOS 1. De StoreKit 2 methode beginRefundRequest(in:) is beschikbaar vanaf die versies, dus elke app die op iOS 15 of later richt kan Apples terugbetalingsformulier vanuit de app tonen.
- Waar moet ik de in-app terugbetalingsknop plaatsen?
- Apples advies is om hem aan te roepen vanuit de accountinstellingen of een helpmenu, niet vanaf een aankoop- of paywallscherm. Dat plaatst het terugbetalingspad waar een ontevreden klant naar ondersteuning zoekt, zonder terugbetalingen te promoten bij klanten die er niet om zouden vragen.
- Is een in-app terugbetaling beter dan dat een klant zijn bank benadert?
- Meestal wel, voor je omzet. Een bankterugboeking is definitief en brengt kosten met zich mee, en haalt zowel Apple als jou uit de beslissing. Een in-app terugbetalingsverzoek houdt de klant in Apples proces, waar een verbruiksaankoop een CONSUMPTION_REQUEST triggert die je kunt beantwoorden en een beoordeling die je kunt beïnvloeden. Een betwistbare terugbetaling is beter dan een onbetwistbare terugboeking.
Bronnen en verder lezen
- Apple Developer: beginRefundRequest(in:)
- Apple Developer: Transaction.RefundRequestStatus
- Apple Developer: Transaction.RefundRequestError
- Apple Developer: App Store Server Notifications V2 notificationType
- Apple Developer: Send Consumption Information
- Apple Developer: Support customers and handle refunds (WWDC21)
RefundHalt
De terugbetalingsautopiloot voor de App Store en Google Play
Lees verder
Wanneer een Google Play-aankoop wordt terugbetaald of teruggeboekt, is de Voided Purchases API hoe je erachter komt
Google Play maakt een aankoop stilletjes ongeldig wanneer die wordt terugbetaald of teruggeboekt. De Voided Purchases API is de lijst van die bestellingen, zodat je toegang kunt intrekken. Hier vind je elk veld, het venster van 30 dagen, de revoke-optie die bestellingen verbergt, en wat het kost.
Drie App Store terugbetalingsmeldingen komen binnen nadat Apple heeft beslist, en REFUND_REVERSED geeft de verkoop terug
Apple stuurt vier terugbetalingsberichten via App Store Server Notifications V2, en de meeste apps verwerken er maar twee. REFUND zegt dat je moet intrekken, REFUND_DECLINED betekent de verkoop behouden, en REFUND_REVERSED geeft de verkoop terug en vraagt je te herstellen wat je hebt weggenomen. Hier staat wat elke melding vereist.