Wenn ein Google-Play-Kauf erstattet oder zurückgebucht wird, ist die Voided Purchases API der Weg, es zu erfahren
Google Play macht einen Kauf still ungültig, wenn er erstattet oder zurückgebucht wird. Die Voided Purchases API ist die Liste dieser Bestellungen, damit Sie den Zugriff entziehen können. Hier finden Sie jedes Feld, das 30-Tage-Fenster, die Widerrufsoption, die Bestellungen verbirgt, und was es kostet.

Wichtigste Erkenntnisse
- Die Voided Purchases API, die Methode purchases.voidedpurchases.list, gibt Bestellungen zurück, die Google Play storniert, erstattet oder zurückgebucht hat, damit Sie ein Widerrufssystem bauen können, das den Zugriff auf das kappt, was dem Kunden nicht mehr gehört.
- Nur widerrufene Bestellungen erscheinen. Eine vom Entwickler ausgestellte Erstattung ohne die Widerrufsoption ist für diese API unsichtbar, wenn Sie also den Zugriff entziehen wollen, müssen Sie mit aktiviertem Widerruf erstatten.
- Das Fenster beträgt 30 Tage. startTime darf nicht älter als 30 Tage zurück sein, ein Server, der länger als einen Monat ausfällt, verliert diese ungültig gemachten Bestellungen also für immer. Fragen Sie nach einem Zeitplan ab.
- voidedSource sagt Ihnen, wer die Bestellung ungültig gemacht hat: 0 ist der Nutzer, 1 ist der Entwickler, 2 ist Google. voidedReason sagt Ihnen den Grund, von 0 Other bis 7 Chargeback und 8 Unacknowledged_purchase.
- Real-time developer notifications senden eine VoidedPurchaseNotification in dem Moment, in dem ein Kauf ungültig gemacht wird, behandeln Sie sie aber als Signal. Rufen Sie die Voided Purchases API für die maßgebliche Liste auf, bevor Sie widerrufen.
- Identifizieren Sie Abo-Verlängerungen über orderId, nicht über purchaseToken. Ein purchaseToken deckt jede Verlängerung eines Abos ab, das Token allein kann also zwei Verlängerungen nicht auseinanderhalten.
- Die Kontingente betragen 6.000 Abfragen pro Tag und 30 Abfragen in jedem 30-Sekunden-Fenster, blättern Sie also mit dem Fortsetzungstoken durch die Ergebnisse und fragen Sie nach Zeitfenster ab, niemals ein Aufruf pro Bestellung.
Eine Erstattung bei Google Play klopft nicht an Ihre Tür. Das Geld fließt ab, der Kunde behält die App offen, und solange Sie nicht nachschauen, ändert sich auf Ihrer Seite nichts. Die Voided Purchases API ist der Ort, an dem Sie nachschauen. Sie reicht Ihnen eine Liste von Bestellungen, die storniert, erstattet oder zurückgebucht wurden, damit Sie den Zugriff auf das entziehen können, wofür der Kunde nicht mehr zahlt. Richten Sie einen geplanten Job darauf, lesen Sie die Liste, kappen Sie die Berechtigung. Das ist die ganze Schleife.
Es gibt einen Haken, über den die meisten Teams stolpern, und er steckt nicht im Code. Nur Bestellungen, die widerrufen wurden, erscheinen hier. Wenn Sie einen Kauf in der Play Console erstatten, ohne die Widerrufsoption anzuhaken, erreicht diese Bestellung diese API nie, und Ihr Job läuft sauber durch, während ein erstatteter Kunde alles behält, was Sie ihm verkauft haben. Dieser Beitrag geht die API Feld für Feld durch, die Zahlen, die sie begrenzen, und die Stelle, an der das Geld verloren geht, wenn Sie sie überspringen.
Was die Voided Purchases API tatsächlich zurückgibt
Die API beantwortet eine Frage: welche Bestellungen dieser App kürzlich ungültig gemacht wurden. Ein Ungültigmachen umfasst drei Ausgänge, die alle damit enden, dass der Kunde sein Geld zurückbekommt. Eine Stornierung, eine Erstattung oder eine Rückbuchung. Es gilt für einmalige In-App-Produkte und für Abos, und den Umfang wählen Sie mit einem einzigen Parameter. Setzen Sie type auf 0, und Sie erhalten nur ungültig gemachte Käufe von In-App-Produkten, das ist die Voreinstellung. Setzen Sie ihn auf 1, und Sie erhalten ungültig gemachte In-App-Käufe und ungültig gemachte Abo-Käufe zusammen.
Jeder Eintrag in der Liste ist ein Objekt eines ungültig gemachten Kaufs. Die Felder sind wenige, und jedes einzelne davon zählt.
Die Felder eines ungültig gemachten Kaufs
| Feld | Was es enthält |
|---|---|
| orderId | Die Bestell-ID, die einen Einmalkauf, einen Abo-Kauf oder eine einzelne Abo-Verlängerung eindeutig identifiziert. Dies ist Ihr Join-Schlüssel |
| purchaseToken | Das Token, das einen Einmalkauf oder ein Abo identifiziert. Es unterscheidet keine Verlängerungen, verwenden Sie dafür also orderId |
| purchaseTimeMillis | Wann der Kauf getätigt wurde, in Millisekunden seit der Epoche |
| voidedTimeMillis | Wann der Kauf storniert, erstattet oder zurückgebucht wurde, in Millisekunden seit der Epoche |
| voidedSource | Wer das Ungültigmachen ausgelöst hat: 0 Nutzer, 1 Entwickler, 2 Google |
| voidedReason | Warum der Kauf ungültig gemacht wurde, eine ganze Zahl von 0 bis 8 |
| voidedQuantity | Die ungültig gemachte Menge aus einer mengenbasierten Teilerstattung, nur zurückgegeben, wenn includeQuantityBasedPartialRefund true ist |
Lesen Sie voidedReason, bevor Sie handeln
voidedReason ist das Feld, das eine rohe Liste in eine Entscheidung verwandelt. Eine Erstattung wegen Reue des Käufers und eine Bankrückbuchung landen in derselben Liste, aber sie sind nicht dasselbe Ereignis, und die Preisgestaltung ab August macht eines davon teuer. Hier ist der vollständige Satz.
| voidedReason | Label | Was es für Sie bedeutet |
|---|---|---|
| 0 | Other | Es wurde keine Kategorie zugewiesen. Widerrufen und weiter |
| 1 | Remorse | Der Käufer hat es sich anders überlegt. Eine gewöhnliche Erstattung |
| 2 | Not_received | Der Kunde sagt, er habe das Produkt nie erhalten. Es lohnt sich, Ihre Lieferung zu prüfen |
| 3 | Defective | Das Produkt hat nicht funktioniert. Ein Qualitätssignal, protokollieren Sie es |
| 4 | Accidental_purchase | Ein unbeabsichtigter Kauf, oft ein geteiltes Gerät |
| 5 | Fraud | Google hat die Transaktion als betrügerisch markiert |
| 6 | Friendly_fraud | Eine Rückbuchung, bei der der rechtmäßige Karteninhaber eine Belastung anficht, die er selbst getätigt hat |
| 7 | Chargeback | Die Bank des Kunden hat die Zahlung rückgängig gemacht. Bei der Bank endgültig, und jetzt Ihnen in Rechnung gestellt |
| 8 | Unacknowledged_purchase | Google hat einen Kauf automatisch erstattet, den Ihre App nie bestätigt hat |
Das 30-Tage-Fenster ist die Falle, die Ihre Liste leert
Die Voided Purchases API kann nur ungültig gemachte Käufe der letzten 30 Tage anzeigen. Der Parameter startTime hat als Voreinstellung die aktuelle Zeit minus 30 Tage und kann nicht älter als das gesetzt werden. endTime hat als Voreinstellung jetzt. Der Endpunkt ist also ein rollierendes Ein-Monats-Fenster, kein Archiv.
Die Folge ist unverblümt. Wenn Ihr Abfrage-Job ausfällt und es fünf Wochen lang niemand bemerkt, sind die Ungültigmachungen der ersten Woche aus der API herausgealtert. Es gibt keinen Aufruf, der sie zurückbringt. Sie werden diese Bestellungen nicht widerrufen, und Sie werden nicht einmal wissen, dass sie existierten, es sei denn, Sie haben sie auf andere Weise erfasst. Die API ist ein Sicherheitsnetz mit einem Loch in der Größe Ihres schlimmsten Ausfalls.
Die Widerrufsoption entscheidet, ob eine Bestellung überhaupt erscheint
Dies ist der bei weitem häufigste Grund, warum ein Team die API als kaputt meldet. Es werden nur widerrufene Bestellungen zurückgegeben. Vom Nutzer ausgelöste Erstattungen, Stornierungen, Rückbuchungen und von Google ausgelöste Erstattungen werden immer widerrufen, erscheinen also immer. Eine vom Entwickler ausgelöste Erstattung ist anders. Wenn Sie eine Bestellung selbst erstatten, über die Play Console oder die Orders API, wählen Sie, ob Sie sie auch widerrufen. Erstatten Sie ohne Widerruf, und die Bestellung ist mit dem Kunden erledigt, taucht aber nie in der Voided Purchases API auf.
Die Regel, die daraus folgt, ist einfach. Wenn Ihre Absicht ist, den Zugriff zu entziehen, erstatten Sie mit aktivierter Widerrufsoption. Andernfalls haben Sie das Geld zurückgegeben und die Tür offen gelassen, und Ihr Widerrufs-Job hat, so gut er auch geschrieben ist, nichts, worauf er reagieren könnte.
Wie Sie sie abfragen, ohne das Kontingent zu sprengen
Der Endpunkt ist ratenbegrenzt, und die Grenzen sind niedrig genug, dass eine naive Schleife sie erreicht. Sie haben 6.000 Abfragen pro Tag, gezählt in pazifischer Zeit, und höchstens 30 Abfragen in einem beliebigen 30-Sekunden-Zeitraum. Dieses Budget ist für gefensterte Abfrage ausreichend und für Designs mit einer Anfrage pro Bestellung feindlich.
Abfragefenster und das Fortsetzungstoken
maxResults hat als Voreinstellung 1.000, was auch die Obergrenze ist. Wenn ein Fenster mehr als eine Seite von Ungültigmachungen enthält, trägt die Antwort ein tokenPagination-Objekt mit einem nextPageToken. Geben Sie dieses Token beim nächsten Aufruf zurück, um durch die Seiten zu laufen. Setzen Sie startTime und endTime, um das Fenster einzugrenzen, das Sie interessiert, blättern Sie durch die Seiten, bis das Token ausgeht, und rücken Sie dann das Fenster vor. Dieses Muster hält Sie sowohl innerhalb der 30-Sekunden-Burst-Grenze als auch der Tagesobergrenze.
Real-time developer notifications schließen die Lücke
Jeden Tag abzufragen lässt immer noch bis zu einen Tag Blindheit, und das 30-Tage-Fenster bestraft lange Lücken. Real-time developer notifications beseitigen die Verzögerung. Google veröffentlicht eine VoidedPurchaseNotification in einem Cloud-Pub/Sub-Topic, das Ihnen gehört, in dem Moment, in dem ein Kauf ungültig gemacht wird, und Ihr Backend verarbeitet sie innerhalb von Sekunden. Die Nachricht ist klein.
| RTDN-Feld | Was es enthält |
|---|---|
| purchaseToken | Das Token aus dem ursprünglichen Kauf |
| orderId | Die Bestell-ID der ungültig gemachten Transaktion, eine neue pro Abo-Verlängerung |
| productType | 1 für ein Abo, 2 für einen Einmalkauf |
| refundType | 1 für eine vollständige Erstattung, 2 für eine mengenbasierte Teilerstattung |

