Alle artikelen
Deep dive7 min leestijd

Een melding van een geannuleerde aankoop laat je Google Play-server de toegang intrekken op het moment dat een terugbetaling binnenkomt

Google Play kan je server direct een melding van een geannuleerde aankoop sturen zodra een aankoop wordt terugbetaald, teruggeboekt of geannuleerd. Ze draagt een purchaseToken, orderId, productType en refundType, en betekent één ding, trek de toegang in. Zo lees je haar en sluit je haar aan.

Een werkplek van een ontwikkelaar bij schemer met een telefoon die een teruggedraaide betaling toont, ter illustratie van een melding van een geannuleerde Google Play-aankoop die een server bereikt

Belangrijkste inzichten

  • Een melding van een geannuleerde aankoop is een Real-time Developer Notification die Google Play naar je Cloud Pub/Sub-onderwerp pusht op het moment dat een aankoop wordt terugbetaald, teruggeboekt of anderszins geannuleerd. Het is een push-signaal, niet iets waar je op moet pollen.
  • De melding draagt precies vier velden: `purchaseToken`, `orderId`, `productType` en `refundType`. Dat is genoeg om de exacte aankoop in je database te vinden en het eraan verbonden recht in te trekken.
  • `productType` is `1` voor een geannuleerd abonnement en `2` voor een geannuleerde eenmalige aankoop. `refundType` is `1` voor een volledige terugbetaling en `2` voor een terugbetaling op basis van aantal, die alleen geldt voor eenmalige aankopen met meerdere stuks.
  • Een melding van een geannuleerde aankoop betekent dat de klant zijn geld al terug heeft. Google's eigen richtlijn is om de toegang tot de bijbehorende inhoud in te trekken, omdat de koper het recht niet langer zou moeten bezitten.
  • Meldingen van geannuleerde aankopen staan uit totdat je ze aanzet. In Play Console kies je onder Monetization setup ofwel abonnementen plus alle geannuleerde aankopen, ofwel dat plus gebeurtenissen van eenmalige producten. Beide opties omvatten geannuleerde aankopen.
  • Een melding van een geannuleerde aankoop is niet een van de twee terugbetalingsstromen die je om bewijs vragen. Het is een kennisgeving achteraf. De enige stromen die jouw input opnemen zijn Apple's CONSUMPTION_REQUEST, met een venster van 12-hour, en Google Play's chargeback-beoordeling via `orders.reviewrefund`, met een venster van 24-hour.
  • Vanaf August 3, 2026 geeft Google de aankoopprijs plus de bankkosten van een terugboeking door aan de ontwikkelaar. Een melding van een geannuleerde aankoop is vaak hoe je server voor het eerst verneemt dat een terugboekingsannulering is binnengekomen, dus het aansluiten ervan is wat je in staat stelt te stoppen met het bedienen van een klant voor wie je niet langer wordt betaald.

Een terugbetaling op Google Play hoeft niet iets te zijn dat je later in een rapport ontdekt. Google Play kan je server direct een melding van een geannuleerde aankoop sturen zodra een aankoop wordt geannuleerd, of de koper nu een selfservice-terugbetaling nam, een supportmedewerker er een verleende, een bank een terugboeking afdwong, of je de bestelling zelf terugbetaalde met de intrekvlag aan. Het bericht is piepklein, het noemt de exacte aankoop, en het draagt één instructie, geef het recht terug, want het geld is al weg.

Wat een melding van een geannuleerde aankoop eigenlijk is

Een melding van een geannuleerde aankoop is één type van Google Play's Real-time Developer Notifications, oftewel RTDN. RTDN is een push-kanaal. Google publiceert een bericht naar een Cloud Pub/Sub-onderwerp dat je bezit, en je backend ontvangt het binnen enkele ogenblikken na de gebeurtenis, in plaats van erachter te komen bij je volgende geplande poll. Dat is het hele punt van de melding van een geannuleerde aankoop ten opzichte van het oudere pull-pad: je hoort van de terugbetaling terwijl ze gebeurt, niet uren later.

