Alle Artikel
Deep dive8 Min. Lesezeit

Zugriff nach einer Rückerstattung entziehen: Der Schritt, den Apple und Google nicht für Sie übernehmen

Apple und Google können eine Rückerstattung abschließen, während der Kunde den Kauf trotzdem behält. Hier steht genau, wann der Zugriff automatisch entzogen wird, wann Ihr Server es selbst tun muss, und welche Benachrichtigung fast keine Integration behandelt.

Ein Smartphone leuchtet nachts auf einem Schreibtisch und veranschaulicht den Moment, in dem der Zugriff auf einen erstatteten Kauf noch nicht entzogen ist

Wichtigste Erkenntnisse

  • Bei Google Play entzieht die Rückerstattung einer Bestellung dem Nutzer nicht von selbst den Zugriff. Der Zugriff wird nur entzogen, wenn in der Play Console "Remove entitlement" angehakt ist oder der API-Aufruf revoke=true übergibt, was nicht die Standardeinstellung ist.
  • Eine Rückerstattung ohne die Widerrufsoption taucht in der Voided Purchases API überhaupt nie auf. Ein Widerrufsprozess, der nur diesen Feed ausliest, übersieht jede einzelne dieser Bestellungen stillschweigend.
  • Apple kann eine Lizenz für Nicht-Verbrauchsgüter und Abonnements automatisch widerrufen, aber ein Verbrauchsgut gilt bereits im Moment des Verbrauchs als geliefert, weshalb StoreKit keinen Mechanismus zum Widerruf hat. Ihr Server muss das Guthaben selbst abziehen.
  • Apple kann seine eigene Rückerstattung auch wieder rückgängig machen. Eine REFUND_REVERSED-Benachrichtigung bedeutet, dass eine zuvor gewährte Rückerstattung zurückgenommen wurde, revocationDate wieder auf null steht und jeder entzogene Zugriff oder jedes abgezogene Guthaben wiederhergestellt werden muss.
  • Das voidedReason-Feld von Google kennt neun Werte, von remorse und accidental_purchase bis fraud, friendly_fraud und unacknowledged_purchase, sodass derselbe Feed, der Ihnen sagt, wann Zugriff zu entziehen ist, auch anzeigt, welche Widerrufe Missbrauch sind und welche ein Fehler in Ihrer eigenen Integration.
  • Jeder Tag, an dem ein erstatteter Kauf seinen Zugriff behält, ist ein Tag, an dem Sie für die dahinterstehende Rechenleistung, den Speicher und die API-Aufrufe mit Geld bezahlen, das Sie bereits zurückgegeben haben.

Eine Rückerstattung zu genehmigen und den Zugriff zu entziehen sind zwei getrennte Schritte, und nur einer davon geschieht automatisch. Entwickler, die annehmen, eine bearbeitete Rückerstattung entspreche einem widerrufenen Kauf, liegen bei beiden großen Stores falsch, auf unterschiedliche Weise und aus unterschiedlichen Gründen. Genau zu wissen, wo die Automatisierung aufhört, ist nötig, um den Zugriff nach einer Rückerstattung zu entziehen, statt Monate später festzustellen, dass es nie geschehen ist.

Warum eine Rückerstattung den Zugriff nicht standardmäßig entzieht

Apple und Google behandeln Geld und Zugriff beide als zwei getrennte Vorgänge. Die Geldseite ist Store-Richtlinie: Sobald eine Rückerstattung genehmigt ist, ist sie endgültig und das Kontobuch wird aktualisiert. Die Zugriffsseite ist optional, oder Aufgabe des Entwicklers, oder beides, je nach Plattform und Kaufart. Keiner der beiden Stores geht davon aus, dass Sie den Zugriff in dem Moment entzogen haben wollen, in dem die Rückerstattung abgeschlossen ist, denn viele legitime Fälle (eine Teilrückerstattung, eine Kulanzgutschrift, eine Support-Geste) sollen das Produkt gar nicht wegnehmen.

Google Play: das Kästchen, das niemand bemerkt

