Wszystkie artykuły
Playbook7 min czytania

Trzy powiadomienia o zwrotach z App Store przychodzą po decyzji Apple, a REFUND_REVERSED oddaje sprzedaż

Apple wysyła cztery wiadomości o zwrotach przez App Store Server Notifications V2, a większość aplikacji obsługuje tylko dwie. REFUND mówi, żeby cofnąć dostęp, REFUND_DECLINED oznacza zachowanie sprzedaży, a REFUND_REVERSED oddaje sprzedaż i prosi o przywrócenie tego, co zabrałeś. Oto czego wymaga każde z nich.

Smartfon pokazujący potwierdzenie płatności obok zwróconej koperty i pojedynczej monety, ilustrujący powiadomienia o zwrotach z App Store, które Apple wysyła po podjęciu decyzji o zwrocie

Najważniejsze wnioski

  • Apple wysyła cztery wiadomości związane ze zwrotami przez App Store Server Notifications V2. CONSUMPTION_REQUEST prosi o twoje dane, a REFUND, REFUND_DECLINED i REFUND_REVERSED zgłaszają wynik po tym, jak Apple już zdecydowało.
  • Powiadomienie REFUND oznacza, że App Store zwrócił środki za transakcję. Zawiera revocationDate i revocationReason i jest twoim sygnałem, aby cofnąć uprawnienie powiązane z tą jedną transakcją, a nie każdy zakup tego produktu.
  • revocationReason ma dwie wartości. 1 oznacza, że zwrot przyznano z powodu problemu z twoim produktem, a 0 oznacza, że przyznano go z innego powodu. Wartość oznaczająca problem to sygnał jakości, który warto logować i śledzić w trendach.
  • REFUND_DECLINED oznacza, że Apple odrzuciło wniosek klienta o zwrot. Zachowujesz sprzedaż i niczego nie zmieniasz, co jest bezpieczne tylko wtedy, gdy nie cofnąłeś dostępu przed ostatecznością decyzji.
  • REFUND_REVERSED oznacza, że Apple cofnęło wcześniej przyznany zwrot, zwykle po tym, jak klient go zakwestionuje. Pola cofnięcia znikają z transakcji, a własna instrukcja Apple mówi, że jeśli cofnąłeś treści, musisz je przywrócić.
  • Odpowiadaj na wszystkie cztery powiadomienia kodem HTTP 200. Jeśli twój serwer był wyłączony i przegapił jedno, punkt końcowy Get Refund History pozwala wyszukać zwrócone transakcje po identyfikatorze transakcji i je uzgodnić.
  • Zwrot za miniony okres subskrypcji nie zawsze oznacza, że dostęp powinien się zakończyć. Jeśli nowszy opłacony okres wciąż jest aktywny, cofnięcie na starej transakcji odcina klienta, który jest na bieżąco.

Apple decyduje o twoim zwrocie, a potem nadal mówi. Gdy wynik jest ustalony, App Store wysyła twojemu serwerowi jedno z trzech powiadomień o zwrotach z App Store, a każde wymaga innego ruchu. REFUND mówi, że pieniądze przepadły i powinieneś odebrać dostęp. REFUND_DECLINED mówi, że klient przegrał wniosek i zachowujesz sprzedaż. REFUND_REVERSED mówi, że Apple cofnęło zwrot, który już przyznało, więc sprzedaż znów należy do ciebie i musisz oddać to, co zabrałeś. Większość aplikacji podłącza pierwsze i po cichu ignoruje pozostałe dwa. W ten sposób płacący klient zostaje odcięty od czegoś, za co zapłacił.

Te trzy są oddzielone od CONSUMPTION_REQUEST, jedynej wiadomości o zwrocie, która prosi o odpowiedź. Powiadomienia po decyzji nie chcą dyskusji. Chcą HTTP 200 i właściwej zmiany w dostępie klienta. Oto co oznacza każde z nich, jakie dokładnie pola niosą fakty i gdzie wyciekają pieniądze, gdy obsłużysz je źle.

Cztery powiadomienia o zwrotach i to, które chce odpowiedzi

App Store Server Notifications V2 to pojedynczy strumień. Kierujesz go na jeden URL, a Apple wysyła tam każdy typ powiadomienia, więc już otrzymujesz wszystkie cztery wiadomości o zwrotach, niezależnie od tego, czy je obsługujesz. Cztery z tych typów dotyczą zwrotów, a tylko jeden z nich jest pytaniem.

