Die Erkennung von Erstattungen in StoreKit 2 hängt an einer einzigen Eigenschaft der Transaktion, und das ist revocationDate
Wenn Apple einen Ihrer Kunden erstattet, liegt die Erstattung bereits in Ihrer App auf der revocationDate der Transaktion, bevor Ihr Server-Job läuft. Hier erfahren Sie, wo die Erkennung von Erstattungen in StoreKit 2 auf dem Gerät erscheint, was revocationDate und revocationReason Ihnen sagen, und warum der Client für Geschwindigkeit da ist und der Server für die Wahrheit.

Wichtigste Erkenntnisse
- In StoreKit 2 trägt ein erstatteter Kauf ein revocationDate ungleich nil auf seiner Transaction, sodass Ihre App die Erstattung selbst erkennen kann, ohne Ihren Server aufzurufen.
- revocationDate wird gesetzt, wenn der App Store eine Transaktion erstattet oder wenn ein Kunde sie durch Family Sharing verliert, sodass ein Datum ungleich nil nicht immer eine Erstattung ist.
- revocationReason sagt Ihnen, warum: developerIssue bedeutet, dass der Kunde ein Problem in Ihrer App angegeben hat, und other deckt jeden übrigen Erstattungsgrund ab.
- Transaction.currentEntitlements schließt erstattete und widerrufene Käufe bereits aus, sodass die sauberste clientseitige Zugangsprüfung schlicht die Frage ist, ob ein Produkt dort noch erscheint.
- Transaction.updates liefert eine Erstattung, die geschah, während Ihre App geschlossen war, nur, wenn Sie beim Start mit dem Zuhören beginnen, sodass ein fehlender Task eine verpasste Erstattung bedeutet.
- Die clientseitige Erkennung greift nur, während die App geöffnet ist, weshalb App Store Server Notifications V2 REFUND das maßgebliche Signal bleibt, das Sie davor bewahrt, für die Bedienung eines erstatteten Nutzers zu zahlen.
- Eine Erstattung kann rückgängig gemacht werden, und wenn das geschieht, werden die Widerrufsfelder aus der Transaktion entfernt, und von Ihnen wird erwartet, dass Sie den Zugang wiederherstellen, den Sie gekappt haben.
Die meisten Apps erfahren von einer Apple-Erstattung über ihren Server, durch eine App Store Server Notification, und bemerken nie, dass dieselbe Erstattung bereits in der App liegt. Sie steht auf der Transaktion, in einer Eigenschaft namens revocationDate, und wenn Sie diese lesen, kann Ihre App den Zugang eines erstatteten Kunden beim nächsten Öffnen kappen, statt auf einen Backend-Job zu warten. Die Erkennung von Erstattungen in StoreKit 2 ist ein clientseitiges Signal, das die meisten Teams überspringen. Hier steht genau, wo eine Erstattung auf dem Gerät erscheint, was sie Ihnen sagt, was nicht, und warum sie neben Ihre Server-Benachrichtigungen gehört und nicht an deren Stelle.
Wo eine Erstattung in StoreKit 2 auftaucht
StoreKit 2 übergibt Ihnen Transaktionen als signierte Werte, und eine Erstattung löscht die Transaktion nicht. Sie markiert sie. Zwei Eigenschaften der Transaction tragen die Markierung, und beide bleiben nil für das gesamte Leben eines gesunden Kaufs. Wenn eine von ihnen ungleich nil wird, hat der App Store den Kauf zurückgenommen.
revocationDate ist das Feld, das umschlägt
revocationDate ist ein optionales Date. Apples eigene Beschreibung ist genau: Es ist das Datum, an dem der App Store die Transaktion erstattet oder sie aus Family Sharing widerrufen hat. Für einen Kauf, der noch gültig ist, ist es nil. In dem Moment, in dem eine Erstattung verarbeitet wird, hält es den Zeitstempel dieser Erstattung. Diese eine Prüfung, ist revocationDate ungleich nil, ist die gesamte clientseitige Erstattungserkennung. Alles andere ist Feinheit, die darauf aufsetzt.
revocationReason sagt Ihnen, warum Apple ihn zurückgezogen hat
revocationReason steht neben dem Datum und erklärt die Ursache. StoreKit gibt ihm zwei Werte, die für Erstattungen wichtig sind. developerIssue bedeutet, dass der Kunde Apple mitgeteilt hat, die Erstattung sei auf ein tatsächliches oder empfundenes Problem in Ihrer App zurückzuführen. other deckt jeden übrigen Grund ab. Ein dritter Wert, upgradedToBundle, ist überhaupt keine Erstattung; er kennzeichnet eine Transaktion, die der App Store widerrufen hat, weil der Kunde zu einem Abo-Bundle gewechselt ist. Lesen Sie den Grund, bevor Sie handeln, denn developerIssue ist der, den zu zählen sich lohnt: eine Häufung davon ist Ihr eigenes Produkt, das Ihnen sagt, wo es kaputtging.
| Eigenschaft | Typ | Was ein Wert ungleich nil bedeutet |
|---|---|---|
revocationDate | Date? | Der App Store hat diese Transaktion an diesem Datum erstattet oder sie durch Family Sharing widerrufen |
revocationReason ist developerIssue | Grund | Der Kunde hat ein tatsächliches oder empfundenes Problem in Ihrer App angeführt |
revocationReason ist other | Grund | Die Erstattung geschah aus einem anderen Grund, den Apple nicht einzeln aufführt |
revocationReason ist upgradedToBundle | Grund | Keine Erstattung; die Transaktion wurde widerrufen, weil der Kunde zu einem Abo-Bundle gewechselt ist |
currentEntitlements lässt einen erstatteten Kauf bereits fallen
Sie müssen die Widerrufsfelder nicht immer selbst lesen. Transaction.currentEntitlements ist die Folge der Käufe, zu denen ein Kunde gerade jetzt noch berechtigt ist, und Apple baut sie so, dass sie die auslässt, die Sie nicht anerkennen sollten. Ein Produkt, das der App Store erstattet oder widerrufen hat, erscheint darin nicht. Ebenso wenig abgelaufene Abos oder Verbrauchsartikel, die weg sind, sobald sie verbraucht sind.
Das macht currentEntitlements zur saubersten Zugangsprüfung. Fragen Sie es, was der Kunde besitzt, gewähren Sie genau das, und eine Erstattung entfernt die Berechtigung für Sie, ohne eine einzige revocationDate-Prüfung. Die Widerrufsfelder sind für den Fall, dass Sie das Detail wollen, das Datum und den Grund, um das Ereignis zu protokollieren oder darauf zu reagieren. Die Berechtigungsliste ist für die schlichte Frage, ob das Licht anbleibt.
Die Erkennung von Erstattungen in StoreKit 2 in der Praxis, beim Start und während die App läuft
Es gibt zwei Momente, in denen Ihre App eine Erstattung auf dem Gerät abfangen kann, und sie brauchen unterschiedlichen Code. Der eine ist, während die App geöffnet ist und eine Erstattung live oder auf einem anderen Gerät geschieht. Der andere ist beim Start, wenn alles nachgeholt wird, was sich änderte, während Sie geschlossen waren. Verpassen Sie den zweiten, und Ihre Erstattungserkennung in StoreKit 2 hat ein Loch genau dort, wo die meisten Erstattungen fallen, denn Kunden haben Ihre App selten offen, wenn sie eine beantragen.
Beginnen Sie beim Start mit dem Zuhören, sonst verpassen Sie die Erstattungen, die im geschlossenen Zustand geschahen
Transaction.updates ist die asynchrone Folge, die eine Transaktion ausgibt, wann immer das System eine außerhalb Ihrer App oder auf einem anderen Gerät erstellt oder aktualisiert, eine Erstattung eingeschlossen. Apples Anweisung ist unmissverständlich: Starten Sie einen Task, der sie durchläuft, sobald Ihre App startet, sonst verpassen Sie womöglich die Transaktionen, die sie nur einmal beim Start liefert. Eine Erstattung, die über Nacht eintraf, kommt beim nächsten Öffnen der App über updates, aber nur, wenn bereits ein Zuhörer läuft, um sie zu empfangen. Kein Zuhörer, kein Ereignis, und die Erstattung bleibt unsichtbar, bis etwas anderes sie abgleicht.
Ein Kauf auf demselben Gerät kommt nicht über updates
Eine Falle erwischt Leute, die Erstattungen von Hand testen. Ein normaler Kauf, der auf demselben Gerät getätigt wird, kommt nicht über updates; StoreKit gibt ihn direkt aus dem Ergebnis des Kaufaufrufs zurück. updates ist für die Änderungen außerhalb des regulären Wegs: Erstattungen, Ask-to-Buy-Freigaben, Einlösungen von Angebotscodes und anderswo getätigte Käufe. Bauen Sie Ihre Erstattungsbehandlung also um updates und currentEntitlements herum, nicht um den Kaufablauf, denn die Erstattung wird nie den Weg zurückgehen, den der Verkauf nahm.