In der Play Console ist die Rückerstattung einer Bestellung ein zweiteiliges Formular: den Rückerstattungsbetrag wählen und dann getrennt entscheiden, ob "Remove entitlement" angehakt wird. Das Kästchen leer zu lassen ist der Standardweg, den die meisten Support-Mitarbeiter wählen, weil die meisten Rückerstattungsanfragen Kulanzgesten sind, bei denen der Kunde behält, was er gekauft hat. Das Problem ist, dass nichts auf dem Bestätigungsbildschirm der Rückerstattung darauf hinweist, dass ein Kunde auf genau diesem Weg auch ein Abonnement oder einen In-App-Artikel nach einer Rückerstattung behält, die eigentlich endgültig sein sollte.

Der API-Weg hat dieselbe Falle

Dieselbe Wahl gibt es auch im Code. Der Endpunkt orders.refund akzeptiert einen optionalen Abfrageparameter revoke; steht er auf true, wird der Zugriff auf den Artikel sofort beendet, und bei einem wiederkehrenden Abonnement wird damit jede zukünftige Zahlung storniert. Lässt man den Parameter weg, wird er standardmäßig false: Die Rückerstattung wird gebucht, der Kaufdatensatz aktualisiert, und der Nutzer verwendet das Produkt genau wie zuvor weiter.

AktionZugriff entzogen?Erscheint in der Voided Purchases API?
Rückerstattung in der Play Console, "Remove entitlement" nicht angehaktNeinNein
Rückerstattung in der Play Console, "Remove entitlement" angehaktJa, sofortJa
orders.refund API, Parameter revoke weggelassen (Standard false)NeinNein
orders.refund API, revoke=trueJa, sofortJa

Diese letzte Zeile ist es, die Integrationen zum Verhängnis wird. Die Voided Purchases API existiert, damit Sie eine Widerrufspipeline bauen können, ohne die Play Console manuell abzufragen, aber sie listet nur Bestellungen, die tatsächlich mit Widerruf annulliert wurden. Eine Rückerstattung, die ohne das Kästchen oder ohne revoke=true bearbeitet wurde, ist für diesen Feed absichtlich unsichtbar, nicht aufgrund eines Fehlers.

Ein Serverschrank mit einem einzigen roten Statuslicht zwischen Reihen grüner Lichter, das eine stille Widerrufsentscheidung darstellt

Das voidedReason-Feld lesen Wenn ein Kauf tatsächlich als annulliert angezeigt wird, nennt das Feld voidedReason den Grund, auf einer Skala von neun Werten: other, remorse, not_received, defective, accidental_purchase, fraud, friendly_fraud, chargeback und unacknowledged_purchase. Das ist nicht nur Buchhaltung. Remorse und accidental_purchase sind gewöhnliche Rückerstattungen. Fraud, friendly_fraud und chargeback sollten eher in eine Betrugsprüfungs-Warteschlange geleitet werden als über einen einfachen Widerruf-und-vergessen-Pfad, weil derselbe Account statistisch mit höherer Wahrscheinlichkeit erneut auffällt.

Ein betrieblicher Punkt ist wichtig, wenn Sie direkt gegen diesen Feed entwickeln: purchases.voidedpurchases.list ist auf 6.000 Abfragen pro Tag und 30 Abfragen in jedem 30-Sekunden-Fenster begrenzt. Ein Design, das in einer engen Schleife abfragt, stößt schnell an diese Grenze; das vorgesehene Muster ist ein geplanter Abruf mit Paginierungs-Tokens, kein kontinuierliches Polling.

Apple: Der App Store kann eine Lizenz widerrufen, aber kein Verbrauchsgut

Apples App Store Server Notifications V2 senden eine REFUND-Benachrichtigung in dem Moment, in dem eine Rückerstattung abgeschlossen wird, gleichermaßen für Verbrauchsgüter, Nicht-Verbrauchsgüter, automatisch verlängerbare Abonnements und nicht verlängerbare Abonnements. Was nach dieser Benachrichtigung geschieht, hängt vollständig von der Kaufart ab, denn der eigene Widerrufsmechanismus von StoreKit deckt nur zwei der vier Arten ab.

