Alle Artikel
Deep dive7 Min. Lesezeit

Hänge an jeden App-Store-Kauf einen appAccountToken, sonst kannst du die Rückerstattung nicht abwehren

Apple schickt deinem Server einen CONSUMPTION_REQUEST, wenn ein Kunde eine Rückerstattung verlangt, aber die Transaktion sagt nie, wer das ist. appAccountToken ist die UUID, die einen Kauf mit deinem Nutzer verknüpft. Setze ihn, und du kannst Apple mit echten Daten antworten. Lass ihn weg, und du rätst.

Ein nummerierter Messingschlüssel liegt auf einem dunklen Kontobuch neben einem Smartphone, das eine Kaufquittung zeigt, und veranschaulicht, wie ein appAccountToken einen App-Store-Kauf mit einem Nutzerkonto verknüpft

Wichtigste Erkenntnisse

  • appAccountToken ist eine UUID, die du an einen App-Store-Kauf hängst, damit die entstehende Transaktion auf genau den Nutzer in deinem eigenen System zurückweist. Apple speichert sie auf der Transaktion und gibt sie überall zurück, wo diese Transaktion auftaucht.
  • Die einzige Formatregel, die Apple durchsetzt, ist, dass der Wert eine gültige UUID ist. Übergibst du etwas anderes, eine ID, eine E-Mail, eine zusammengesetzte Zeichenkette, verwirft StoreKit sie stillschweigend und gibt appAccountToken als nil zurück.
  • In StoreKit 2 setzt du sie mit einer einzigen Kaufoption, Product.PurchaseOption.appAccountToken(_:), und verwendest dabei eine stabile UUID, die du für dieses Konto erzeugt und gespeichert hast.
  • Setze sie einmal beim ursprünglichen Kauf, und Apple trägt denselben Token über jede Verlängerung, jeden Abbuchungsversuch und jedes Upgrade in der Abo-Kette weiter.
  • Seit 2025 erlaubt der Endpunkt Set App Account Token deinem Server, einen Token an Käufe außerhalb deiner App zu hängen, etwa Einlösungen von Angebotscodes und beworbene Käufe, die der In-App-Ablauf nie erreichen konnte.
  • appAccountToken macht Apples CONSUMPTION_REQUEST beantwortbar. Ohne ihn kannst du die Rückerstattung nicht dem Kunden zuordnen, dessen Nutzung du innerhalb des 12-Stunden-Fensters beschreiben sollst.
  • Eine Rückerstattung, die du nicht identifizieren kannst, ist eine Rückerstattung, die du nicht abwehren kannst. Du gibst Geld für Käufe zurück, für die du Beweise zum Behalten hattest, dazu die Rechenleistung, API-Aufrufe und Auszahlungen, die du für ihre Lieferung schon ausgegeben hast.

Ein Kunde verlangt von Apple eine Rückerstattung, Apple schickt deinem Server einen CONSUMPTION_REQUEST, und du hast zwölf Stunden, um mit echten Daten darüber zu antworten, wie diese Person das Produkt genutzt hat. Dann öffnest du die Benachrichtigung und merkst, dass du keine Ahnung hast, wer das ist. Die Transaktion trägt eine originalTransactionId und eine Produkt-ID, aber nichts, das auf das Konto in deiner eigenen Datenbank zeigt. Genau diese Lücke schließt appAccountToken, und wenn du ihn zum Kaufzeitpunkt nicht gesetzt hast, kannst du sie für diesen Verkauf im Nachhinein nicht mehr schließen.

appAccountToken ist eine UUID, die du an einen Kauf hängst, damit die entstehende App-Store-Transaktion einen Verweis auf genau den Nutzer in deinem System trägt. Setze ihn, und jede Rückerstattungsfrage, die Apple je zu diesem Kunden stellt, kommt mit dessen Identität an. Lass ihn weg, und du rätst. Hier steht, was das Feld ist, wie du es setzt, welcher neue Endpunkt Käufe außerhalb deiner App rettet und was die fehlende Verknüpfung wirklich kostet, wenn eine Rückerstattung eintrifft.

Was appAccountToken wirklich ist

