Wszystkie artykuły
Playbook8 min czytania

Jeśli Twoja aplikacja wciąż działa na App Store Server Notifications V1, Apple nigdy nie zapyta Cię o zwroty za subskrypcje

Apple oznaczyło App Store Server Notifications V1 jako przestarzałe w czerwcu 2023 roku, a V1 nigdy nie dostało CONSUMPTION_REQUEST dla subskrypcji, REFUND_DECLINED ani REFUND_REVERSED. Oto co traci serwer na V1, ile to kosztuje i jak przejść na V2, nie gubiąc żadnego zwrotu.

Stara skrzynka pocztowa przepełniona nieotwartymi listami obok nowoczesnej szafy serwerowej, ilustrująca sygnały o zwrotach gubione w App Store Server Notifications V1

Najważniejsze wnioski

  • Apple oznaczyło App Store Server Notifications V1 i endpoint verifyReceipt jako przestarzałe 5 czerwca 2023 roku. Oba nadal działają, nie dostają nowych funkcji i nie mają ogłoszonej daty wyłączenia.
  • Dokumentacja V1 od Apple wymienia CONSUMPTION_REQUEST tylko dla zakupów konsumpcyjnych (consumables). Consumption requests dla automatycznie odnawianych subskrypcji dodano do App Store Server Notifications V2 w kwietniu 2024 roku.
  • REFUND_DECLINED i REFUND_REVERSED istnieją tylko w App Store Server Notifications V2, więc serwer na V1 nigdy się nie dowie, że Apple odrzuciło zwrot albo go cofnęło.
  • W V1 zwrot automatycznie odnawianej subskrypcji przez Apple przychodzi jako CANCEL. W V2 przychodzi jako REFUND, z polami revocationDate i revocationReason w podpisanej transakcji.
  • Apple ponawia nieudane powiadomienie V2 pięć razy w ciągu około tygodnia, po 1, 12, 24, 48 i 72 godzinach. Nieudane powiadomienie V1 dostaje trzy ponowienia, po 6, 24 i 48 godzinach, i nie da się go odzyskać przez Get Notification History.
  • Po przełączeniu aplikacji na V2 w App Store Connect nowe powiadomienia od razu przychodzą w formacie V2, a powiadomienia V1, które są już w trakcie ponawiania, mogą napływać jeszcze przez około 78 godzin.

Version 1 App Store Server Notifications nadal dostarcza zwroty, ale pomija to jedno powiadomienie, które pozwala zakwestionować zwrot za subskrypcję. Apple oznaczyło V1 jako przestarzałe 5 czerwca 2023 roku, razem z endpointem verifyReceipt, i od tego czasu każdą nową funkcję związaną ze zwrotami dodaje wyłącznie do V2. Jeśli w ustawieniach App Store Connect nadal masz Version 1, Apple może rozstrzygnąć zwrot za subskrypcję, nie wysyłając Twojemu serwerowi ani jednego CONSUMPTION_REQUEST. Nie przegrywasz tam sporu. Po prostu nikt Cię do niego nie zaprasza.

Co oznacza wycofanie App Store Server Notifications V1

Przestarzałe nie znaczy wyłączone. Inżynier Apple napisał na forach deweloperów w czerwcu 2023 roku, że verifyReceipt i powiadomienia V1 będą działać do czasu ogłoszenia daty wyłączenia, że ta data nie została jeszcze ustalona i że deweloperzy zostaną uprzedzeni z wyprzedzeniem. Ponad trzy lata później App Store Connect nadal oferuje opcję "Version 1 (deprecated)" przy ustawianiu adresu URL serwera.

Przestarzałe oznacza za to zamrożenie. Każda zmiana w changelogu powiadomień Apple od czerwca 2023 roku dotyczy V2: nowe pola w podpisanej transakcji, nowe typy powiadomień, dane o 12-miesięcznym zobowiązaniu dodane w kwietniu 2026 roku. Serwer na V1 nie widzi nic z tego.

Jakich sygnałów o zwrotach serwer na V1 nigdy nie dostaje

Tak te same zdarzenia związane ze zwrotami docierają do serwera na V1 i na V2, według dokumentacji Apple dla każdej wersji.

Zdarzenie zwrotuVersion 1Version 2
Klient prosi Apple o zwrot za zakup konsumpcyjnyCONSUMPTION_REQUESTCONSUMPTION_REQUEST
Klient prosi Apple o zwrot za automatycznie odnawianą subskrypcjęBrak w dokumentacji V1CONSUMPTION_REQUEST, od kwietnia 2024
Apple zwraca środki za automatycznie odnawianą subskrypcjęCANCELREFUND
Apple zwraca środki za zakup konsumpcyjny, niekonsumpcyjny lub nieodnawianą subskrypcjęREFUNDREFUND
Apple odrzuca zwrot, który klient rozpoczął w Twojej aplikacjiNiedostępneREFUND_DECLINED
Apple cofa zwrot, który już przyznałoNiedostępneREFUND_REVERSED
Odzyskujesz powiadomienia utracone podczas awariiNiedostępneGet Notification History