PowiadomienieCo Apple ci komunikujeTwoje działanieOczekiwana odpowiedź
CONSUMPTION_REQUESTKlient poprosił o zwrot, a Apple chce twoich danychSend Consumption Information w ciągu 12 godzinTak, prawdziwe dane
REFUNDApp Store zwrócił środki za transakcjęCofnij uprawnienie dla tej transakcjiNie, HTTP 200
REFUND_DECLINEDApp Store odrzucił zwrotZachowaj dostęp, nic nie zmieniajNie, HTTP 200
REFUND_REVERSEDApple cofnęło przyznany zwrotPrzywróć treści, które cofnąłeśNie, HTTP 200

Co powiadomienie REFUND naprawdę ci mówi

REFUND uruchamia się, gdy App Store pomyślnie zwrócił klientowi środki za transakcję. Dotyczy każdego typu zakupu: produktu zużywalnego, produktu niezużywalnego, subskrypcji odnawialnej automatycznie i subskrypcji nieodnawialnej. Podpisana transakcja w powiadomieniu niesie teraz dwa pola, których nie miała przed zwrotem, i te dwa pola to cała historia.

revocationDate i revocationReason niosą fakty

revocationDate to czas UNIX w milisekundach, w którym App Store zwrócił środki za transakcję lub ją cofnął. revocationReason podaje ci kategorię zwrotu i przyjmuje dokładnie dwie wartości.

revocationReasonZnaczenie według AppleCo z tego wyczytać
1Zwrot przyznano z powodu problemu z produktemSygnał jakości lub dostarczenia. Zaloguj go, śledź trend i szukaj wzorca w jednym produkcie lub jednym buildzie
0Zwrot przyznano z innego powoduZwykły zwrot. Cofnij uprawnienie i działaj dalej

Sama obecność revocationDate w transakcji jest już flagą. Jeśli pobierzesz transakcję później i ma ona revocationDate, ten zakup został zwrócony, z powiadomieniem lub bez. Odczytuj powód obok, aby fala zwrotów o wartości 1 przy jednym wydaniu nie umknęła ci jako szum.

Cofaj według transakcji, nie według produktu

Pułapką jest tu cofnięcie zbyt wiele. REFUND wskazuje jedną transakcję. Nie mówi ci, aby wyłączyć każdy zakup, jaki klient kiedykolwiek zrobił dla tego identyfikatora produktu. Własne wytyczne Apple mówią, aby sprawdzić, jaki dostęp klient wciąż posiada, zanim cokolwiek odetniesz, ponieważ uprawnienia się nakładają. Klasyczny przypadek to subskrypcja: zwrot ląduje na zeszłomiesięcznym odnowieniu, podczas gdy tegomiesięczne odnowienie jest aktywne i w pełni opłacone. Cofnij na poziomie produktu, a właśnie odciąłeś bieżącego, płacącego klienta z powodu zwrotu za okres, który już się zakończył.

REFUND_DECLINED oznacza, że już wygrałeś, więc tego nie cofaj

REFUND_DECLINED przychodzi, gdy App Store odrzucił wniosek klienta o zwrot. Klient poprosił, Apple powiedziało nie, a ty zachowujesz sprzedaż. Na pierwszy rzut oka nie ma nic do zrobienia i to jest sedno. Błąd, który to powiadomienie ujawnia, jest inny: zbyt wczesne cofnięcie dostępu.

Jeśli twój kod reaguje na CONSUMPTION_REQUEST, odbierając klientowi dostęp, zanim Apple orzeknie, REFUND_DECLINED to moment, w którym ta decyzja wybucha. Apple zatrzymało twoje pieniądze, a ty odciąłeś klienta, którego zwrot odrzucono. Ten klient płaci teraz za produkt, którego nie może używać, otwiera zgłoszenie do wsparcia i to zapamiętuje. Rozwiązaniem jest reguła, nie funkcja: cofaj przy REFUND, nigdy przy wniosku. REFUND_DECLINED to po prostu potwierdzenie Apple, że wczesne cofnięcie byłoby błędną decyzją.

REFUND_REVERSED to powiadomienie, które ci płaci