appAccountToken ist eine undurchsichtige UUID, die du erzeugst und im Moment des Kaufs an StoreKit übergibst. Apple speichert sie auf der Transaktion und gibt sie in den Transaktionsinformationen für diesen Kauf zurück, und sie bleibt dort. In Apples Worten ist es "die UUID, die die Transaktion mit dem Konto des Nutzers in deinem eigenen Dienst verknüpft." Die einzige Formatregel ist, dass es eine UUID sein muss. Apple liest sie nicht, prüft nicht, worauf sie verweist, und interessiert sich nicht dafür, was sie auf deiner Seite bedeutet. Es ist eine Verknüpfung, die du kontrollierst.

Weil sie auf der Transaktion liegt, kommt sie überall dort zurück, wo die Transaktion zurückkommt. Die signierte Transaktion in einer Server-Benachrichtigung, die Antwort von Get Transaction Info der App Store Server API und jede Verlängerung in einer Abo-Kette tragen alle denselben Token, wenn du ihn beim ursprünglichen Kauf gesetzt hast. Eine UUID, einmal angehängt, folgt der Abrechnung des Kunden über die gesamte Dauer der Beziehung.

Es muss eine echte UUID sein, sonst verschwindet sie stillschweigend

Die eine Regel, die Apple durchsetzt, ist das Format. StoreKit 2 verlangt eine RFC 4122 UUID. Übergibst du eine zusammengesetzte Zeichenkette, eine Ganzzahl-ID oder eine E-Mail-Adresse, wirft StoreKit keinen Fehler. Es verwirft den Wert und die Transaktion kommt mit appAccountToken auf nil gesetzt zurück. Entwickler stolpern ständig darüber, und das Symptom ist immer dasselbe, irgendeine Variante von "appAccountToken is missing in the transaction payload" in Apples eigenen Foren, fast immer, weil der übergebene Wert keine gültige UUID war. Erzeuge serverseitig eine echte UUID, speichere sie zum Konto und übergib StoreKit niemals etwas anderes.

Wie du ihn zum Kaufzeitpunkt setzt

In StoreKit 2 ist es eine einzige Kaufoption. Erzeuge die UUID auf deinem Server, wenn der Nutzer sich anmeldet oder zum ersten Mal zur Kasse gelangt, speichere sie im Kontodatensatz und übergib denselben Wert an den Kaufaufruf.

Die Signatur lautet Product.PurchaseOption.appAccountToken(_ token: UUID), und ein Kauf sieht aus wie try await product.purchase(options: [.appAccountToken(token)]). Wenn die Transaktion zurückkommt, über die App Store Server API verifiziert oder per Server-Benachrichtigung geliefert, trägt sie diese UUID, und dein Server findet den Kunden mit einer einzigen Abfrage.

Verwende einen stabilen Token pro Konto

Erzeuge nicht für jeden Kauf desselben Nutzers einen frischen Token. Apple gibt den Token bei Verlängerungen, Abbuchungsversuchen und Upgrades in derselben Kette zurück, sodass eine stabile UUID pro Konto dir einen sauberen Faden vom ersten Kauf durch jedes künftige Ereignis gibt. Ein Token, der sich pro Kauf ändert, reißt diesen Faden und untergräbt den ganzen Zweck. Ein Konto, ein Token, jedes Mal wiederverwendet, wenn dieses Konto kauft.

Der Endpunkt, der Käufe außerhalb der App rettet

Bis 2025 gab es ein Loch. Wenn ein Kunde einen Angebotscode einlöste oder einen beworbenen In-App-Kauf direkt aus dem App Store tätigte, lief in deiner App nie der Kaufablauf, also gab es nirgends, wo appAccountToken zu setzen war. Diese Transaktionen kamen anonym an und blieben es.

WWDC 2025 schloss die Lücke mit dem Endpunkt Set App Account Token. Dein Server ruft PUT /inApps/v1/transactions/{originalTransactionId}/appAccountToken auf der App Store Server API mit der UUID im Body auf, und Apple setzt den Token auf dieser Transaktion. Es funktioniert für jeden Produkttyp, deckt Einlösungen von Angebotscodes und beworbene Käufe ab, und der Wert, den du sendest, überschreibt jeden bereits auf der Transaktion vorhandenen Token. Du kannst einen Kauf jetzt im Nachhinein von deinem Server aus zuordnen, ohne dass er je durch deine App läuft.