Czy V1 w ogóle dostaje jeszcze CONSUMPTION_REQUEST?

Tak, dla zakupów konsumpcyjnych. Dokumentacja referencyjna V1 opisuje CONSUMPTION_REQUEST jako powiadomienie wysyłane, gdy klient rozpoczyna wniosek o zwrot za zakup konsumpcyjny. Inżynier Apple potwierdził na forach w 2023 roku, że consumption requests w V1 są wysyłane przy kwalifikujących się zwrotach. Luka dotyczy subskrypcji. Changelog Apple datuje consumption requests dla subskrypcji na 11 kwietnia 2024 roku, w V2, a dokumentacja Send Consumption Information mówi, że Apple wysyła to żądanie przez Twój endpoint V2.

Dlaczego CANCEL w V1 łatwo źle odczytać

Gdy w V1 Apple zwraca środki za subskrypcję, typ powiadomienia to CANCEL, często w parze z DID_CHANGE_RENEWAL_STATUS. Wiele serwerów traktuje każde anulowanie jak wyłączenie automatycznego odnawiania przez klienta, więc dostęp działa do końca okresu. V2 usuwa tę dwuznaczność. Zwrot przychodzi jako REFUND, a wyłączenie odnawiania przez klienta przychodzi jako DID_CHANGE_RENEWAL_STATUS z podtypem AUTO_RENEW_DISABLED.

Ile kosztuje pozostanie na V1

Apple decyduje o każdym zwrocie w App Store. CONSUMPTION_REQUEST to jedyny moment, w którym Twoje dane o użyciu trafiają do tej decyzji, a Apple prosi o odpowiedź w ciągu 12 godzin. W V1 zwroty za subskrypcje pomijają ten krok.

Oto przykład na poglądowych liczbach. Załóżmy, że Twoja aplikacja sprzedaje miesięczną subskrypcję za $9.99, która obejmuje generowanie obrazów przez AI. Subskrybent wykonuje w miesiącu 400 generacji, a każda kosztuje Cię realne pieniądze za inferencję modelu. Potem prosi Apple o zwrot.

Pozycja kosztówSerwer na V1Serwer na V2
Twoja część płatnościZwracana, jeśli Apple zatwierdziZwracana, jeśli Apple zatwierdzi
Moc obliczeniowa, wywołania API i przechowywanie w tym miesiącuJuż opłacone, nie do odzyskaniaJuż opłacone, nie do odzyskania
Szansa, by pokazać Apple 400 generacjiBrakJeden CONSUMPTION_REQUEST, 12 godzin
Informacja, że Apple odrzuciło zwrotNigdyREFUND_DECLINED
Informacja, że zwrot został cofniętyNigdyREFUND_REVERSED

Płatność, którą tracisz, to Twoja część, a nie cena katalogowa. W pierwszym roku płatnej subskrypcji danego subskrybenta Apple wypłaca 70% ceny subskrypcji, pomniejszonej o należne podatki, a po tym okresie lub w przypadku członków App Store Small Business Program 85%. Rachunek za moc obliczeniową nie maleje razem z nią. Inferencja, wywołania zewnętrznych API i przechowywanie plików zostały opłacone wtedy, gdy klient z nich korzystał.

Dwa brakujące powiadomienia o wyniku też kosztują. Bez REFUND_REVERSED serwer, który odebrał dostęp po zwrocie, nigdy go nie przywraca, gdy Apple cofa zwrot, więc płacący klient zostaje zablokowany i pisze do supportu. Bez REFUND_DECLINED nie odróżnisz zwrotu, który wciąż czeka na decyzję, od takiego, który Apple odrzuciło.

Dłonie dewelopera przekładają kabel sieciowy ze starego portu panelu krosowego do nowego, obok otwartego laptopa

Jak przejść z V1 na V2, nie gubiąc żadnego zwrotu

Przejście na V2 to zmiana po stronie serwera plus jedno ustawienie. Wskazówki samego Apple na forach, od App Store Commerce Engineer z grudnia 2025 roku, wyjaśniają, co dzieje się w dniu przełączenia.