Het pull-pad bestaat nog steeds en doet er nog steeds toe. De Voided Purchases API laat je server, op je eigen schema, vragen om de lijst van aankopen die in een tijdvak zijn geannuleerd. De twee vullen elkaar aan. De melding vertelt je het moment dat één aankoop omslaat; de API laat je in bulk afstemmen en alles bijwerken wat een gemist bericht zou hebben achtergelaten.

Ze reist mee binnen een Real-time Developer Notification

De melding van een geannuleerde aankoop arriveert nooit op zichzelf. Ze zit binnen een DeveloperNotification-omhulsel, en dat omhulsel wordt geleverd als één base64-gecodeerde string in het veld data van het Pub/Sub-bericht. Je handler decodeert die string naar JSON voordat hij iets kan lezen. Het omhulsel noemt altijd de app en de tijd van de gebeurtenis, en het bevat precies één meldingsobject van de vijf die Google definieert. Ze sluiten elkaar uit, dus een bericht dat een voidedPurchaseNotification draagt zal niet ook een abonnements- of eenmalige gebeurtenis dragen.

OmhulselveldWat het bevat
versionDe schemaversie van de melding, bijvoorbeeld 1.0
packageNameDe app waar de gebeurtenis bij hoort, bijvoorbeeld com.acme.app
eventTimeMillisWanneer de gebeurtenis plaatsvond, in milliseconden sinds epoch
Een van vijf meldingsobjectenoneTimeProductNotification, subscriptionNotification, voidedPurchaseNotification, pendingRefundReviewNotification of testNotification. Per bericht is er slechts één aanwezig

De vier velden die ze draagt

Haal het omhulsel eraf en de melding van een geannuleerde aankoop is zelf vier velden. Dat is bewust karig. Google's standpunt is dat als alles wat je nodig hebt is de juiste aankoop vinden en het recht aanpassen, deze vier genoeg zijn, en je geen enkele API hoeft terug te bellen om te handelen.

VeldWat het isHoe je het gebruikt
purchaseTokenDe token die aan het toestel werd gegeven toen het item werd gekochtJe primaire sleutel. Koppel hem aan het aankooprecord dat je bij het verlenen opsloeg
orderIdHet bestel-id dat aan de koper wordt getoond, bijvoorbeeld GS.0000-0000-0000Een voor mensen leesbare tweede sleutel voor support en afstemming
productTypeOf het geannuleerde item een abonnement of een eenmalige aankoop wasStuur naar het juiste intrekpad
refundTypeOf de annulering een volledige terugbetaling of een terugbetaling op basis van aantal wasBeslis of je alles intrekt of alleen het terugbetaalde aantal

productType vertelt je wat er is geannuleerd

productType is een klein geheel getal, en het bepaalt welk van je intrekpaden je neemt. Een abonnementsannulering moet lopende toegang afwikkelen; een annulering van een eenmalige aankoop verwijdert simpelweg een enkel recht.

Waarde `productType`ConstanteBetekenis
1PRODUCT_TYPE_SUBSCRIPTIONEen abonnementsaankoop werd geannuleerd
2PRODUCT_TYPE_ONE_TIMEEen eenmalige aankoop werd geannuleerd

refundType vertelt je hoeveel er terugkwam

refundType scheidt een schone volledige terugdraaiing van een gedeeltelijke. Het gedeeltelijke geval is smal. Het verschijnt alleen wanneer bij een eenmalige aankoop met meerdere stuks een deel, maar niet het hele aantal, werd terugbetaald.

Waarde `refundType`ConstanteBetekenis
1REFUND_TYPE_FULL_REFUNDDe aankoop werd volledig geannuleerd
2REFUND_TYPE_QUANTITY_BASED_PARTIAL_REFUNDEen deel van een aankoop met meerdere stuks werd geannuleerd

Zet het eerst aan, anders komt het nooit

