Eine Rückerstattung bei Google Play erfolgt lautlos. Die Zahlung wird rückgängig gemacht, der Kunde nutzt die App weiter, und auf Ihrer Seite ändert sich nichts, es sei denn, Sie prüfen es bewusst. Genau dafür ist die Voided Purchases API da. Sie liefert die Bestellungen zurück, die storniert, erstattet oder zurückgebucht wurden, damit Sie den Zugriff auf das entziehen können, wofür der Kunde nicht mehr bezahlt. Verbinden Sie damit einen geplanten Job, lesen Sie die Rückmeldung aus und widerrufen Sie die Berechtigung. Das ist der gesamte Mechanismus.
Ein Punkt stolpert fast jedes Team, und er liegt in der Richtlinie, nicht im Code. Diese API listet nur Bestellungen, die tatsächlich widerrufen wurden. Erstatten Sie einen Kauf in der Play Console, ohne die Option „Widerrufen“ zu aktivieren, taucht diese Bestellung hier nie auf – Ihr Job läuft dann einwandfrei, während ein erstatteter Kunde mit allem davonzieht, was Sie verkauft haben. Im Folgenden finden Sie die API Feld für Feld, die Limits, die sie begrenzen, und wo das Geld still und leise versickert, wenn sie nicht angebunden ist.
Das Wichtigste in Kürze
Die Voided Purchases API, erreichbar über die Methode purchases.voidedpurchases.list, listet Bestellungen auf, die Google Play storniert, erstattet oder zurückgebucht hat. Darauf können Sie ein System aufbauen, das den Zugriff auf Käufe entzieht, die der Kunde nicht mehr besitzt.
Sie zeigt ausschließlich widerrufene Bestellungen. Eine vom Entwickler ausgelöste Rückerstattung ohne Widerruf bleibt hier unsichtbar – wer den Zugriff entziehen will, muss also mit aktiviertem Widerruf erstatten.
Ihre Reichweite umfasst rollierend 30 Tage. Da startTime nicht weiter als 30 Tage zurückgehen kann, verliert jeder Server, der länger als einen Monat offline ist, diese Widerrufe unwiderruflich – deshalb muss das Polling nach einem festen Zeitplan laufen.
voidedSource gibt an, wer den Widerruf ausgelöst hat: 0 für den Kunden, 1 für den Entwickler, 2 für Google. voidedReason erklärt den Grund und reicht von 0 für „Other“ bis 7 für „Chargeback“ und 8 für „Unacknowledged_purchase“.
Echtzeit-Entwicklerbenachrichtigungen lösen in dem Moment, in dem ein Kauf widerrufen wird, eine VoidedPurchaseNotification aus – behandeln Sie das jedoch nur als Hinweis. Bestätigen Sie den Sachverhalt über die Voided Purchases API, bevor Sie etwas widerrufen.
Unterscheiden Sie Abo-Verlängerungen anhand der orderId, niemals anhand des purchaseToken. Ein einziges purchaseToken umfasst sämtliche Verlängerungen eines Abonnements, sodass das Token allein eine Periode nicht von der nächsten trennen kann.
Die Obergrenzen liegen bei 6,000 Abfragen pro Tag und 30 innerhalb eines beliebigen 30-Sekunden-Zeitraums. Begrenzen Sie daher jede Anfrage auf ein Zeitfenster und blättern Sie mit dem Continuation-Token durch, statt eine Anfrage pro Bestellung zu senden.
Was die API zurückliefert
Der Endpunkt beantwortet genau eine Frage: Welche Bestellungen dieser App wurden zuletzt widerrufen. Ein Widerruf fasst drei Ausgänge zusammen, die alle das Geld des Kunden zurückgeben, nämlich eine Stornierung, eine Rückerstattung oder eine Rückbuchung. Er erreicht sowohl einmalige In-App-Produkte als auch Abonnements, und ein Parameter legt den Umfang fest. Lassen Sie type auf dem Standardwert 0, erhalten Sie nur widerrufene In-App-Produktkäufe zurück. Setzen Sie type auf 1, erhalten Sie widerrufene In-App-Käufe und widerrufene Abo-Käufe gemeinsam.
Jedes Element in der Antwort ist ein voidedPurchase-Objekt mit einem kurzen, aber wertvollen Satz an Feldern:
orderId kennzeichnet eindeutig einen einmaligen Kauf, ein Abonnement oder eine einzelne Verlängerung darin. Behandeln Sie dies als Ihren Verknüpfungsschlüssel.
purchaseToken identifiziert einen einmaligen Kauf oder ein Abonnement, trennt dabei aber keine Verlängerungen – verlassen Sie sich dafür auf orderId.
purchaseTimeMillis erfasst, wann der Kauf stattfand, in Millisekunden seit der Epoche.
voidedTimeMillis erfasst, wann er storniert, erstattet oder zurückgebucht wurde, ebenfalls in Millisekunden seit der Epoche.
voidedSource benennt, wer den Widerruf ausgelöst hat: 0 steht für den Kunden, 1 für den Entwickler und 2 für Google.
voidedReason gibt die Ursache als Ganzzahl von 0 bis 8 an.
voidedQuantity enthält die widerrufene Menge aus einer mengenbasierten Teilerstattung und erscheint nur, wenn includeQuantityBasedPartialRefund auf true gesetzt ist.
Da ein purchaseToken ein gesamtes Abonnement abdeckt, während jede Verlängerung eine neu vergebene orderId erhält, führt eine Verknüpfung Ihrer Berechtigungen über das Token dazu, dass Sie den falschen Zeitraum widerrufen. Verknüpfen Sie stattdessen über orderId.
Lesen Sie voidedReason, bevor Sie etwas anfassen
voidedReason verwandelt eine bloße Liste in eine echte Entscheidung, denn eine Rückerstattung wegen Meinungsänderung und eine Rückbuchung durch die Bank laufen über denselben Feed, obwohl sie grundverschieden sind. Die vollständige Liste lautet:
1. Other ist keiner Kategorie zugeordnet. Widerrufen Sie und machen Sie weiter.
2. Remorse ist ein Kunde, der es sich anders überlegt hat – eine alltägliche Rückerstattung.
3. Not_received ist die Behauptung, das Produkt sei nie angekommen – ein Blick auf Ihre Auslieferung lohnt sich.
4. Defective bedeutet, dass es nicht funktioniert hat – ein Qualitätssignal, das Sie erfassen sollten.
5. Accidental_purchase ist ein versehentlicher Kauf, häufig auf einem gemeinsam genutzten Gerät.
6. Fraud ist eine Transaktion, die Google als betrügerisch eingestuft hat.
7. Friendly_fraud ist eine Rückbuchung, bei der der tatsächliche Karteninhaber eine Zahlung anfechtet, die er selbst getätigt hat.
8. Chargeback ist die Bank des Kunden, die die Zahlung rückgängig macht – bei der Bank endgültig und nun Ihnen in Rechnung gestellt.
9. Unacknowledged_purchase ist eine automatische Rückerstattung durch Google für einen Kauf, den Ihre App nie bestätigt hat.
Grund 9 ist eine Rückerstattung, die Sie sich selbst zuzuschreiben haben. Jeder Kauf, den Ihre App unbestätigt lässt, wird von Google automatisch erstattet – ein unacknowledged_purchase in diesem Feed ist also Umsatz, der an einen einzigen ausgelassenen Aufruf verloren geht, nicht an eine Entscheidung des Käufers.
Das 30-Tage-Fenster, das die Liste still und leise leert
Die API reicht nicht weiter als 30 Tage zurück. startTime liegt standardmäßig bei „jetzt minus 30 Tage“ und lässt sich nicht früher setzen, und endTime steht standardmäßig auf der Gegenwart – Sie erhalten also ein rollierendes Ein-Monats-Fenster und kein dauerhaftes Archiv.
Die Konsequenz ist drastisch. Bricht ein Polling-Job ab und bleibt das fünf Wochen unbemerkt, sind die Widerrufe der ersten Woche bereits aus der API herausgefallen – kein Aufruf kann sie zurückholen. Diese Bestellungen bleiben nicht widerrufen, und Sie würden es nicht einmal bemerken, hätten Sie sie nicht anderswo erfasst. Das Netz hat ein Loch, genau so groß wie Ihr längster Ausfall. Pollen Sie mindestens täglich und gleichen Sie gegen die Echtzeitbenachrichtigungen ab – behandeln Sie die 30 Tage als die harte Löschuhr, die sie tatsächlich sind.
Ob eine Bestellung überhaupt auftaucht, hängt vom Widerruf ab
Das ist der Hauptgrund, warum Teams die API für defekt halten. Sie liefert ausschließlich widerrufene Bestellungen zurück. Von Kunden gestartete Rückerstattungen, Stornierungen, Rückbuchungen und von Google ausgelöste Rückerstattungen widerrufen alle automatisch und landen deshalb immer im Feed. Eine vom Entwickler ausgelöste Rückerstattung ist die Ausnahme. Erstatten Sie selbst, ob über die Play Console oder über die Orders API, bleibt die Entscheidung über den Widerruf eine separate Entscheidung, die Sie treffen müssen. Lehnen Sie sie ab, wird die Bestellung mit dem Kunden abgewickelt, taucht aber nie in diesem Feed auf.
Die Lehre daraus ist kurz. Wenn Ihr Ziel der Zugriffsentzug ist, erstatten Sie mit aktiviertem Widerruf. Lassen Sie das aus, haben Sie das Geld zurückgegeben und die Tür offen gelassen – und Ihr Widerruf-Job, egal wie sorgfältig gebaut, hat dann nichts, womit er arbeiten kann.
Pollen, ohne das Kontingent zu sprengen
Der Endpunkt ist ratenbegrenzt, und die Obergrenzen liegen niedrig genug, dass eine unachtsame Schleife sie reißt. Sie erhalten 6,000 Abfragen pro Tag, gezählt in Pacific Time, und nie mehr als 30 innerhalb eines beliebigen 30-Sekunden-Zeitraums. Dieses Budget passt zu fenstergestütztem Polling und bestraft jedes Design mit einem Aufruf pro Bestellung.
Zeitfenster und das Continuation-Token
maxResults liegt standardmäßig bei 1,000, und das ist zugleich der Höchstwert. Enthält ein Fenster mehr Widerrufe, als eine Seite fassen kann, kommt die Antwort mit einem tokenPagination-Objekt, das ein nextPageToken enthält. Geben Sie dieses Token bei Ihrem nächsten Aufruf zurück, um durch die Seiten zu blättern. Legen Sie die Grenzen des Fensters mit startTime und endTime fest, blättern Sie weiter, bis das Token versiegt, und verschieben Sie das Fenster erst dann weiter. Dieser Rhythmus bleibt sowohl unter der 30-Sekunden-Burst-Grenze als auch unter dem Tageskontingent.
Echtzeitbenachrichtigungen schließen die Tageslücke
Selbst tägliches Polling lässt Sie bis zu 24 Stunden blind, und lange Lücken sind genau das, was das 30-Tage-Fenster bestraft. Echtzeit-Entwicklerbenachrichtigungen schließen diese Verzögerung. In dem Moment, in dem ein Kauf widerrufen wird, wird eine VoidedPurchaseNotification an ein Cloud Pub/Sub-Topic unter Ihrer Kontrolle veröffentlicht, und Ihr Backend verarbeitet sie innerhalb von Sekunden. Ihre Payload bleibt kompakt:
purchaseToken ist das Token aus dem ursprünglichen Kauf.
orderId ist die ID für die widerrufene Transaktion, pro Abo-Verlängerung neu vergeben.
productType ist 1 für ein Abonnement und 2 für einen einmaligen Kauf.
refundType unterscheidet eine vollständige Rückerstattung, gekennzeichnet mit 1, von einer mengenbasierten Teilerstattung, gekennzeichnet mit 2.
Verstehen Sie die Benachrichtigung als Alarm, nicht als Tatsache. Sobald eine VoidedPurchaseNotification eintrifft, fragen Sie die Voided Purchases API ab, um zu bestätigen, wie der Status der Bestellung tatsächlich ist, und widerrufen Sie erst danach. Der Alarm sagt Ihnen, dass Sie prüfen sollen; die API sagt Ihnen die Wahrheit.
Was es Sie an Geld kostet
Die API ist die Verrohrung, aber der Grund, sie zu verlegen, ist eine Rechnung – und zwei der Posten darauf steigen.
Ab dem 3. August 2026 geht die Rückbuchungsrechnung auf Ihr Konto
Ab dem 3. August 2026 verlagert Google die Kosten einer Rückbuchung auf den Entwickler. Sie verlieren den Kaufpreis und übernehmen zusätzlich die Rückbuchungsgebühr der Bank. Ein voidedReason von 7 ist dann nicht mehr nur ein entgangener Verkauf, sondern ein Posten mit angehängter Gebühr. Die Rückbuchung selbst lässt sich nicht umkehren, da sie bei der Bank endgültig ist, aber ein schnell erkannter Widerruf erlaubt es Ihnen, die Berechtigung zu entziehen und, bei allem, was noch laufend geliefert wird, die Ausgaben für einen Kunden zu stoppen, der erstattet und dann zurückgebucht wurde.
Sie finanzieren weiterhin einen Kunden, der bereits erstattet wurde
Der Verkaufspreis ist in dem Moment weg, in dem ein Widerruf eintrifft. Was Sie noch kontrollieren, sind die Kosten, die Lieferung fortzusetzen. Für jede Stunde, in der eine erstattete Berechtigung aktiv bleibt, laufen die Rechnungen, die der Kunde nicht mehr deckt, weiter auf Ihrer Seite auf: die Rechenleistung, die Aufrufe des Modellanbieters, der Speicher und jede Auszahlung an Creator oder Partner, die seine Aktivität auslöst. Die Widerruf-Pipeline auf Basis dieser API aufzubauen ist der Weg, diese Ausgaben abzuschalten. Lassen Sie das aus, finanzieren Sie das Produkt für Leute, die der Store bereits entschädigt hat.
Friendly Fraud ist ein Trend, kein Einzelfall
Ein voidedReason von 5 oder 6 steht selten allein. Fraud und Friendly Fraud ballen sich um Accounts, Geräte und gelegentlich bestimmte Aktionen. Da die API jedem Widerruf voidedSource und voidedReason beifügt, haben Sie genug, um Missbrauch pro Account als Trend zu erkennen, statt jede Rückbuchung als isolierten Verlust hinzunehmen. Ein Account, der ein zweites Mal zurückbucht, sagt Ihnen, was die erste Rückerstattung nicht verraten hat.
Alles zusammengeführt
Das gesamte Modell ist klein, sobald die Teile vorliegen. Hören Sie in Echtzeit auf VoidedPurchaseNotification, damit nichts einen vollen Tag warten muss. Behandeln Sie die Voided Purchases API als Quelle der Wahrheit, verknüpft über orderId, damit Verlängerungen nie verschwimmen. Lesen Sie voidedSource und voidedReason, damit eine Rückbuchung getrennt von einer Reue-Rückerstattung behandelt wird. Pollen Sie in einem Rhythmus, der eng genug ist, dass das 30-Tage-Fenster nie zuschlägt, und erstatten Sie mit aktiviertem Widerruf, sobald Sie den Zugriff entziehen wollen.
Das ist die Ebene, die Refund Sensor für Sie übernimmt. Sie verarbeitet die Echtzeitbenachrichtigungen, gleicht jeden Widerruf mit der API ab, widerruft die genaue Bestellung statt des gesamten Produkts und hält eine Rückbuchung durch die Bank getrennt von einer gewöhnlichen Rückerstattung, damit die teuren Fälle sichtbar werden statt sich zu verstecken. Sie erhalten den Zugriffsentzug innerhalb von Sekunden und eine vollständige Aufzeichnung darüber, wer was wann widerrufen hat und warum – ohne dass Sie eine Pub/Sub-Pipeline oder einen Polling-Job selbst aufbauen müssen.
Wo diese Regeln dokumentiert sind
Google Play Developer API: der Leitfaden zur Voided Purchases API
Google Play Developer API: die Methode purchases.voidedpurchases.list
Android Developers: Referenz zu Echtzeit-Entwicklerbenachrichtigungen für VoidedPurchaseNotification
Android Developers: Betrug und Missbrauch bekämpfen mit Play Billing
Häufig gestellte Fragen
Weil der Feed ausschließlich widerrufene Bestellungen enthält. Vom Kunden gestartete Rückerstattungen sowie Stornierungen, Rückbuchungen und von Google ausgelöste Rückerstattungen widerrufen von selbst und erscheinen immer. Eine Rückerstattung, die Sie selbst auslösen, taucht nur auf, wenn Sie zusätzlich den Widerruf aktiviert haben. Erstatten Sie ohne zu widerrufen, ist die Bestellung abgewickelt, hier aber unsichtbar – aktivieren Sie den Widerruf also immer dann, wenn Ihr Ziel der Zugriffsentzug ist.
Dreißig Tage, und keinen Tag weiter. startTime liegt standardmäßig bei der aktuellen Zeit minus 30 Tage und lehnt jeden früheren Wert ab, sodass sich der Endpunkt wie ein rollierendes Ein-Monats-Fenster verhält, nicht wie ein Archiv. Ist ein Widerruf älter als 30 Tage, ist er verschwunden, ohne Möglichkeit, ihn zurückzuholen – genau deshalb pollen Sie nach einem festen Zeitplan und stützen das mit Echtzeitbenachrichtigungen ab.
Beides hat seine Funktion. Eine VoidedPurchaseNotification erreicht Sie innerhalb von Sekunden und fordert Sie zur Prüfung auf, aber Googles Empfehlung ist, sie als Signal zu behandeln, nicht als Tatsache. Bestätigen Sie den aktuellen Status über die Voided Purchases API und widerrufen Sie erst dann. Die Benachrichtigung eliminiert die Verzögerung; die API liefert die verbindlichen Werte voidedSource und voidedReason, auf deren Grundlage Sie tatsächlich handeln.
Sehen Sie sich voidedReason an. Eine 7 ist eine Rückbuchung, bei der die Bank des Kunden die Zahlung rückgängig gemacht hat, und eine 6 ist Friendly Fraud. Eine 1 ist eine gewöhnliche Rückerstattung wegen Meinungsänderung. Die Unterscheidung ist wichtig, denn ab dem 3. August 2026 gibt Google den Rückbuchungsbetrag und die Bankgebühr an den Entwickler weiter, sodass eine 7 Sie mehr kostet als eine einfache Rückerstattung.
Ja. Setzen Sie den Parameter type auf 1, erhalten Sie widerrufene In-App-Käufe zusammen mit widerrufenen Abo-Käufen; der Standardwert 0 liefert nur In-App-Produkte. Bei Abonnements legen Sie den genauen widerrufenen Zeitraum über orderId fest, da ein einzelnes purchaseToken jede Verlängerung umfasst, während jede Verlängerungstransaktion ihre eigene orderId erhält.



