Wszystkie artykuły
Deep dive7 min czytania

Dołącz appAccountToken do każdego zakupu w App Store, inaczej nie obronisz zwrotu

Apple wysyła na Twój serwer CONSUMPTION_REQUEST, gdy klient prosi o zwrot, ale transakcja nigdy nie mówi, kim on jest. appAccountToken to UUID, który łączy zakup z powrotem z Twoim użytkownikiem. Ustaw go, a odpowiesz Apple prawdziwymi danymi. Pomiń go, a będziesz zgadywać.

Numerowany mosiężny klucz leżący na ciemnej księdze obok smartfona pokazującego paragon zakupu, ilustrujący, jak appAccountToken łączy zakup w App Store z kontem użytkownika

Najważniejsze wnioski

  • appAccountToken to UUID, który dołączasz do zakupu w App Store, aby powstała transakcja wskazywała z powrotem na dokładnie tego użytkownika w Twoim własnym systemie. Apple przechowuje go w transakcji i zwraca wszędzie tam, gdzie ta transakcja się pojawia.
  • Jedyną regułą formatu, której Apple pilnuje, jest to, że wartość jest prawidłowym UUID. Przekaż cokolwiek innego, id, e-mail, sklejony ciąg znaków, a StoreKit po cichu go odrzuci i zwróci appAccountToken jako nil.
  • W StoreKit 2 ustawiasz go jedną opcją zakupu, Product.PurchaseOption.appAccountToken(_:), używając stabilnego UUID, który wygenerowałeś i zapisałeś dla tego konta.
  • Ustaw go raz przy pierwotnym zakupie, a Apple przenosi ten sam token przez każde odnowienie, każdą ponowną próbę obciążenia i każdą aktualizację w łańcuchu subskrypcji.
  • Od 2025 roku punkt końcowy Set App Account Token pozwala Twojemu serwerowi dołączyć token do zakupów dokonanych poza aplikacją, takich jak realizacja kodów promocyjnych i zakupy promowane, do których przepływ w aplikacji nigdy nie mógł dotrzeć.
  • appAccountToken sprawia, że CONSUMPTION_REQUEST od Apple da się odpowiedzieć. Bez niego nie możesz przypisać zwrotu do klienta, którego zużycie masz opisać w oknie 12 godzin.
  • Zwrot, którego nie potrafisz zidentyfikować, to zwrot, którego nie potrafisz obronić. Oddajesz pieniądze za zakupy, na których zatrzymanie miałeś dowody, plus moc obliczeniową, wywołania API i wypłaty, które już wydałeś na ich dostarczenie.

Klient prosi Apple o zwrot, Apple wysyła na Twój serwer CONSUMPTION_REQUEST, a Ty masz dwanaście godzin, aby odpowiedzieć prawdziwymi danymi o tym, jak ta osoba korzystała z produktu. Potem otwierasz powiadomienie i uświadamiasz sobie, że nie masz pojęcia, kim ona jest. Transakcja niesie originalTransactionId i id produktu, ale nic, co wskazywałoby na konto w Twojej własnej bazie danych. Dokładnie tę lukę zamyka appAccountToken, a jeśli nie ustawiłeś go w chwili zakupu, nie możesz jej zamknąć po fakcie dla tej sprzedaży.

appAccountToken to UUID, który dołączasz do zakupu, aby powstała transakcja w App Store niosła wskaźnik z powrotem do dokładnie tego użytkownika w Twoim systemie. Ustaw go, a każde pytanie o zwrot, jakie Apple kiedykolwiek zada w sprawie tego klienta, przychodzi z jego tożsamością. Pomiń go, a będziesz zgadywać. Oto czym jest to pole, jak je ustawić, jaki nowy punkt końcowy ratuje zakupy dokonane poza aplikacją i ile naprawdę kosztuje brakujące powiązanie, gdy nadchodzi zwrot.

Czym właściwie jest appAccountToken

appAccountToken to nieprzejrzysty UUID, który generujesz i przekazujesz do StoreKit w chwili zakupu. Apple przechowuje go w transakcji i zwraca w informacjach o transakcji dla tego zakupu, i tam pozostaje. Słowami Apple, jest to "UUID, który wiąże transakcję z kontem użytkownika w Twojej własnej usłudze." Jedyna reguła formatu to to, że musi być to UUID. Apple go nie czyta, nie weryfikuje, na co wskazuje, i nie obchodzi go, co on oznacza po Twojej stronie. To powiązanie, które kontrolujesz.