REFUND_REVERSED to to, którego prawie nikt nie obsługuje, i to ono zwraca ci pieniądze. Apple wysyła je, gdy cofa wcześniej przyznany zwrot, zwykle po tym, jak klient ten zwrot zakwestionuje. Pola cofnięcia, które REFUND dodał do transakcji, zostają ponownie usunięte, więc zakup znów odczytywany jest jako opłacony. Apple ujmuje zadanie dewelopera w jednym zdaniu: jeśli twoja aplikacja cofnęła treści lub usługi w wyniku powiązanego zwrotu, musi je przywrócić. Dotyczy to każdego typu zakupu, od produktu zużywalnego po subskrypcję odnawialną automatycznie.

Problem pojawiający się tygodnie później

Prawdziwe pytanie, które deweloperzy zadają na własnych forach Apple, dotyczy czasu. REFUND_REVERSED może nadejść tygodnie po pierwotnym REFUND, długo po wygaśnięciu okresu subskrypcji. Czy przywracasz wtedy dostęp? Przywróć to, co transakcja faktycznie przyznaje, ograniczone do tego, co obejmuje ta transakcja. Dla produktu zużywalnego lub niezużywalnego włącz odblokowanie z powrotem. Dla okresu subskrypcji, który już minął, nie rozdajesz nowego czasu, poprawiasz zapis, aby historia klienta była dokładna, a każde wciąż ważne uprawnienie ponownie się uruchomiło. Przywróć konkretną transakcję, a twoja logika nakładania się zdecyduje, co jest obecnie aktywne.

Moneta odkładana z powrotem obok smartfona, ilustrująca cofnięty zwrot z App Store, który przywraca sprzedaż deweloperowi

Gdzie leżą pieniądze, gdy robisz to dobrze

Każde z tych powiadomień odpowiada realnej liczbie, a koszt złej obsługi to nie tylko cena sprzedaży.

REFUND: przestań płacić za obsługę klienta, któremu zwrócono środki

Cena sprzedaży przepada w chwili, gdy przychodzi REFUND. Co wciąż możesz kontrolować, to koszt dalszego dostarczania. Każda godzina, w której zwrócone uprawnienie pozostaje aktywne, to dalsze wydatki na rzeczy, za które klient już nie płaci: moc obliczeniową, wywołania API modelu, przechowywanie oraz każdą wypłatę dla twórcy lub partnera powiązaną z jego użytkowaniem. Szybkie cofnięcie przy REFUND zatrzymuje ten licznik. Zignorowanie powiadomienia oznacza finansowanie produktu dla kogoś, komu sklep już zrekompensował.

REFUND_DECLINED: nie zamieniaj wygranej w zwrot z dobrej woli

Gdy cofniesz zbyt wcześnie, a zwrot zostanie później odrzucony, zachowałeś sprzedaż na papierze, a straciłeś ją w praktyce. Klient, który zapłacił, nie może korzystać z produktu, więc dziedziczysz rozmowę z pomocą techniczną i, często, uznaniowy zwrot, aby to naprawić. To płacenie dwa razy za jedną sprzedaż, która nigdy nie była zagrożona. Poprawna obsługa REFUND_DECLINED nic nie kosztuje i właśnie dlatego pozostawienie dostępu nietkniętego aż do REFUND to najtańsza reguła, jaką możesz przyjąć.

REFUND_REVERSED: najgorsze połączenie to brak zarówno ich pieniędzy, jak i ich dostępu

Zignoruj REFUND_REVERSED, a osiągniesz najgorszy możliwy wynik. Otrzymałeś zapłatę, a klient nie ma nic. Skontaktował się już raz ze swoim bankiem, aby cofnąć zwrot, a osoba odcięta od produktu, za który jest teraz obciążana, to osoba, która prawdopodobnie skontaktuje się z bankiem po raz drugi. Ten kolejny spór może stać się chargebackiem karty, który jest ostateczny po stronie banku i kosztuje więcej, niż kiedykolwiek dała sprzedaż. Przywrócenie dostępu w chwili nadejścia REFUND_REVERSED to najtańsze ubezpieczenie w całym procesie zwrotów.

Co skonfigurować