Ein Stapel Papierquittungen auf einem dunklen Schreibtisch, bei denen die Zeile für den Kundennamen leer geblieben ist, eine von einem warmen Spotlight beleuchtet, veranschaulicht einen App-Store-Kauf, der ohne appAccountToken ankommt, um den Käufer zu identifizieren
KaufkanalWo du appAccountToken setztHinweise
In-App-KaufStoreKit-Kaufoption zum KaufzeitpunktProduct.PurchaseOption.appAccountToken(UUID)
Einlösung eines AngebotscodesSet App Account Token Endpunkt, serverseitigKein In-App-Ablauf zum Einhaken, also nachträglich setzen
Beworbener In-App-Kauf aus dem App StoreSet App Account Token Endpunkt, serverseitigDer Kauf passiert außerhalb deiner App
Abo-VerlängerungNichts zu tunWird automatisch vom ursprünglichen Kauf übernommen

Wo dich die fehlende Verknüpfung Geld kostet

Der Sinn des Tokens sind nicht ordentliche Aufzeichnungen. Er ist, dass Apples eine Rückerstattungsfrage an Entwickler, der CONSUMPTION_REQUEST, nur beantwortbar ist, wenn du den Kunden findest, um den es geht.

Wenn ein Käufer eine Rückerstattung für ein Verbrauchsprodukt oder ein nicht erneuerbares Abo verlangt, schickt Apple deinem Server eine CONSUMPTION_REQUEST-Benachrichtigung und gibt dir zwölf Stunden, um mit Send Consumption Information zu antworten. Deine Antwort sind Daten über genau diesen Kunden: wie viel des Produkts er verbraucht hat, wie lange sein Konto besteht, wie hoch seine Gesamtausgaben sind, wie sein Lieferstatus ist. appAccountToken ist selbst eines der Felder in dieser Anfrage, und wichtiger noch, es ist die Art und Weise, wie die Transaktion der Benachrichtigung dem Konto zugeordnet wird, dessen Nutzung du gleich beschreiben wirst. Kein Token, keine Zuordnung, keine korrekte Antwort.

Was eine leere Antwort wirklich kostet

Eine nicht identifizierte Rückerstattung erzwingt eine schlechte Wahl. Du kannst die Verbrauchsanfrage mit nichts beantworten, was als geringer Verbrauch gelesen wird und Apple in Richtung Gewährung der Rückerstattung drängt, auch bei Kunden, die das Produkt intensiv genutzt haben. Oder du rätst. So oder so erstattest du Käufe, für die du die Beweise zur Abwehr hattest, und du hast die echten Kosten ihrer Bereitstellung bereits bezahlt.

Diese Kosten sind nicht der Verkaufspreis. Ein Verbrauchsprodukt, das eine Reihe von Modell-API-Aufrufen ausführte, Bilder generierte, ein Video exportierte oder eine Creator-Auszahlung auslöste, gab echtes Geld aus, sobald es geliefert wurde. Die Rückerstattung gibt die Zahlung des Kunden zurück. Sie gibt nicht die Rechnung des Anbieters zurück. Multipliziere einen nicht identifizierbaren Kunden mit jeder Rückerstattung, die er einreicht, und mit jedem Serien-Rückerstatter, der darauf zählt, dass du nicht weißt, wer er ist, und der Token, den du weggelassen hast, wird zur teuersten Codezeile, die du nie geschrieben hast.

Dieselbe Idee gibt es unter Android, unter anderem Namen

Google Play löst das identische Problem mit setObfuscatedAccountId, das eine Kontokennung an einen Kauf hängt, damit Googles Rückbuchungsprüfung über orders.reviewrefund gegen einen echten Nutzer beantwortet werden kann. Anderer Store, andere Mechanik, dieselbe Lektion: Hänge die Identität zum Kaufzeitpunkt an, sonst kannst du den Streitfall später nicht abwehren. Im App Store ist dieses Werkzeug appAccountToken, und es muss eine UUID sein.

Drei Gewohnheiten, die den Token an Ort und Stelle halten

  • Erzeuge eine UUID pro Konto und speichere sie. Ein stabiler Token pro Kunde, erstellt bei der Anmeldung oder beim ersten Bezahlvorgang, im Datensatz gespeichert und für jeden Kauf wiederverwendet.
  • Validiere, bevor du ihn übergibst. Bestätige in deinem Kaufcode, dass der Wert eine echte UUID ist, damit eine fehlerhafte ID niemals stillschweigend zu einem nil-Token auf der Transaktion werden kann.
  • Fülle Käufe außerhalb der App nach. Wenn eine Server-Benachrichtigung für eine Einlösung eines Angebotscodes oder einen beworbenen Kauf ohne Token eintrifft, rufe den Endpunkt Set App Account Token auf, um den richtigen anzuhängen.