Ponieważ żyje na transakcji, wraca wszędzie tam, gdzie wraca transakcja. Podpisana transakcja w powiadomieniu serwerowym, odpowiedź Get Transaction Info z App Store Server API i każde odnowienie w łańcuchu subskrypcji niosą ten sam token, jeśli ustawiłeś go przy pierwotnym zakupie. Jeden UUID, dołączony raz, towarzyszy rozliczeniom klienta przez całe trwanie relacji.

Musi być prawdziwym UUID, inaczej znika po cichu

Jedyna reguła, której Apple pilnuje, to format. StoreKit 2 wymaga UUID zgodnego z RFC 4122. Jeśli przekażesz sklejony ciąg znaków, całkowite id lub adres e-mail, StoreKit nie rzuca błędu. Odrzuca wartość, a transakcja wraca z appAccountToken ustawionym na nil. Deweloperzy ciągle się na tym potykają, a objaw jest zawsze ten sam, jakaś odmiana "appAccountToken is missing in the transaction payload" na własnych forach Apple, prawie zawsze dlatego, że przekazana wartość nie była prawidłowym UUID. Wygeneruj prawdziwy UUID po stronie serwera, zapisz go przy koncie i nigdy nie podawaj StoreKit niczego innego.

Jak ustawić go w chwili zakupu

W StoreKit 2 jest to jedna opcja zakupu. Wygeneruj UUID na swoim serwerze, gdy użytkownik się rejestruje lub po raz pierwszy dociera do kasy, zapisz go w rekordzie konta i przekaż tę samą wartość do wywołania zakupu.

Sygnatura to Product.PurchaseOption.appAccountToken(_ token: UUID), a zakup wygląda jak try await product.purchase(options: [.appAccountToken(token)]). Gdy transakcja wraca, zweryfikowana przez App Store Server API lub dostarczona powiadomieniem serwerowym, niesie ten UUID, a Twój serwer odnajduje klienta jednym zapytaniem.

Używaj jednego stabilnego tokenu na konto

Nie generuj świeżego tokenu dla każdego zakupu tego samego użytkownika. Apple zwraca token przy odnowieniach, ponownych próbach obciążenia i aktualizacjach w tym samym łańcuchu, więc stabilny UUID na konto daje Ci czystą nić od pierwszego zakupu przez każde przyszłe zdarzenie. Token, który zmienia się przy każdym zakupie, zrywa tę nić i niweczy cały cel. Jedno konto, jeden token, użyty ponownie za każdym razem, gdy to konto kupuje.

Punkt końcowy, który ratuje zakupy poza aplikacją

Do 2025 roku istniała dziura. Jeśli klient zrealizował kod promocyjny albo kupił promowany zakup w aplikacji wprost z App Store, Twoja aplikacja nigdy nie uruchomiła przepływu zakupu, więc nie było gdzie ustawić appAccountToken. Te transakcje przychodziły anonimowe i takie pozostawały.

WWDC 2025 zamknęło lukę punktem końcowym Set App Account Token. Twój serwer wywołuje PUT /inApps/v1/transactions/{originalTransactionId}/appAccountToken na App Store Server API z UUID w treści, a Apple ustawia token na tej transakcji. Działa dla każdego typu produktu, obejmuje realizację kodów promocyjnych i zakupy promowane, a wartość, którą wysyłasz, nadpisuje każdy token już obecny na transakcji. Możesz teraz powiązać zakup po fakcie, ze swojego serwera, bez tego, by kiedykolwiek przechodził przez Twoją aplikację.