Zbuduj endpoint V2, zanim zmienisz ustawienie

  • Przyjmuj żądanie POST, którego treść zawiera signedPayload. Payloady V2 to JWS podpisane przez Apple, więc zweryfikuj podpis, zanim zaufasz czemukolwiek w środku. App Store Server Library od Apple zrobi to za Ciebie.
  • Przenieś obsługę CANCEL na REFUND, a REFUND_DECLINED i REFUND_REVERSED obsłuż jako nowe przypadki.
  • Odpowiadaj na CONSUMPTION_REQUEST dla subskrypcji przez Send Consumption Information, i tylko wtedy, gdy klient zgodził się na udostępnianie danych Apple. Apple mówi, że bez zgody nie należy odpowiadać.
  • Przy powodzeniu zwracaj HTTP od 200 do 206. Każdy kod 40x lub 50x sprawia, że Apple ponawia próbę.

Zmień ustawienie w App Store Connect

W App Store Connect otwórz swoją aplikację, wybierz Informacje o aplikacji w sekcji Ogólne, znajdź App Store Server Notifications i ustaw Production Server URL na swój endpoint V2 z wybraną opcją Version 2. Jeśli chcesz najpierw przetestować, zrób to samo dla adresu URL sandboxa i użyj Request a Test Notification, aby sprawdzić, czy Twój serwer odpowiada.

Zostaw handler V1 włączony na około trzy dni

Po przełączeniu nowe powiadomienia od razu przychodzą w formacie V2, dla każdej subskrypcji, starej i nowej. Powiadomienia V1, które są już w trakcie ponawiania, nadal przychodzą w formacie V1, dopóki się nie powiodą albo nie wyczerpią prób. Apple szacuje ostatnią możliwą próbę V1 na około 78 godzin, czyli 6 plus 24 plus 48. Zostaw stary handler działający dłużej, a potem go usuń.

Przy okazji zastąp verifyReceipt

verifyReceipt został oznaczony jako przestarzały tego samego dnia. Nadal odpowiada, ale Apple kieruje serwery do App Store Server API. Get Transaction Info zwraca jedną podpisaną transakcję, Get Transaction History zwraca historię klienta, a Get Refund History wyświetla każdy zwrócony zakup klienta. Razem z powiadomieniami V2 pokrywają to, do czego większość serwerów używała paragonów, łącznie z polem cancellation_date, które kiedyś oznaczało zwrot w paragonie.

RefundHalt łączy się z App Store Server Notifications V2 i odpowiada na każdy CONSUMPTION_REQUEST w 12-godzinnym oknie, korzystając z danych o użyciu, które Twoja aplikacja już zapisuje. Jeśli nadal jesteś na V1, przełączenie to krok, który w ogóle to umożliwia.

Często zadawane pytania

Czy App Store Server Notifications V1 zostanie wyłączone?
Jeszcze nie. Apple oznaczyło V1 i verifyReceipt jako przestarzałe 5 czerwca 2023 roku, a oba nadal działają. Apple poinformowało, że daty wyłączenia jeszcze nie ma i że deweloperzy zostaną uprzedzeni z wyprzedzeniem. Do tego czasu V1 nie dostaje nowych funkcji.
Czy w V1 dostaję powiadomienia CONSUMPTION_REQUEST?
Według dokumentacji V1 od Apple tylko dla zakupów konsumpcyjnych. Consumption requests dla automatycznie odnawianych subskrypcji dodano do V2 w kwietniu 2024 roku, a Apple wysyła je przez Twój endpoint V2. Jeśli sprzedajesz subskrypcje i zostajesz na V1, nie możesz odpowiadać na te wnioski o zwrot.
Jak wygląda zwrot za subskrypcję w V1 w porównaniu z V2?
W V1 przychodzi jako CANCEL, często razem z DID_CHANGE_RENEWAL_STATUS. W V2 przychodzi jako REFUND, z polami revocationDate i revocationReason w podpisanej transakcji. V2 wysyła też REFUND_DECLINED, gdy Apple odrzuca zwrot rozpoczęty w Twojej aplikacji, oraz REFUND_REVERSED, gdy Apple cofa przyznany zwrot.
Co się dzieje z powiadomieniami, gdy przełączam się z V1 na V2?
Nowe powiadomienia przychodzą w formacie V2 wkrótce po przełączeniu, dla wszystkich subskrypcji. Powiadomienia V1, które są już ponawiane, nadal przychodzą w formacie V1, dopóki się nie powiodą albo nie wyczerpią prób, co według Apple trwa do około 78 godzin po przełączeniu. Utrzymuj oba handlery przez ten czas.
Czy mogę wrócić do V1 po przejściu na V2?
Tak, przez endpoint Modify an App w App Store Connect API, jak opisuje technote TN3180 od Apple. Apple nazywa to nietypowym przypadkiem i nadal oznacza V1 jako przestarzałe, więc powrót oznacza rezygnację z consumption requests dla subskrypcji i nowszych powiadomień o zwrotach.

Ź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ć.