Was die clientseitige Erkennung nicht für Sie tun kann
Erstattungen auf dem Gerät zu lesen ist schnell und kostenlos, aber es hat eine Grenze, und so zu tun, als gäbe es sie nicht, ist der Weg, auf dem Umsatz versickert. Das Gerät weiß nur, was StoreKit ihm gesagt hat, und StoreKit spricht nur, während Ihre App läuft. Ein Kunde, der eine Erstattung erhält und Ihre App nie wieder öffnet, ist ein Kunde, den Ihre clientseitige Prüfung nie sieht.
Ein revocationDate ist nicht immer eine Erstattung
Dasselbe Feld schlägt auch bei Family Sharing um. Wenn ein Kunde den Zugang zu einem geteilten Kauf verliert, weil der Organisator ihn entfernt hat oder die Freigabe endete, erhält diese Transaktion ebenfalls ein revocationDate. Ein Datum ungleich nil bedeutet also, dass der Kunde diesen Kauf nicht mehr hat, was genau das ist, was Sie für die Zugangssteuerung brauchen, aber es bedeutet nicht immer, dass Geld zurückgeflossen ist. Wenn Sie Erstattungen für den Umsatz zählen, trennen Sie die Family-Sharing-Widerrufe von den echten, bevor Sie der Zahl trauen.
Eine Erstattung kann rückgängig gemacht werden
Eine Erstattung ist nicht immer endgültig. Apple kann sie rückgängig machen, und wenn das geschieht, werden die Widerrufsfelder aus der Transaktion entfernt und der Kauf ist wieder gültig. Wenn Sie den Zugang bei der Erstattung gekappt haben, wird von Ihnen erwartet, dass Sie ihn bei der Rücknahme wiederherstellen. Auf dem Gerät zeigt sich das als weiteres updates-Ereignis mit einer sauberen Transaktion; auf Ihrem Server ist es eine eigene REFUND_REVERSED-Benachrichtigung. Behandeln Sie nur die Erstattung, dann lassen Sie einen zahlenden Kunden ohne Zugang und mit einer funktionierenden Quittung stranden.
Was ein später Widerruf tatsächlich kostet
Eine Erstattung ist selten nur der Verkaufspreis, der Ihr Konto verlässt. Wenn sie durchgeht, haben Sie meist bereits echtes Geld ausgegeben, um diesen Kauf zu bedienen, und diese Ausgabe kommt nicht zurück. Die generierten Bilder kosten GPU-Minuten. Die Chat-Antworten kosten Modell-API-Aufrufe, die Ihnen pro Token berechnet wurden. Die Uploads kosten Speicher, für dessen Vorhaltung Sie weiter zahlen. Wenn der Kauf eine Auszahlung an einen Creator finanziert hat, ist dieses Geld bereits raus. Nichts davon kehrt sich mit der Erstattung um.
Die clientseitige Erkennung verkleinert das Fenster bei dem einen Teil, den Sie noch steuern können, den künftigen Ausgaben. Je früher Sie wissen, dass ein Kauf erstattet ist, desto früher hören Sie auf, ihn zu bedienen. Aber das Gerät sagt es Ihnen nur, während die App geöffnet ist, sodass ein erstatteter Nutzer, der nie wiederkommt, jeden serverseitigen Zugang behält, den Sie gewährt haben, und Sie still jedes Mal Geld kostet, wenn ein Hintergrund-Job oder ein synchronisiertes Gerät in seinem Namen handelt. Der Client macht den Widerruf schnell. Er macht ihn nicht garantiert.
Nutzen Sie den Client für Geschwindigkeit und den Server für die Wahrheit
Das saubere Design nutzt beide Signale für das, worin sie jeweils gut sind. Auf dem Gerät geben Ihnen Transaction.updates und currentEntitlements eine sofortige, lokale Reaktion in dem Moment, in dem ein erstatteter Kunde die App öffnet, gut für die Oberfläche und um Berechtigungsänderungen ohne Rundlauf abzuschließen. Auf dem Server senden App Store Server Notifications V2 eine REFUND-Nachricht, die ankommt, egal ob die App je wieder geöffnet wird, und das ist das einzige Signal, das Ihr Backend zuverlässig davon abhält, für ein erstattetes Konto Geld auszugeben.
| Signal | Wo es lebt | Feuert, wenn | Vertrauen Sie darauf, dass es |
|---|---|---|---|
revocationDate auf einer Transaktion | Gerät, StoreKit 2 | Ihre App die Transaktion liest | Ihnen sagt, dass ein bestimmter Kauf erstattet oder widerrufen wurde |
Transaction.updates | Gerät, StoreKit 2 | Eine Erstattung eintrifft, während die App läuft, oder beim Start, wenn Sie zuhören | Sofort reagiert für einen Kunden, der anwesend ist |
currentEntitlements | Gerät, StoreKit 2 | Sie prüfen, was der Kunde jetzt besitzt | Den Zugang steuert, ohne dass Sie Erstattungen selbst nachverfolgen |
REFUND-Benachrichtigung | Ihr Server, App Store Server Notifications V2 | Apple die Erstattung verarbeitet, App offen oder nicht | Serverseitige Ausgaben für einen Kunden stoppt, der nie zurückkehrt |
Verdrahten Sie die Gerätesignale für den Kunden, der das Telefon in der Hand hält, und die Server-Benachrichtigung für den, der es nicht tut. Die Erstattung erscheint mit Absicht an beiden Stellen. Nur eines von beiden zu lesen ist der Weg, auf dem ein erstattetes Konto Sie weiter kostet, nachdem der Verkauf längst weg ist.
Häufig gestellte Fragen
- Wie erkenne ich eine Erstattung in StoreKit 2?
- Prüfen Sie das revocationDate der Transaktion. Es ist nil bei einem gültigen Kauf und hält ein Datum, sobald der App Store die Transaktion erstattet, sodass ein revocationDate ungleich nil das Signal ist, dass ein Kauf erstattet oder widerrufen wurde.
- Was ist der Unterschied zwischen revocationDate und revocationReason?
- revocationDate ist der Zeitpunkt, an dem der App Store den Kauf zurückgenommen hat, und revocationReason ist das Warum. Der Grund ist developerIssue, wenn der Kunde ein Problem in Ihrer App angeführt hat, und other für alles andere.
- Erscheint ein erstatteter Kauf noch in currentEntitlements?
- Nein. Transaction.currentEntitlements schließt Käufe aus, die der App Store erstattet oder widerrufen hat, sodass ein erstattetes Produkt von selbst aus den Berechtigungen des Kunden herausfällt, was es zu einer sicheren Zugangsprüfung macht.
- Sagt StoreKit meiner App von einer Erstattung, die geschah, während die App geschlossen war?
- Nur, wenn Sie ab dem Start zuhören. Transaction.updates liefert diese Änderungen einmal beim Start, sodass Sie einen Task starten müssen, der sie durchläuft, sobald Ihre App startet, sonst wird die Erstattung verpasst, bis etwas anderes sie abgleicht.
- Reicht die clientseitige Erstattungserkennung für sich allein?
- Nein. Das Gerät erfährt von einer Erstattung nur, während Ihre App läuft, sodass ein Kunde, der die App nie wieder öffnet, für es unsichtbar ist. App Store Server Notifications V2 REFUND ist das Signal, das Sie ungeachtet dessen erreicht.
- Bedeutet ein revocationDate immer, dass der Kunde erstattet wurde?
- Nein. revocationDate wird auch gesetzt, wenn ein Kunde einen Kauf durch Family Sharing verliert, sodass ein Datum ungleich nil bedeutet, dass er den Kauf nicht mehr hat, aber nicht immer, dass Geld zurückgegeben wurde.
Quellen und weiterführende Informationen
- Apple Developer: Transaction.revocationDate (StoreKit)
- Apple Developer: Transaction.RevocationReason (StoreKit)
- Apple Developer: Transaction.currentEntitlements (StoreKit)
- Apple Developer: Transaction.updates (StoreKit)
- Apple Developer: App Store Server Notifications V2 notificationType (REFUND, REFUND_REVERSED)
- Apple Developer Tech Talk: Support customers with StoreKit 2 and App Store Server API
RefundHalt
Der Rückerstattungs-Autopilot für App Store und Google Play
Weiterlesen
Jedes Erstattungsfenster im App Store und bei Google Play ist ein Countdown, und so viele Stunden gibt Ihnen jedes davon
Jede Erstattung im App Store und bei Google Play startet eine Uhr, und die meisten laufen ohne Sie. Apples kürzestes Erstattungsfenster liegt bei 12 Stunden, Googles Chargeback-Fenster bei 24, und ab dem 3. August 2026 ist ein verpasstes Chargeback-Fenster eine Rechnung, nicht nur ein verlorener Verkauf. Hier ist jede Frist, die Ihr Konto berührt.
Eine Benachrichtigung über einen stornierten Kauf lässt Ihren Google Play-Server den Zugriff in dem Moment entziehen, in dem eine Rückerstattung eintrifft
Google Play kann Ihrem Server in dem Moment eine Benachrichtigung über einen stornierten Kauf senden, in dem ein Kauf erstattet, zurückgebucht oder storniert wird. Sie trägt einen purchaseToken, eine orderId, einen productType und einen refundType und bedeutet eine Sache, den Zugriff zu entziehen. So lesen und verdrahten Sie sie.