Meldingen van geannuleerde aankopen stromen niet standaard binnen. Je schakelt RTDN één keer in, in Play Console, en richt het op een Pub/Sub-onderwerp dat je beheert. De schakelaar staat onder Monetize, dan Monetization setup, in de sectie Real-time developer notifications boven aan de pagina. Vink Enable real-time notifications aan, plak vervolgens je volledige onderwerpnaam in de vorm projects/{project_id}/topics/{topic_name}, en gebruik Send Test Message om te bevestigen dat de leiding werkt voordat je erop vertrouwt.

De inhoudsschakelaar is waar mensen geannuleerde aankopen mislopen. Beide keuzes omvatten ze, dus je kunt niet per ongeluk terugbetalingen weigeren terwijl je abonnementen behoudt.

  • Ontvang meldingen voor abonnementen en alle geannuleerde aankopen. Je ontvangt abonnementsgebeurtenissen en elke geannuleerde aankoop, maar geen aankoopgebeurtenissen van eenmalige producten.
  • Ontvang alle meldingen voor abonnementen en eenmalige producten. Je ontvangt het bovenstaande plus gebeurtenissen van eenmalige producten zoals ONE_TIME_PRODUCT_PURCHASED en ONE_TIME_PRODUCT_CANCELED.
Een creditcard met de voorkant naar beneden naast een papieren bon, staand voor een geannuleerde Google Play-aankoop

Wat het je kost, in geld

Een annulering is een verlies dat al is geboekt tegen de tijd dat de melding je bereikt. De verkoopprijs is weg, en zo ook alles wat je uitgaf om die klant te bedienen. Als ze afbeeldingen genereerden, calls tegen je modellen uitvoerden, opslag aanspraken, of een uitbetaling aan een derde partij in gang zetten, werden die kosten met echt geld betaald en komen ze niet terug met de terugbetaling. De melding kan niets daarvan terughalen. Wat ze wel kan doen is het bloeden vanaf hier stoppen, wat de hele reden is om er snel op te handelen.

Het bloeden is het ergst bij abonnementen en het ergst bij terugboekingen. Een abonnement dat je niet intrekt blijft je geld kosten om te bedienen, maand na maand, voor een klant die niet langer betaalt. En een terugboeking is de duurste soort annulering. Vanaf August 3, 2026 stelt Google's documentatie dat een terugboeking de aankoopprijs plus de bankkosten doorgeeft aan de ontwikkelaar. De melding van een geannuleerde aankoop is vaak de eerste plek waar je eigen systemen horen dat een terugboeking is voltooid, dus een handler die ter plekke intrekt is wat een verloren verkoop ervan weerhoudt te veranderen in een verloren verkoop plus weken gratis service.

Hoe je een melding van een geannuleerde aankoop afhandelt, stap voor stap

Verifieer het bericht en verwijder duplicaten

  • Bevestig dat het Pub/Sub-bericht van Google komt en gericht is op het onderwerp dat je hebt geconfigureerd, en decodeer vervolgens het base64-veld data om de DeveloperNotification-JSON te krijgen.
  • Gebruik de Pub/Sub messageId om duplicaten te laten vallen. Google waarschuwt dat dezelfde melding meer dan eens kan worden bezorgd, dus behandel herhaling als normaal en maak je handler idempotent.
  • Bevestig (acknowledge) het bericht pas nadat je het veilig hebt vastgelegd, zodat een crash midden in de handler de gebeurtenis niet verliest.

Zoek de aankoop op

  • Koppel de purchaseToken aan de aankoop die je opsloeg toen je het recht voor het eerst verleende. Val terug op orderId voor supportopzoekingen en handmatige afstemming.
  • Lees productType om het abonnements- of eenmalige intrekpad te kiezen, en lees refundType om te beslissen tussen een volledige en een gedeeltelijke intrekking.