Obsługa jest niewielka, gdy model jest poprawny. Powiąż uprawnienia z identyfikatorem transakcji, aby każde powiadomienie wskazywało na jeden zakup. Przy CONSUMPTION_REQUEST wyślij swoje dane w ciągu 12 godzin. Przy REFUND cofnij tę transakcję. Przy REFUND_DECLINED nie rób nic. Przy REFUND_REVERSED przywróć. Szybko zwracaj HTTP 200 dla wszystkich i wykonaj zmianę dostępu we własnym czasie.

Na lukę, którą zostawiają powiadomienia, użyj punktu końcowego Get Refund History. Jeśli twój serwer był wyłączony podczas awarii i przegapił REFUND, wywołaj wyszukiwanie zwrotów App Store Server API dla identyfikatora transakcji pod /inApps/v2/refund/lookup/{transactionId} i odczytaj podpisane transakcje z ich revocationDate i revocationReason. Uzgadnia jedną transakcję naraz i przechodzi po stronach zwróconych zakupów klienta, więc przegapiony webhook nie staje się trwale źle ustawionym uprawnieniem.

To jest część, którą RefundHalt wykonuje za ciebie. Nasłuchuje wszystkich czterech typów, cofa przy REFUND, pozostawia dostęp nietknięty przy REFUND_DECLINED i automatycznie przywraca przy REFUND_REVERSED, każde powiązane z dokładną transakcją. Cofnięty zwrot nie czeka w kolejce, podczas gdy płacący klient pozostaje odcięty, a odrzucony nigdy nie wyzwala cofnięcia, które musiałbyś odwoływać.

Często zadawane pytania

Jaka jest różnica między REFUND a REFUND_REVERSED?
REFUND oznacza, że App Store zwrócił środki za transakcję i powinieneś cofnąć to uprawnienie, natomiast REFUND_REVERSED oznacza, że Apple cofnęło przyznany zwrot i powinieneś przywrócić cofnięte treści. Te dwa tworzą parę: zakup może przejść przez REFUND, a następnie, jeśli spór klienta zostanie uchylony, przez REFUND_REVERSED. Powiąż zmiany dostępu z identyfikatorem transakcji, aby każde powiadomienie działało na właściwym zakupie.
Czy muszę coś odesłać w odpowiedzi na powiadomienie REFUND?
Nie. Na REFUND, REFUND_DECLINED i REFUND_REVERSED odpowiadasz kodem HTTP 200 bez treści. Tylko CONSUMPTION_REQUEST prosi cię o wysłanie danych i robi to przez punkt końcowy Send Consumption Information w ciągu 12 godzin. Pozostałe trzy to Apple zgłaszające decyzję, a nie zadające pytanie.
Co powinienem zrobić, gdy dostanę powiadomienie REFUND_DECLINED?
Nic się nie zmienia, ponieważ zwrot klienta został odrzucony, a ty zachowujesz sprzedaż. Jedyny sposób, w jaki REFUND_DECLINED powoduje pracę, to gdy cofnąłeś dostęp zbyt wcześnie, zanim Apple orzekło. Cofaj przy REFUND, a nie przy CONSUMPTION_REQUEST, a REFUND_DECLINED staje się potwierdzeniem, że dostęp słusznie pozostawiono nietknięty.
Czy powinienem przywrócić dostęp, gdy REFUND_REVERSED przychodzi tygodnie po zwrocie?
Tak, przywróć uprawnienie, które przyznaje ta konkretna transakcja. Apple stwierdza, że jeśli twoja aplikacja cofnęła treści z powodu powiązanego zwrotu, musi je przywrócić. Dla produktu zużywalnego lub niezużywalnego włącz odblokowanie z powrotem. Dla okresu subskrypcji, który już wygasł, poprawiasz zapis, nie przyznajesz nowego czasu, więc twoja logika nakładania się wciąż decyduje, co jest obecnie aktywne.
Jak wychwycić powiadomienie o zwrocie, które przegapił mój serwer?
Użyj punktu końcowego Get Refund History w App Store Server API, który wyszukuje zwrócone transakcje klienta po identyfikatorze transakcji pod /inApps/v2/refund/lookup/{transactionId}. Zwraca podpisane transakcje z revocationDate i revocationReason, więc po awarii możesz uzgodnić dostęp bez czekania na powiadomienie, które już się uruchomiło. Obsługuje jeden identyfikator transakcji na wywołanie i przechodzi po stronach zwróconych zakupów 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ć.