Jest jeden endpoint, który zwraca całą App Store refund history klienta, i oto co odsyła w odpowiedzi
Endpoint Get Refund History od Apple zwraca pełną App Store refund history klienta jako podpisane transakcje. Oto każde pole, jak token revision stronicuje, dlaczego działa per klient, a nie per aplikacja, i ile kosztuje Cię przeoczony zwrot.

Najważniejsze wnioski
- Get Refund History to endpoint App Store Server API, który zwraca zwrócone zakupy w aplikacji danego klienta dla Twojej aplikacji jako listę podpisanych transakcji, dzięki czemu uzgadniasz zwroty i odbierasz dostęp, nawet gdy powiadomienie nigdy do Ciebie nie dotarło.
- Wywołujesz GET /inApps/v2/refund/lookup/{transactionId} z dowolnym identyfikatorem transakcji tego klienta, a Apple zwraca jego zwroty dla każdego typu zakupu w Twojej aplikacji, nie tylko tego, o który pytałeś.
- Odpowiedź ma trzy pola: signedTransactions, do 20 transakcji JWS na stronę, posortowanych od najstarszego zwrotu, plus token revision i wartość logiczną hasMore do stronicowania.
- Zapisz końcowy token revision. Przekaż go z powrotem następnym razem, a Apple zwróci tylko zwroty nowsze niż ten punkt, co zamienia pełny zrzut historii w krótką listę nowych wierszy przy każdym uruchomieniu.
- Każda zdekodowana transakcja niesie revocationDate i revocationReason. revocationReason równy 1 oznacza, że klient dostał zwrot z powodu faktycznego lub odczuwanego problemu w Twojej aplikacji, a 0 oznacza inny powód, na przykład przypadkowy zakup.
- Endpoint działa per klient, nie per aplikacja. Nie ma jednego wywołania, które wylistuje każdy zwrot w całej Twojej aplikacji, więc uzgadniasz per konto od identyfikatora transakcji albo czytasz strumień powiadomień REFUND dla widoku obejmującego całą aplikację.
- Powodem, by to podłączyć, są pieniądze. Zwrot, którego nigdy nie wychwycisz, utrzymuje konto aktywne, a Ty dalej płacisz za moc obliczeniową, wywołania API modelu, przechowywanie i wypłaty dla klienta, którego App Store już rozliczył.
Apple prowadzi dla każdego konta klienta powiązanego z Twoją aplikacją przeszukiwalny zapis każdego zwrotu, który przyznał, i jedno wywołanie go zwraca. Endpoint nazywa się Get Refund History, jest częścią App Store Server API i podaje Ci pełną App Store refund history tego klienta jako listę podpisanych transakcji. Przekazujesz identyfikator transakcji, dostajesz z powrotem to, co Apple zwróciło, i uzgadniasz to z tym, co nadal masz włączone.
Oto dlaczego warto się tym zająć. Zwrot, którego nigdy nie widzisz, to zwrot, za który dalej płacisz. Pieniądze już przepadły, ale konto pozostaje aktywne, i każdą godzinę, gdy tak jest, dalej wydajesz na moc obliczeniową, wywołania API modelu, przechowywanie i każdą wypłatę powiązaną z tym klientem. Twoje powiadomienia o zwrotach mają wychwytywać to w chwili, gdy się dzieje. Get Refund History to zabezpieczenie na wypadek, gdy tego nie zrobią, po awarii, po wdrożeniu, które zgubiło webhooka, albo w sprawie wsparcia, gdzie potrzebujesz całego obrazu w jednym wywołaniu.
Co zwraca endpoint App Store refund history
Wywołujesz GET /inApps/v2/refund/lookup/{transactionId} względem App Store Server API, podpisane tym samym JWT, którego używasz do każdego innego wywołania. Identyfikator transakcji w ścieżce może być dowolną transakcją tego klienta. Apple czyta go jako tożsamość, nie jako filtr, i zwraca zwrócone zakupy tego klienta z całej Twojej aplikacji: dobra konsumpcyjne, dobra niekonsumpcyjne, subskrypcje odnawialne automatycznie i nieodnawialne na równi. Starsze V1 tego endpointu zwracało do 50 zwrotów w jednej odpowiedzi i jest wycofane. Bieżąca wersja stronicuje, więc obsługujesz klientów z długą historią bez ogromnego ładunku danych.
Odpowiedź to trzy pola
| Pole | Co zawiera |
|---|---|
| signedTransactions | Do 20 zwróconych transakcji tego klienta, każda jako podpisany JWS, który weryfikujesz i dekodujesz. Posortowane od najstarszego zwrotu, według revocationDate. Pusta tablica oznacza, że klient nie ma zwrotów w Twojej aplikacji |
| revision | Token stronicowania. Przekaż go z powrotem, aby dostać następną stronę, i zachowaj ostatni, aby następnym razem pobrać tylko nowe zwroty |
| hasMore | True, gdy Apple przechowuje więcej zwróconych transakcji, niż zwróciła ta strona, więc wywołujesz ponownie z revision |
Co mówi Ci jedna zwrócona transakcja
Każdy wpis w signedTransactions to JWS. Zweryfikuj go względem łańcucha certyfikatów Apple, zdekoduj, a masz zwykły ładunek transakcji z wypełnionymi polami zwrotu. To są te, które tu się liczą.
| Pole | Co Ci mówi |
|---|---|
| transactionId | Identyfikator zwróconej transakcji, Twój klucz łączący z powrotem do zarejestrowanego zakupu |
| originalTransactionId | Identyfikator pierwszego zakupu w łańcuchu, sposób na powiązanie odnowień subskrypcji ze sobą |
| productId | Zwrócony produkt, abyś odebrał właściwe uprawnienie i nic poza tym |
| revocationDate | Czas UNIX, w milisekundach, w którym Apple zwróciło transakcję |
| revocationReason | Dlaczego Apple ją zwróciło. 1 oznacza faktyczny lub odczuwany problem z Twoją aplikacją, 0 oznacza inny powód, na przykład przypadkowy zakup |
| price, currency | Kwota, w milliunits, oraz jej kod waluty ISO 4217, abyś mógł zsumować zwrócone pieniądze |
| appAccountToken | UUID, który dołączyłeś przy zakupie, najczystszy sposób na przypisanie zwrotu z powrotem do Twojego własnego użytkownika |
Token revision to sposób, by przestać czytać całą listę od nowa
Naiwny sposób użycia tego endpointu to wyszukanie klienta i przejście przez każdą stronę za każdym razem. To działa, i u klienta z pięćdziesięcioma zwrotami to pięćdziesiąt wierszy, które już znałeś, plus ten jeden nowy. Token revision istnieje, by zabić to marnotrawstwo. Każda odpowiedź niesie revision. Gdy hasMore ma wartość true, przekazujesz go z powrotem, aby dostać następną stronę. Gdy docierasz do końca, zachowujesz ostatni revision, który widziałeś.
Czego ten endpoint nie zrobi
Jest jedno oczekiwanie, którego trzeba się pozbyć, zanim na tym zbudujesz. Get Refund History działa per klient, nie per aplikacja. Nie zapytasz go o każdy zwrot, jaki Twoja aplikacja odnotowała w zeszłym tygodniu. Odpowiada na jedno pytanie, które zwroty ma to konto, i musisz przyjść z identyfikatorem transakcji dla tego konta, by je zadać. Deweloperzy nieustannie uderzają w tę ścianę i szukają endpointu zwrotów dla całej aplikacji, który nie istnieje.
Widok obejmujący całą aplikację znajduje się gdzie indziej. Twój strumień App Store Server Notifications wysyła powiadomienie REFUND w chwili, gdy Apple przyznaje każdy zwrot, a Get Notification History pozwala Ci odtworzyć ten strumień przefiltrowany do typów zwrotów w zakresie dat. Podział jest więc czysty. Powiadomienia i ich historia dają Ci strumień obejmujący całą aplikację. Get Refund History daje Ci miarodajną listę jednego konta, na żądanie, co jest tym, czego chcesz przy biurku wsparcia albo po awarii.