Trek in en leg vast

  • Verwijder het recht. Bij een volledige terugbetaling snijd je de toegang tot het item af. Bij een terugbetaling op basis van aantal verlaag je het verleende aantal met het terugbetaalde bedrag en laat je de rest intact.
  • Noteer wat je deed en wanneer, met purchaseToken en orderId als sleutel. Dat record is wat je later een supportticket laat beantwoorden, en wat de Voided Purchases API netjes laat afstemmen tegen je eigen staat.

Waar het staat tussen de andere terugbetalingssignalen

Een melding van een geannuleerde aankoop is een kennisgeving, geen onderhandeling. Ze vertelt je een uitkomst die al is beslist. Het is de moeite waard haar naast de signalen te zien waarmee ze gemakkelijk te verwarren is, want slechts enkele ervan vragen ooit om jouw kant van het verhaal.

SignaalRichtingNeemt het jouw input op
Melding van een geannuleerde aankoop (RTDN)Google pusht naar je serverNee. Ze rapporteert een annulering die al is gebeurd
Voided Purchases APIJe server haalt op bij GoogleNee. Het is een alleen-lezen lijst van eerdere annuleringen
pendingRefundReviewNotification (RTDN)Google pusht naar je serverJa, indirect. Het markeert een terugboeking die je vervolgens aanvecht via orders.reviewrefund binnen 24 uur
Apple CONSUMPTION_REQUESTApple vraagt je serverJa. Je antwoordt met Send Consumption Information binnen 12 uur

De les om vast te houden is eenvoudig. Over beide stores zijn er precies twee terugbetalingsstromen waar de ontwikkelaar iets in te brengen heeft, Apple's CONSUMPTION_REQUEST en Google Play's chargeback-beoordeling. Een melding van een geannuleerde aankoop is geen van beide. Tegen de tijd dat ze je bereikt, ligt de beslissing achter je en het enige wat in jouw handen rest is hoe snel je intrekt.

Veelgestelde vragen

Wat betekent een melding van een geannuleerde aankoop op Google Play?
Het betekent dat een aankoop werd terugbetaald, teruggeboekt of anderszins geannuleerd, en dat de klant zijn geld terug heeft. Google's richtlijn is om de toegang tot de bijbehorende inhoud in te trekken, omdat de koper het recht niet langer zou moeten bezitten. De melding noemt de exacte aankoop via haar `purchaseToken` en `orderId`.
Welke velden bevat een Google Play-melding van een geannuleerde aankoop?
Vier: `purchaseToken`, `orderId`, `productType` en `refundType`. `productType` is `1` voor een abonnement en `2` voor een eenmalige aankoop. `refundType` is `1` voor een volledige terugbetaling en `2` voor een terugbetaling op basis van aantal bij een aankoop met meerdere stuks.
Hoe zet ik meldingen van geannuleerde aankopen aan?
Open in Play Console Monetize en dan Monetization setup, en vink in de sectie Real-time developer notifications Enable real-time notifications aan, en voer vervolgens de naam van je Cloud Pub/Sub-onderwerp in. Beide inhoudsopties, abonnementen plus alle geannuleerde aankopen, en dat plus gebeurtenissen van eenmalige producten, omvatten geannuleerde aankopen.
Wat is het verschil tussen de melding van een geannuleerde aankoop en de Voided Purchases API?
De melding is een push-signaal dat in realtime via Cloud Pub/Sub wordt bezorgd op het moment dat een aankoop wordt geannuleerd. De Voided Purchases API is een pull-pad dat je server op zijn eigen schema bevraagt om annuleringen over een tijdvak op te sommen. Gebruik de melding om onmiddellijk te reageren en de API om af te stemmen en bij te werken.
Laat een melding van een geannuleerde aankoop me de terugbetaling aanvechten?
Nee. Het is een kennisgeving achteraf van een beslissing die al is genomen. De enige Google Play-stroom die jouw input opneemt is de chargeback-beoordeling via `orders.reviewrefund`, waarop je 24 uur hebt om te antwoorden, en op Apple is het de CONSUMPTION_REQUEST met een venster van 12-hour.

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.