Warum Verbrauchsgüter die Ausnahme sind

Ein Nicht-Verbrauchsgut oder ein Abonnement hat einen dauerhaften Anspruch, den Apples Systeme abschalten können. Ein Verbrauchsgut hat das nicht: Sobald es genutzt ist, gilt es als geliefert, und in StoreKit bleibt nichts mehr übrig, das widerrufen werden könnte. Hat ein Kunde 500 Münzen gekauft, sie ausgegeben und eine Rückerstattung erhalten, sind die Münzen aus Apples Sicht bereits verschwunden. Das einzige Kontobuch, das sie noch führt, ist Ihres. Die REFUND-Benachrichtigung ist Ihr einziges Signal, die passende ursprüngliche Transaktions-ID zu finden und dieses Guthaben von Ihren eigenen Aufzeichnungen abzuziehen; nichts auf Apples Seite erledigt das für Sie.

BenachrichtigungWas sie bedeutetWas Ihr Server tun muss
REFUNDApple hat einen Verbrauchsgut-, Nicht-Verbrauchsgut-, automatisch verlängerbaren oder nicht verlängerbaren Kauf erstattetZugriff auf Nicht-Verbrauchsgüter und Abonnements sofort entziehen; das Guthaben des Verbrauchsguts selbst abziehen
REFUND_DECLINEDApple hat die Rückerstattungsanfrage eines Kunden abgelehntNichts. Der Zugriff war nie gefährdet
REFUND_REVERSEDApple hat eine bereits gewährte Rückerstattung rückgängig gemachtWiederherstellen, was an Zugriff oder Guthaben die REFUND-Benachrichtigung Sie entfernen ließ
CONSUMPTION_REQUESTApple möchte Ihre Nachweise, bevor über eine Rückerstattung entschieden wirdInnerhalb von 12 Stunden antworten; dies löst vor einem REFUND aus, nicht danach

Die Benachrichtigung, die fast niemand behandelt

REFUND_REVERSED ist diejenige, die die meisten Integrationen komplett übergehen, weil sie beschreibt, wie Apple seine eigene Entscheidung rückgängig macht, ein Fall, den nur wenige Entwickler beim ersten Entwurf einplanen. Trifft sie ein, springt revocationDate bei der Transaktion wieder auf null: Aus Apples Sicht ist der Kauf wieder gültig. Hat Ihr Server bei Eingang des ursprünglichen REFUND einen Zugriffsanspruch gelöscht, einen Abonnementeintrag storniert oder ein Verbrauchsgut-Guthaben auf null gesetzt, ist REFUND_REVERSED das Signal, all das rückgängig zu machen.

Wie man die Lücke schließt, Schritt für Schritt

  • Setzen Sie bei Google Play jeden Rückerstattungsweg standardmäßig auf revoke=true, ob über die Play Console oder die API, außer ein konkreter Supportfall verlangt, dass der Kunde den Zugriff behält.
  • Fragen Sie purchases.voidedpurchases.list nach einem Zeitplan mit Paginierungs-Tokens ab, nicht in einer engen Schleife, und bleiben Sie unter 6.000 Anfragen pro Tag und 30 pro 30 Sekunden.
  • Leiten Sie voidedReason-Werte wie fraud, friendly_fraud und chargeback in eine Prüf-Warteschlange statt in einen automatischen Widerruf-und-Abschluss-Pfad.
  • Abonnieren Sie bei Apple die App Store Server Notifications V2 und entziehen Sie den Zugriff auf Nicht-Verbrauchsgüter und Abonnements in dem Moment, in dem eine REFUND-Benachrichtigung sie nennt.
  • Speichern Sie die ursprüngliche Transaktions-ID zu jedem Verbrauchsgut-Kauf, damit eine REFUND-Benachrichtigung das genaue abzuziehende Guthaben ohne manuelle Suche finden kann.
  • Behandeln Sie REFUND_REVERSED explizit und protokollieren Sie jeden Widerruf mit Bezug zu seiner Transaktions- oder Bestell-ID, damit eine Rücknahme genau das wiederherstellen kann, was entfernt wurde.