Stos papierowych paragonów sprzedaży na ciemnym biurku z pustą linią na nazwisko klienta, jeden oświetlony ciepłym reflektorem, ilustrujący zakup w App Store, który przychodzi bez appAccountToken pozwalającego zidentyfikować kupującego
Kanał zakupuGdzie ustawiasz appAccountTokenUwagi
Zakup w aplikacjiOpcja zakupu StoreKit w chwili kupnaProduct.PurchaseOption.appAccountToken(UUID)
Realizacja kodu promocyjnegoPunkt końcowy Set App Account Token, po stronie serweraBrak przepływu w aplikacji do podpięcia, więc ustaw go po fakcie
Promowany zakup w aplikacji z App StorePunkt końcowy Set App Account Token, po stronie serweraKupno dzieje się poza Twoją aplikacją
Odnowienie subskrypcjiNic do zrobieniaPrzenoszone automatycznie z pierwotnego zakupu

Gdzie brakujące powiązanie kosztuje Cię pieniądze

Sens tokenu to nie schludne rejestry. Chodzi o to, że jedyne pytanie Apple do deweloperów o zwroty, CONSUMPTION_REQUEST, da się odpowiedzieć tylko wtedy, gdy potrafisz odnaleźć klienta, którego dotyczy.

Gdy kupujący prosi o zwrot za produkt konsumpcyjny lub subskrypcję nieodnawialną, Apple wysyła na Twój serwer powiadomienie CONSUMPTION_REQUEST i daje Ci dwanaście godzin na odpowiedź przez Send Consumption Information. Twoja odpowiedź to dane o tym konkretnym kliencie: ile produktu zużył, jak długo trwa jego konto, jakie są jego wydatki na przestrzeni życia, jaki jest status dostawy. appAccountToken sam jest jednym z pól w tym żądaniu, a co ważniejsze, jest sposobem, w jaki transakcja z powiadomienia zostaje przypisana do konta, którego zużycie masz właśnie opisać. Brak tokenu, brak wyszukania, brak trafnej odpowiedzi.

Ile naprawdę kosztuje pusta odpowiedź

Niezidentyfikowany zwrot wymusza zły wybór. Możesz odpowiedzieć na żądanie zużycia niczym, co odczytuje się jako niskie zużycie i popycha Apple ku przyznaniu zwrotu, również klientom, którzy intensywnie korzystali z produktu. Albo możesz zgadywać. Tak czy inaczej zwracasz pieniądze za zakupy, na których obronę miałeś dowody, a realny koszt ich dostarczenia już poniosłeś.

Ten koszt to nie cena sprzedaży. Produkt konsumpcyjny, który uruchomił partię wywołań model API, wygenerował obrazy, wyeksportował wideo albo wyzwolił wypłatę dla twórcy, wydał prawdziwe pieniądze w chwili dostarczenia. Zwrot oddaje płatność klienta. Nie oddaje faktury dostawcy. Pomnóż jednego niemożliwego do zidentyfikowania klienta przez każdy zwrot, który złoży, i przez każdego seryjnego zwracającego, który liczy na to, że nie wiesz, kim jest, a token, który pominąłeś, staje się najdroższą linijką kodu, której nigdy nie napisałeś.

Ten sam pomysł istnieje na Androidzie, pod inną nazwą

Google Play rozwiązuje ten sam problem za pomocą setObfuscatedAccountId, który dołącza identyfikator konta do zakupu, aby weryfikację obciążenia zwrotnego Google przez orders.reviewrefund dało się odpowiedzieć wobec prawdziwego użytkownika. Inny sklep, inna mechanika, ta sama lekcja: dołącz tożsamość w chwili zakupu, inaczej nie obronisz sporu później. W App Store tym narzędziem jest appAccountToken, i musi być UUID.

Trzy nawyki, które utrzymują token na miejscu

  • Wygeneruj UUID na konto i zapisz go. Jeden stabilny token na klienta, utworzony przy rejestracji lub przy pierwszej kasie, zapisany w jego rekordzie i użyty ponownie przy każdym zakupie.
  • Zweryfikuj, zanim go przekażesz. Potwierdź w kodzie zakupu, że wartość jest prawdziwym UUID, aby zniekształcone id nigdy nie mogło po cichu stać się tokenem nil na transakcji.
  • Uzupełnij zakupy poza aplikacją. Gdy nadejdzie powiadomienie serwerowe o realizacji kodu promocyjnego lub o zakupie promowanym bez tokenu, wywołaj punkt końcowy Set App Account Token, aby dołączyć właściwy.