Tu diese drei Dinge, und jede Transaktion, die Apple dir je schickt, Rückerstattungsanfragen inbegriffen, kommt bereits mit dem Kunden verknüpft an, zu dem sie gehört.

Das ist die Grundlage, auf die sich RefundHalt stützt. Wir lesen appAccountToken von jeder Transaktion und Server-Benachrichtigung ab, verknüpfen ihn mit der Nutzung, die wir für dieses Konto ohnehin verfolgen, und beantworten Apples Verbrauchsanfrage innerhalb des Zwölf-Stunden-Fensters mit den echten Zahlen des Kunden. Der Token ist der Faden. Setze ihn einmal, und deine Rückerstattungsabwehr hat etwas, woran sie sich festhalten kann.

Häufig gestellte Fragen

Was ist appAccountToken im App Store?
appAccountToken ist eine UUID, die du erzeugst und über StoreKit an einen Kauf hängst, damit die entstehende App-Store-Transaktion auf ein bestimmtes Nutzerkonto in deinem eigenen System zurückweist. Apple speichert sie auf der Transaktion und gibt sie in den Transaktionsinformationen, den Server-Benachrichtigungen und jeder Verlängerung in derselben Kette zurück, wodurch du jedes künftige Ereignis, eine Rückerstattungsanfrage inbegriffen, mit dem richtigen Kunden verbinden kannst.
Warum ist mein appAccountToken nil oder fehlt?
Fast immer, weil der übergebene Wert keine gültige UUID war. StoreKit 2 verlangt eine RFC 4122 UUID und verwirft alles andere stillschweigend, sodass eine zusammengesetzte Zeichenkette, eine Ganzzahl-ID oder eine E-Mail als nil appAccountToken zurückkommt, während der Kauf trotzdem gelingt. Die andere häufige Ursache ist ein Kauf außerhalb deiner App, etwa eine Einlösung eines Angebotscodes, bei der kein In-App-Ablauf zum Setzen des Tokens lief.
Kann ich appAccountToken nach dem Kauf setzen, für Angebotscodes?
Ja, seit 2025. Der Endpunkt Set App Account Token auf der App Store Server API erlaubt deinem Server, den Token auf einer bestehenden Transaktion anzuhängen oder zu überschreiben, indem du PUT /inApps/v1/transactions/{originalTransactionId}/appAccountToken mit der UUID im Body aufrufst. Es funktioniert für jeden Produkttyp und ist für Käufe außerhalb deiner App gebaut, etwa Einlösungen von Angebotscodes und beworbene In-App-Käufe.
Muss appAccountToken eine UUID sein?
Ja. Die eine Formatregel, die Apple durchsetzt, ist, dass der Wert eine gültige UUID ist. Ansonsten ist er undurchsichtig, kann also auf jeden Kontoschlüssel verweisen, den du auf deiner Seite magst, aber wenn er keine UUID ist, speichert StoreKit ihn nicht und die Transaktion kommt mit appAccountToken auf nil gesetzt zurück.
Wie hilft appAccountToken bei Rückerstattungen?
Wenn ein Kunde eine Rückerstattung verlangt, schickt Apple einen CONSUMPTION_REQUEST und gibt dir zwölf Stunden, um mit Daten über genau diesen Käufer zu antworten. appAccountToken ist die Art und Weise, wie du die Transaktion der Benachrichtigung dem Konto zuordnest, dessen Nutzung du melden musst, und es ist eines der Felder in der Verbrauchsanfrage selbst. Ohne ihn kannst du nicht mit echter Nutzung antworten, also neigt Apple dazu, Rückerstattungen zu gewähren, die du mit Beweisen hättest anfechten können.
Sollte appAccountToken für jeden Kauf unterschiedlich sein?
Nein. Verwende eine stabile UUID pro Konto und nutze sie für jeden Kauf dieses Nutzers wieder. Apple trägt den Token über Verlängerungen und Upgrades in einer Abo-Kette weiter, sodass ein stabiler Token dir eine saubere Verknüpfung über die Zeit gibt. Ein Token, der sich pro Kauf ändert, reißt diese Verknüpfung und macht es schwerer, Transaktionen demselben Kunden zuzuordnen.

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.