Was die Lücke tatsächlich kostet

Bei alldem geht es nicht um Fairness gegenüber dem Kunden; es geht darum, was weiterläuft, nachdem das Geld schon weg ist. Ein erstattetes Abonnement, das weiterhin Ihre API aufruft, Daten speichert und Rechenleistung verbraucht, ist kein moralisches Problem, sondern ein Kostenpunkt: Sie zahlen die Infrastrukturrechnung für einen Kauf, dessen Erlös Sie bereits zurückgegeben haben. Die Stores verfolgen diese Kosten nicht für Sie, denn aus ihrer Sicht ist die Rückerstattung in dem Moment abgeschlossen, in dem das Geld sich bewegt. Die Zugriffsseite geht vollständig zu Ihren Lasten.

Aus genau diesem Grund behandelt RefundHalt den Widerruf als Teil der Rückerstattungspipeline und nicht als nachträglichen Gedanken: Ein REFUND-Ereignis und eine Zugriffsänderung werden als eine einzige Aktion erfasst, und ein REFUND_REVERSED-Ereignis stellt den Zustand automatisch wieder her, statt darauf zu warten, dass jemand bemerkt, dass der Kunde noch von etwas ausgesperrt ist, das Apple ihm bereits zurückgegeben hat.

Häufig gestellte Fragen

Entzieht eine Rückerstattung eines Kaufs bei Google Play automatisch den Zugriff?
Nein. Der Zugriff wird nur entzogen, wenn in der Play Console "Remove entitlement" angehakt ist oder der Aufruf der orders.refund-API revoke=true enthält. Keines von beiden ist die Standardeinstellung, sodass eine Rückerstattung gebucht werden kann, während der Kunde das Produkt weiter nutzt.
Was passiert, wenn ein Verbrauchsgut als In-App-Kauf im App Store erstattet wird?
Apple sendet eine REFUND-Benachrichtigung, aber StoreKit hat keine Möglichkeit, ein Verbrauchsgut zu widerrufen, weil es nach dem Verbrauch als geliefert gilt. Der Server des Entwicklers muss die ursprüngliche Transaktion finden und das Guthaben manuell abziehen.
Was ist die REFUND_REVERSED-Benachrichtigung und braucht sie eine besondere Behandlung?
REFUND_REVERSED bedeutet, dass Apple eine bereits gewährte Rückerstattung rückgängig gemacht hat; revocationDate springt zurück auf null und der Kauf ist wieder gültig. Jeder Zugriff oder jedes Guthaben, das die ursprüngliche REFUND-Benachrichtigung entfernt hat, muss wiederhergestellt werden, und die meisten Integrationen hören auf diese Benachrichtigung überhaupt nie.
Warum könnte eine erstattete Google-Play-Bestellung nicht in der Voided Purchases API erscheinen?
Die API listet nur Bestellungen, die mit Widerruf annulliert wurden. Wurde eine Rückerstattung ohne die Widerrufsoption bearbeitet, wird die Bestellung von diesem Endpunkt überhaupt nicht zurückgegeben, sodass eine Pipeline, die sich allein darauf verlässt, diese Rückerstattungen vollständig übersieht.
Wie oft kann ich die Voided Purchases API von Google abfragen?
Der Endpunkt ist auf 6.000 Abfragen pro Tag und 30 Abfragen in jedem 30-Sekunden-Fenster begrenzt, er ist also für einen geplanten Abruf mit Paginierungs-Tokens gedacht, nicht für kontinuierliches Polling.

Quellen und weiterführende Informationen

RefundHalt

Der Rückerstattungs-Autopilot für App Store und Google Play

Weiterlesen

Die nächste Rückerstattungsanfrage ist bereits unterwegs.

Richten Sie RefundHalt in der Zeit ein, die Sie brauchen, um eine weitere Support-E-Mail über eine Rückerstattung zu lesen, die Sie nicht anfechten konnten.