Was Sie das an Geld kostet
Die API ist Installation, aber der Grund, sie zu verdrahten, ist eine Rechnung. Jede Ungültigmachung in dieser Liste entspricht einer echten Zahl, und zwei davon werden teurer.
Die Rückbuchungsrechnung landet ab dem 3. August 2026 bei Ihnen
Ab dem 3. August 2026 verlagert Google die Kosten einer Rückbuchung auf den Entwickler. Sie verlieren den Kaufpreis und zahlen obendrauf die Rückbuchungsgebühr der Bank. Ein voidedReason von 7 ist nicht länger nur ein verlorener Verkauf, es ist ein Posten mit angehängter Gebühr. Sie können eine Rückbuchung nicht rückgängig machen, sie ist bei der Bank endgültig, aber Sie können danach die Blutung stoppen. Die Ungültigmachung schnell zu erwischen, erlaubt Ihnen, die Berechtigung zu widerrufen und, für alles, was Sie noch liefern, aufzuhören, für einen Kunden zu zahlen, der erstattet und dann zurückgebucht wurde.
Sie zahlen weiter, um einen erstatteten Kunden zu bedienen
Der Kaufpreis ist in dem Moment weg, in dem eine Ungültigmachung erscheint. Was Sie noch kontrollieren, sind die Kosten dafür, weiter zu liefern. Jede Stunde, die eine erstattete Berechtigung aktiv bleibt, zahlen Sie weiter für die Dinge, die der Kunde nicht mehr finanziert: Rechenleistung, Modell-API-Aufrufe, Speicher und jede an seine Nutzung gebundene Auszahlung an Creator oder Partner. Ein von dieser API angetriebenes Widerrufssystem ist die Art, wie Sie diesen Zähler abstellen. Überspringen Sie es, und Sie finanzieren das Produkt für Leute, die der Store bereits entschädigt hat.
Friendly Fraud ist ein Muster, das sich zu verfolgen lohnt
Ein voidedReason von 5 oder 6 ist kein Einzelfall. Betrug und Friendly Fraud häufen sich nach Konto, nach Gerät und manchmal nach Aktion. Die API gibt Ihnen voidedSource und voidedReason bei jeder Ungültigmachung, was genügt, um Missbrauch nach Konto zu verfolgen, statt jede Rückabwicklung als isolierte Kosten zu behandeln. Ein Kunde, der zweimal zurückbucht, sagt Ihnen etwas, das die erste Erstattung nicht gesagt hat.
Die Verdrahtung auf die RefundHalt-Art
Das Modell ist klein, sobald Sie alle Teile beisammen haben. Hören Sie in Echtzeit auf VoidedPurchaseNotification, damit nichts einen ganzen Tag wartet. Rufen Sie die Voided Purchases API als Quelle der Wahrheit auf, mit Schlüssel auf orderId, damit Abo-Verlängerungen nie verwechselt werden. Lesen Sie voidedSource und voidedReason, damit eine Rückbuchung anders behandelt wird als eine Reue-Erstattung. Fragen Sie nach einem Zeitplan ab, der eng genug ist, dass das 30-Tage-Fenster nie zubeißt, und erstatten Sie mit aktivierter Widerrufsoption, wann immer Ihre Absicht ist, den Zugriff zu kappen.
Das ist der Teil, den RefundHalt für Sie übernimmt. Es verarbeitet die Echtzeitbenachrichtigungen, gleicht jede Ungültigmachung gegen die API ab, widerruft die genaue Bestellung statt des gesamten Produkts und trennt eine Bankrückbuchung von einer gewöhnlichen Erstattung, damit die teuren markiert und nicht begraben werden. Sie erhalten in Sekunden entzogenen Zugriff und eine Aufzeichnung darüber, wer was und warum ungültig gemacht hat, ohne selbst eine Pub/Sub-Pipeline und einen Abfrage-Job aufzusetzen.
Häufig gestellte Fragen
- Warum erscheinen meine erstatteten Bestellungen nicht in der Voided Purchases API?
- Weil nur widerrufene Bestellungen zurückgegeben werden. Nutzererstattungen, Stornierungen, Rückbuchungen und von Google ausgelöste Erstattungen werden immer widerrufen und erscheinen immer. Eine vom Entwickler ausgelöste Erstattung erscheint nur, wenn Sie auch die Widerrufsoption gewählt haben. Wenn Sie eine Bestellung erstattet haben, ohne sie zu widerrufen, ist die Bestellung erledigt, aber für diese API unsichtbar, also erstatten Sie mit aktiviertem Widerruf, wann immer Sie den Zugriff entziehen wollen.
- Wie weit reicht die Voided Purchases API zurück?
- Dreißig Tage. Der Parameter startTime hat als Voreinstellung die aktuelle Zeit minus 30 Tage und kann nicht älter als das gesetzt werden, der Endpunkt ist also ein rollierendes Ein-Monats-Fenster statt eines Archivs. Eine ungültig gemachte Bestellung, die über 30 Tage hinaus altert, ist aus der API verschwunden, ohne dass es eine Möglichkeit gibt, sie abzurufen, weshalb Sie nach einem Zeitplan abfragen und es mit Echtzeitbenachrichtigungen absichern.
- Sollte ich Real-time developer notifications oder die Voided Purchases API verwenden, um den Zugriff zu entziehen?
- Verwenden Sie beide. Die VoidedPurchaseNotification trifft innerhalb von Sekunden ein und sagt Ihnen, dass Sie hinschauen sollen, aber Googles eigene Empfehlung ist, sie als Signal zu behandeln, nicht als Quelle der Wahrheit. Rufen Sie die Voided Purchases API auf, um den aktuellen Zustand zu bestätigen, und widerrufen Sie dann. Die Benachrichtigung beseitigt die Verzögerung, und die API gibt Ihnen die maßgeblichen voidedSource und voidedReason, auf die Sie reagieren können.
- Wie unterscheide ich in der API eine Rückbuchung von einer gewöhnlichen Erstattung?
- Lesen Sie das Feld voidedReason. Ein Wert von 7 ist eine Rückbuchung, was bedeutet, dass die Bank des Kunden die Zahlung rückgängig gemacht hat, und 6 ist Friendly Fraud. Ein Wert von 1 ist eine Reue-Erstattung. Das ist wichtig, weil Google ab dem 3. August 2026 den Kaufpreis der Rückbuchung und die Bankgebühr an den Entwickler weitergibt, ein voidedReason von 7 kostet Sie also mehr als eine schlichte Erstattung.
- Deckt die Voided Purchases API Abos ab?
- Ja. Setzen Sie den Parameter type auf 1, um sowohl ungültig gemachte In-App-Käufe als auch ungültig gemachte Abo-Käufe zu erhalten. Die Voreinstellung, type 0, gibt nur Käufe von In-App-Produkten zurück. Bei Abos identifizieren Sie den genauen ungültig gemachten Zeitraum über orderId, weil ein purchaseToken jede Verlängerung abdeckt und für jede Verlängerungstransaktion eine neue orderId erzeugt wird.
Quellen und weiterführende Informationen
- Google Play Developer API: Voided Purchases API guide
- Google Play Developer API: purchases.voidedpurchases.list method
- Google Play Developer API: purchases.voidedpurchases resource (voidedSource and voidedReason)
- Android Developers: Real-time developer notifications reference (VoidedPurchaseNotification)
- Android Developers: Fight fraud and abuse with Play Billing
RefundHalt
Der Rückerstattungs-Autopilot für App Store und Google Play
Weiterlesen
Drei App Store Rückerstattungs-Benachrichtigungen treffen ein, nachdem Apple entschieden hat, und REFUND_REVERSED gibt den Verkauf zurück
Apple sendet vier Rückerstattungs-Nachrichten über App Store Server Notifications V2, und die meisten Apps verarbeiten nur zwei. REFUND weist dich an zu widerrufen, REFUND_DECLINED bedeutet den Verkauf zu behalten, und REFUND_REVERSED gibt den Verkauf zurück und bittet dich, wiederherzustellen, was du entzogen hast. Hier steht, was jede einzelne erfordert.
Jede Apple-Rückerstattungsanfrage kommt jetzt mit einem Grund, und consumptionRequestReason ist die Art, ihn zu lesen
Seit WWDC24 trägt jede Apple CONSUMPTION_REQUEST einen consumptionRequestReason, den vom Kunden selbst angegebenen Grund für die gewünschte Rückerstattung. Es gibt fünf Werte, von UNINTENDED_PURCHASE bis LEGAL, und jeder sollte verändern, was Sie innerhalb Ihres 12-Stunden-Fensters zurücksenden. So lesen Sie jeden einzelnen.