Ile kosztuje Cię przeoczony zwrot w pieniądzach
Endpoint to instalacja. Rachunek to powód, dla którego kładziesz rurę. Każdy zwrot na tej liście to pieniądze już zwrócone, a jedyną zmienną, która pozostaje pod Twoją kontrolą, jest to, jak długo dalej wydajesz na konto, które już nie płaci.
Dalej płacisz za obsługę zwróconego konta
Cena zakupu przepada w chwili, gdy Apple przyznaje zwrot. To, co dalej działa, to koszt dostarczania. Dla aplikacji, która wykonuje realną pracę na użytkownika, to moc obliczeniowa, wywołania API modelu, przechowywanie i każda wypłata dla twórcy lub partnera powiązana z ich użyciem. Zwrócony klient, któremu nigdy nie odciąłeś dostępu, to subskrypcja, którą finansujesz z własnej kieszeni. Uzgadnianie względem Get Refund History i odbieranie dostępu na podstawie tego, co znajdujesz, to sposób, by wyłączyć ten licznik, gdy powiadomienie się prześlizgnęło.
Powód zwrotu równy 1 to przebrany raport o usterce
revocationReason kosztuje Cię podwójnie, jeśli go zignorujesz. Pierwszym kosztem jest sam zwrot. Drugim jest każdy przyszły zwrot z tej samej przyczyny. Gdy produkt wciąż wraca z revocationReason 1, faktycznym lub odczuwanym problemem w Twojej aplikacji, Apple wręcza Ci oznaczoną próbkę tego, co sprawia, że klienci proszą o zwrot pieniędzy. Wyznacz z tego trend per produkt, a możesz załatać wyciek zamiast wypłacać go zwrot po zwrocie.
Wychwycenie z opóźnieniem nadal bije niewychwycenie
Chargeback jest ostateczny wobec banku i w drugim sklepie niesie teraz opłatę, którą deweloper przełyka. Zwrot w App Store taki nie jest. Jest rozliczony, ale uprawnienie należy do Ciebie, byś je odebrał w chwili, gdy wiesz. Więc nawet zwrot, który znajdziesz kilka dni za późno przez ten endpoint, wart jest znalezienia. Nie odzyskasz pieniędzy, ale możesz zatrzymać wydatek, który wciąż za nim biegł.
Jak to pasuje do powiadomień i do Google
Traktuj te elementy jako jeden system. Powiadomienie REFUND to sygnał na żywo, wypchnięty na Twój serwer w chwili, gdy Apple decyduje. Get Refund History to oparte na pobieraniu źródło prawdy dla jednego klienta, wywołanie, które robisz, gdy push zawiódł albo gdy człowiek potrzebuje pełnego konta przed sobą. Po stronie Google Play kształt to ta sama idea pod innymi nazwami: VoidedPurchaseNotification wypycha się w czasie rzeczywistym, a Voided Purchases API to lista, którą pobierasz. Oba sklepy dają Ci strumień i księgę. Błędem jest ufać tylko strumieniowi, bo strumienie się gubią.
Podłączanie tego w stylu RefundHalt
Pętla jest mała, gdy każdy element jest na swoim miejscu. Weź powiadomienie REFUND jako wyzwalacz. Uzgadniaj względem Get Refund History, aby zgubiony webhook nigdy nie zostawił zwróconego konta aktywnym. Zdekoduj każdą transakcję, zwiąż ją po appAccountToken lub transactionId z powrotem z Twoim użytkownikiem, przeczytaj revocationReason, aby zwrot z usterki został oznaczony, a nie tylko odłożony, i odbierz dokładne uprawnienie zamiast całego konta. Stronicuj tokenem revision, abyś czytał nowe zwroty, nie stare.
To jest część, którą RefundHalt prowadzi za Ciebie. Nasłuchuje powiadomień o zwrotach, sięga po Get Refund History, gdy potrzebuje miarodajnej listy, weryfikuje każdą podpisaną transakcję, odbiera dokładny zakup i zachowuje revision, aby każde przejście czytało tylko to, co się zmieniło. Dostajesz odcięty dostęp w kilka sekund i czysty zapis tego, kto dostał zwrot, za co i dlaczego, bez samodzielnego stawiania odpytywania i weryfikacji JWS.
Często zadawane pytania
- Jak zobaczyć każdy zwrot w całej mojej aplikacji, a nie tylko jednego klienta?
- Nie da się tego przez Get Refund History, bo działa on per klient i potrzebuje identyfikatora transakcji dla konta, o które pytasz. Dla widoku obejmującego całą aplikację użyj strumienia App Store Server Notifications, który wysyła powiadomienie REFUND dla każdego zwrotu w chwili, gdy Apple go przyznaje, oraz Get Notification History, aby odtworzyć ten strumień przefiltrowany do typów zwrotów w zakresie dat.
- Ile zwrotów zwraca endpoint Get Refund History?
- Bieżąca wersja zwraca do 20 zwróconych transakcji na stronę, posortowanych od najstarszego zwrotu, i stronicuje przez resztę tokenem revision, gdy hasMore ma wartość true. Wycofany endpoint V1 zwracał do 50 w jednej odpowiedzi. Nie ma limitu na łączną liczbę, więc klient z długą historią po prostu obejmuje więcej stron.
- Do czego służy token revision?
- To sposób, w jaki stronicujesz, i sposób, w jaki unikasz czytania całej historii klienta za każdym razem. Każda odpowiedź zawiera revision. Przekazujesz go z powrotem, aby pobrać następną stronę, i zapisujesz ostatni, aby Twoje kolejne wyszukiwanie zwracało tylko zwroty nowsze niż ten punkt. To utrzymuje zaplanowane uzgadnianie na krótkiej liście nowych wierszy.
- Co oznacza revocationReason w zwróconej transakcji?
- To powód, dla którego Apple zwróciło transakcję. Wartość 1 oznacza, że klient dostał zwrot z powodu faktycznego lub odczuwanego problemu w Twojej aplikacji, a 0 oznacza inny powód, na przykład przypadkowy zakup. revocationDate mówi Ci, kiedy nastąpił zwrot, w milisekundach UNIX. Czytanie revocationReason pozwala oddzielić usterkę produktu od jednorazowego zwrotu z żalu.
- Czy nadal tego potrzebuję, skoro już obsługuję powiadomienia REFUND?
- Tak, jako zabezpieczenie. Powiadomienia to sygnał na żywo, ale push może nie dotrzeć podczas awarii, złego wdrożenia lub zmiany webhooka, a przeoczony zwrot zostawia zwrócone konto aktywnym i kosztującym Cię pieniądze. Get Refund History to oparte na pobieraniu źródło prawdy, względem którego uzgadniasz, aby nic nie zostało włączone, co Apple już zwróciło.
Źródła i materiały dodatkowe
- Apple Developer: Get Refund History (App Store Server API)
- Apple Developer: RefundHistoryResponse
- Apple Developer: JWSTransactionDecodedPayload (revocationDate, revocationReason)
- Apple Developer: Get Refund History V1 (deprecated)
- Apple Developer: App Store Server Notifications V2 notificationType (REFUND)
- Apple Developer: Support customers and handle refunds (WWDC21)
RefundHalt
Autopilot zwrotów dla App Store i Google Play
Czytaj dalej
Twoja aplikacja może pokazać arkusz wniosku o zwrot środków wewnątrz aplikacji, a oto co robi Apple, gdy klient dotknie przycisku wyślij
Wewnątrzaplikacyjny wniosek o zwrot Apple pozwala klientowi poprosić o zwrot bez opuszczania Twojej aplikacji, na arkuszu, który Apple buduje i sprawdza. Oto co zwraca beginRefundRequest, jakie zegary CONSUMPTION_REQUEST i 48 godzin uruchamia na Twoim serwerze oraz czy warto wdrożyć ten przycisk.
Gdy zakup w Google Play zostaje zwrócony lub obciążony zwrotnie, Voided Purchases API jest sposobem, w jaki się o tym dowiadujesz
Google Play po cichu unieważnia zakup, gdy zostaje on zwrócony lub obciążony zwrotnie. Voided Purchases API to lista tych zamówień, dzięki której możesz odebrać dostęp. Oto każde pole, okno 30 dni, opcja revoke, która ukrywa zamówienia, oraz ile to kosztuje.