Zrób te trzy rzeczy, a każda transakcja, jaką Apple Ci kiedykolwiek prześle, wraz z żądaniami zwrotu, przychodzi już powiązana z klientem, do którego należy.

To fundament, na którym opiera się RefundHalt. Odczytujemy appAccountToken z każdej transakcji i powiadomienia serwerowego, wiążemy go ze zużyciem, które i tak śledzimy dla tego konta, i odpowiadamy na żądanie zużycia Apple w oknie dwunastu godzin prawdziwymi liczbami klienta. Token jest nicią. Ustaw go raz, a Twoja obrona przed zwrotami ma się czego trzymać.

Często zadawane pytania

Czym jest appAccountToken w App Store?
appAccountToken to UUID, który generujesz i dołączasz do zakupu przez StoreKit, aby powstała transakcja w App Store wskazywała z powrotem na konkretne konto użytkownika w Twoim własnym systemie. Apple przechowuje go w transakcji i zwraca w informacjach o transakcji, powiadomieniach serwerowych i każdym odnowieniu w tym samym łańcuchu, co pozwala Ci połączyć każde przyszłe zdarzenie, w tym żądanie zwrotu, z właściwym klientem.
Dlaczego mój appAccountToken jest nil albo go brakuje?
Prawie zawsze dlatego, że wartość, którą przekazałeś, nie była prawidłowym UUID. StoreKit 2 wymaga UUID zgodnego z RFC 4122 i po cichu odrzuca wszystko inne, więc sklejony ciąg znaków, całkowite id lub e-mail wracają jako nil appAccountToken, a zakup mimo to się udaje. Druga częsta przyczyna to zakup dokonany poza aplikacją, jak realizacja kodu promocyjnego, gdzie nie uruchomił się żaden przepływ w aplikacji, by ustawić token.
Czy mogę ustawić appAccountToken po zakupie, dla kodów promocyjnych?
Tak, od 2025 roku. Punkt końcowy Set App Account Token na App Store Server API pozwala Twojemu serwerowi dołączyć lub nadpisać token na istniejącej transakcji przez wywołanie PUT /inApps/v1/transactions/{originalTransactionId}/appAccountToken z UUID w treści. Działa dla każdego typu produktu i jest zbudowany dla zakupów dokonanych poza aplikacją, takich jak realizacja kodów promocyjnych i promowane zakupy w aplikacji.
Czy appAccountToken musi być UUID?
Tak. Jedyna reguła formatu, której Apple pilnuje, to to, że wartość jest prawidłowym UUID. Poza tym jest nieprzejrzysty, więc może wskazywać na dowolny klucz konta, jaki lubisz po swojej stronie, ale jeśli nie jest UUID, StoreKit go nie zapisze i transakcja wraca z appAccountToken ustawionym na nil.
Jak appAccountToken pomaga przy zwrotach?
Gdy klient prosi o zwrot, Apple wysyła CONSUMPTION_REQUEST i daje Ci dwanaście godzin na odpowiedź danymi o tym konkretnym kupującym. appAccountToken to sposób, w jaki dopasowujesz transakcję z powiadomienia do konta, którego zużycie masz zgłosić, i jest jednym z pól w samym żądaniu zużycia. Bez niego nie możesz odpowiedzieć prawdziwym zużyciem, więc Apple skłania się ku przyznawaniu zwrotów, które mogłeś zakwestionować dowodami.
Czy appAccountToken powinien być inny dla każdego zakupu?
Nie. Używaj jednego stabilnego UUID na konto i użyj go ponownie przy każdym zakupie tego użytkownika. Apple przenosi token przez odnowienia i aktualizacje w łańcuchu subskrypcji, więc stabilny token daje Ci czyste powiązanie w czasie. Token, który zmienia się przy każdym zakupie, zrywa to powiązanie i utrudnia przypisanie transakcji z powrotem do tego samego klienta.

Źródła i materiały dodatkowe

RefundHalt

Autopilot zwrotów dla App Store i Google Play

Czytaj dalej

Kolejny wniosek o zwrot jest już w drodze.

Skonfiguruj RefundHalt w czasie potrzebnym na przeczytanie kolejnej wiadomości od pomocy technicznej o zwrocie, którego nie udało Ci się zakwestionować.