Przegapione powiadomienia o zwrotach mogą kosztować cię jedyne zwroty, które wolno ci zakwestionować. Oba sklepy pozwalają je odzyskać, jeśli sprawdzisz na czas
Gdy serwer przegapi powiadomienie o zwrocie, dwa procesy zwrotu, w których sklep prosi o twoje dowody, zamykają się bez ciebie. Oto jak Apple i Google Play ponawiają dostawę, jak daleko wstecz można odzyskać przegapione powiadomienia o zwrotach i gdzie są luki.

Najważniejsze wnioski
- Apple ponawia nieudaną dostawę App Store Server Notifications V2 pięć razy, po 1, 12, 24, 48 i 72 godzinach od poprzedniej próby. Druga ponowna próba przychodzi więc około 13 godzin po pierwszej próbie.
- Apple prosi deweloperów o odpowiedź na CONSUMPTION_REQUEST w ciągu 12 godzin od jego otrzymania. Serwer, który przegapi pierwszą dostawę i ponowienie po godzinie, może zobaczyć żądanie dopiero wtedy, gdy to okno prawdopodobnie już minęło.
- Endpoint Apple Get Notification History zwraca powiadomienia V2 z ostatnich 180 dni w środowisku produkcyjnym, po 20 rekordów na stronę. Flaga onlyFailures ogranicza wyniki do powiadomień, które nigdy nie dotarły do twojego serwera, oraz tych, które są jeszcze ponawiane.
- Google Play dostarcza weryfikacje obciążeń zwrotnych wyłącznie przez PendingRefundReviewNotification, a pendingRefundToken potrzebny do wywołania orders.reviewrefund w ciągu 24 godzin przychodzi właśnie w tym powiadomieniu. Google nie dokumentuje osobnego API, które listowałoby oczekujące weryfikacje.
- Google Cloud Pub/Sub domyślnie przechowuje niepotwierdzone wiadomości przez 7 dni, maksymalnie 31 dni. Subskrypcję bez aktywności subskrybenta usuwa po 31 dniach, chyba że zmienisz jej okres wygaśnięcia.
- Voided Purchases API w Google Play odzyskuje zwroty, cofnięcia i obciążenia zwrotne z ostatnich 30 dni, z limitem 6000 zapytań dziennie i 30 zapytań w każdym okresie 30 sekund. Nie odzyska jednak weryfikacji obciążenia zwrotnego, na którą nigdy nie odpowiedziałeś.
- Sandbox Apple wysyła każde powiadomienie raz, bez ponowień. Procedura odzyskiwania, która działała tylko w sandboksie, nigdy nie została sprawdzona z prawdziwym harmonogramem ponowień Apple.
Przegapione powiadomienia o zwrotach to cichy sposób, w jaki deweloper traci jedyne dwie decyzje o zwrocie, w których ma coś do powiedzenia. CONSUMPTION_REQUEST od Apple i weryfikacja obciążenia zwrotnego w Google Play zaczynają się od powiadomienia i obie mają krótki termin: 12 godzin w Apple, 24 godziny w Google. Jeśli w chwili nadejścia wiadomości twój serwer nie działa, jest wolny albo źle skonfigurowany, sklep nie czeka. Decyduje na podstawie tego, co już ma.
Dobra wiadomość jest taka, że żaden sklep nie wyrzuca wiadomości po pierwszej nieudanej próbie. Apple ponawia dostawę i prowadzi 180-dniową historię, którą możesz odpytać. Google publikuje przez Pub/Sub, który trzyma niepotwierdzone wiadomości przez kilka dni. Zła wiadomość: harmonogram ponowień nie pasuje do okien na odpowiedź, a jeden z dwóch procesów w ogóle nie ma API do odzyskiwania.
Jak każdy sklep dostarcza powiadomienia o zwrotach
Apple wysyła App Store Server Notifications bezpośrednio na adres HTTPS, który ustawiasz w App Store Connect. Google nie wywołuje twojego serwera bezpośrednio. Publikuje powiadomienia dla deweloperów w czasie rzeczywistym w temacie Google Cloud Pub/Sub, a twoja subskrypcja tego tematu albo wypycha je na twój endpoint, albo czeka, aż serwer sam je pobierze.
| Pytanie | App Store | Google Play |
|---|---|---|
| Kanał dostawy | HTTPS POST na twój adres URL | Temat Cloud Pub/Sub, push lub pull |
| Co liczy się jako sukces | HTTP od 200 do 206 | Potwierdzenie wiadomości Pub/Sub albo kod sukcesu na endpoincie push |
| Ponowienia | 5 dla V2, po 1, 12, 24, 48 i 72 godzinach od poprzedniej próby | Pub/Sub dostarcza ponownie do potwierdzenia lub do końca okresu przechowywania |
| Jak długo przetrwa przegapiona wiadomość | 180 dni w Get Notification History | Domyślnie 7 dni w subskrypcji, do 31 dni |
| Zwrot, przy którym sklep prosi o twoje dowody | CONSUMPTION_REQUEST, odpowiedź w ciągu 12 godzin | PendingRefundReviewNotification, odpowiedź w ciągu 24 godzin |
| Zapasowe pobieranie przyznanych zwrotów | Get Notification History, Get Refund History | Voided Purchases API, ostatnie 30 dni |
| Zachowanie w sandboksie lub teście | Jedna próba, bez ponowień | Wysłanie wiadomości testowej z Play Console |
Co Apple uznaje za niepowodzenie
Dokumentacja Apple jest konkretna. Zwróć dowolny status od 200 do 206 i dostawa jest zakończona. Zwróć 40x lub 50x, a Apple ponowi próbę. Każdy inny kod Apple też uznaje za nieudany. Każda próba jest zapisywana z polem sendAttemptResult, a jego wartości wyglądają jak lista prawdziwych awarii: TIMED_OUT, TLS_ISSUE, CIRCULAR_REDIRECT, NO_RESPONSE, PREMATURE_CLOSE, UNSUCCESSFUL_HTTP_RESPONSE_CODE i kilka innych. Przy TIMED_OUT Apple radzi sprawdzić, czy serwer nie przetwarza wiadomości synchronicznie.
Co Google uznaje za niepowodzenie
Przy subskrypcji push potwierdzeniem jest kod sukcesu z twojego endpointu. Przy subskrypcji pull serwer musi potwierdzić każdą pobraną wiadomość, inaczej Pub/Sub dostarczy ją ponownie. Domyślny termin potwierdzenia to 10 sekund, maksymalny 600 sekund. Przewodnik Google po RTDN dodaje regułę, którą warto powtórzyć: powiadomienie mówi tylko, że coś się zmieniło. Pełny stan zakupu nadal pobierasz z Google Play Developer API.
Dlaczego harmonogram ponowień Apple nie pasuje do 12-godzinnego okna
Odstępy między ponowieniami Apple liczy od poprzedniej próby, a nie od pierwszej. Po zsumowaniu wychodzi taka oś czasu dla jednego powiadomienia V2, którego serwer stale nie odbiera.
| Próba | Odstęp od poprzedniej próby | Godziny od pierwszej próby |
|---|---|---|
| Pierwsza dostawa | Brak | 0 |
| Ponowienie 1 | 1 godzina | 1 |
| Ponowienie 2 | 12 godzin | 13 |
| Ponowienie 3 | 24 godziny | 37 |
| Ponowienie 4 | 48 godzin | 85 |
| Ponowienie 5 | 72 godziny | 157 |
Apple każe odpowiedzieć w ciągu 12 godzin od otrzymania CONSUMPTION_REQUEST. Jeśli serwer nie działa przy pierwszej dostawie i przy ponowieniu godzinę później, następna próba przychodzi 13 godzin po pierwszej. Apple nie mówi, czy żądanie odebrane dopiero przy ponowieniu dostaje nowe 12 godzin. Ostrożna interpretacja zakłada, że zegar startuje przy pierwszej próbie. Same ponowienia nie uratują więc żądania przegapionego o ponad godzinę.
Czy Apple ponawia próbę po HTTP 400?
Według dokumentacji tak. Apple wymienia 40x i 50x jako kody, które uruchamiają ponowienie. W marcu 2026 roku deweloper napisał na forach Apple, że ponowienia po odpowiedziach 400 chyba ustały, a później, że dostawy wróciły po dniu lub dwóch. Apple poprosiło o zgłoszenie przez Feedback Assistant. Traktuj udokumentowane zachowanie jako regułę, a własny monitoring jako dowód.
Odzyskiwanie przegapionych powiadomień App Store przez Get Notification History
Get Notification History zwraca powiadomienia w wersji 2, które Apple próbowało wysłać na twój serwer w wybranym przez ciebie przedziale czasu. Każdy rekord zawiera pełny podpisany ładunek, więc możesz przekazać go do tego samego handlera co powiadomienie na żywo. Każdy rekord zawiera też tablicę sendAttempts z maksymalnie sześcioma wpisami, jednym dla pierwszej próby i po jednym dla każdego z pięciu ponowień.
- startDate i endDate są wymagane, a startDate musi mieścić się w ostatnich 180 dniach w produkcji lub w ostatnich 30 dniach w sandboksie.
- Ustaw onlyFailures na true, aby dostać tylko powiadomienia, które nie dotarły do serwera, oraz te, które Apple wciąż ponawia.
- Filtruj po jednym notificationType, na przykład CONSUMPTION_REQUEST lub REFUND, albo po transactionId jednego klienta, ale nie po obu w jednym żądaniu.
- Każde wywołanie zwraca do 20 rekordów. Wywołuj dalej z paginationToken, dopóki hasMore ma wartość true, i za każdym razem wysyłaj tę samą treść żądania.
Jedno zastrzeżenie jest ważne przy zwrotach. Apple podaje, że rekordy historii pokazują stan zakupu z chwili pierwszego wysłania powiadomienia, a nie obecny. Odzyskany REFUND to więc fakt z przeszłości. Zanim odbierzesz dostęp, sprawdź bieżący stan przez endpointy transakcji lub statusu subskrypcji.
Powiadomień V1 nie da się tak odzyskać
Get Notification History obejmuje tylko wersję 2. Apple ponawia powiadomienia V1 trzy razy, po 6, 24 i 48 godzinach od poprzedniej próby. Jeśli wszystkie się nie udadzą, nie ma historii do odtworzenia. To kolejny powód, by przenieść na V2 każdą aplikację, która wciąż korzysta z V1.
Odzyskiwanie przegapionych powiadomień o zwrotach z Google Play
Siatką bezpieczeństwa Google jest sam Pub/Sub. Dopóki subskrypcja istnieje, wiadomość, której nikt nie potwierdził, zostaje w niej przez okres przechowywania: domyślnie 7 dni, a po zwiększeniu do 31 dni. Gdy endpoint wróci, dostawa zostaje wznowiona. Dwa ustawienia mogą to po cichu zniweczyć.
- Temat dead-letter przenosi wiadomość poza subskrypcję po ustalonej liczbie nieudanych prób dostawy. Domyślnie jest to 5, a przy domyślnej polityce natychmiastowego ponownego dostarczania pięć prób może minąć bardzo szybko. Jeśli go używasz, pilnuj tematu dead-letter jak drugiej skrzynki odbiorczej.
- Subskrypcja bez aktywności subskrybenta, czyli bez otwartych połączeń, aktywnych pobrań czy udanych pushy, domyślnie wygasa po 31 dniach. Endpoint, który nie działa przez miesiąc, może stracić samą subskrypcję razem ze wszystkim, co w niej czeka.
Unieważnione zakupy mają 30-dniową kopię zapasową
Dla zwrotów, które już nastąpiły, zapasowym źródłem pobierania jest Voided Purchases API. Wyświetla unieważnione zakupy z ostatnich 30 dni, do 1000 na stronę, z limitem 6000 zapytań dziennie i 30 zapytań w każdym okresie 30 sekund dla każdej aplikacji. Przekaż type 1, aby oprócz produktów jednorazowych uwzględnić subskrypcje. Codzienne uruchomienie wyłapie każdy zwrot, który zgubił twój potok powiadomień, a uprawnienia i dane o przychodach pozostaną rzetelne.
Weryfikacje obciążeń zwrotnych jej nie mają
PendingRefundReviewNotification działa inaczej. Zawiera pendingRefundToken, który musisz przekazać do orders.reviewrefund, a od otrzymania masz 24 godziny na wysłanie preferencji co do zwrotu i dowodów użycia. Google zapisuje pierwsze wywołanie i ignoruje kolejne. Dokumentacja Google nie opisuje żadnego endpointu, który listowałby oczekujące weryfikacje. Jeśli ta wiadomość Pub/Sub przepadnie, twoje dowody w sprawie tego obciążenia zwrotnego przepadną razem z nią.
Ile kosztuje przegapione powiadomienie o zwrocie
Przegapione powiadomienie o zwrocie, który jest już ostateczny, kosztuje cię pracę księgową. Znajdziesz je później w Voided Purchases API lub w Get Notification History, odbierzesz dostęp, jeśli wymaga tego twoja polityka, a raporty się wyrównają. Irytujące, ale tanie.
Przegapione powiadomienie w jednym z dwóch procesów, które można zakwestionować, kosztuje prawdziwe pieniądze, bo sklep decyduje bez twoich dowodów. W Apple decyzja o zwrocie zapada bez twoich danych o zużyciu. W Google Play przy zamówieniach złożonych po 3 sierpnia 2026 roku przegrane obciążenie zwrotne kosztuje cię cenę zakupu pomniejszoną o opłatę serwisową Play oraz opłatę za obciążenie zwrotne naliczoną przez bank kupującego. Google pokrywa tylko własną opłatę serwisową.
A pieniądze wydane na dostarczenie zakupu zniknęły, zanim spór się zaczął.
- Moc obliczeniowa: czas GPU i serwerów za każdym generowaniem, renderem lub odpowiedzią modelu, z których kupujący już skorzystał.
- Wywołania API: zapytania do zewnętrznych usług rozliczone w chwili wysłania, często za każde wywołanie.
- Przechowywanie: pliki i multimedia utworzone przez kupującego, wciąż na twoim rachunku za hosting.
- Wypłaty: udziały w przychodach już wypłacone twórcom, afiliantom lub partnerom z tej sprzedaży.
Nic z tego nie wraca, gdy zwrot przejdzie. Dowody wysłane w ciągu tych 12 lub 24 godzin to twoja jedyna dźwignia, a przegapione powiadomienie ci ją odbiera.
Procedura odzyskiwania, która się sprawdza
- Najpierw potwierdzaj. Zapisz surowy ładunek, zwróć kod sukcesu, a potem przetwarzaj go w kolejce.
- Co kilka minut odpytuj Get Notification History Apple z onlyFailures o CONSUMPTION_REQUEST, aby awaria kosztowała cię tylko minuty z 12-godzinnego okna.
- Codziennie uruchamiaj przegląd Get Notification History z onlyFailures za ostatnie kilka dni dla wszystkich typów i odtwarzaj to, co znajdziesz.
- Codziennie wywołuj Voided Purchases API z type 1 dla każdej aplikacji w Google Play i porównuj wynik ze zwrotami, które już zapisałeś.
- W Pub/Sub utrzymuj przechowywanie wiadomości na poziomie co najmniej 7 dni, ustaw alerty na temat dead-letter, jeśli go masz, oraz na narastanie niedostarczonych wiadomości.
- Przetestuj całą ścieżkę także w produkcji. Sandbox Apple wysyła każde powiadomienie raz, bez ponowień, a Request a Test Notification razem z Get Test Notification Status pokazują dokładnie, jak odpowiedział twój serwer.

RefundHalt odbiera za ciebie powiadomienia z obu sklepów i automatycznie odpowiada na CONSUMPTION_REQUEST oraz weryfikacje obciążeń zwrotnych w wyznaczonych terminach. Nie musisz więc pilnować zegara.
Często zadawane pytania
- Jak długo Apple ponawia nieudane powiadomienie serwera App Store?
- W wersji 2 około sześciu i pół dnia. Apple ponawia pięć razy, po 1, 12, 24, 48 i 72 godzinach od poprzedniej próby, więc ostatnie ponowienie przychodzi 157 godzin po pierwszej dostawie. Powiadomienia w wersji 1 są ponawiane trzy razy, po 6, 24 i 48 godzinach od poprzedniej próby.
- Jak daleko wstecz mogę odzyskać przegapione powiadomienia serwera App Store?
- W produkcji 180 dni. Endpoint Apple Get Notification History zwraca powiadomienia w wersji 2 z ostatnich 180 dni, a w sandboksie z ostatnich 30 dni, po 20 rekordów na wywołanie. Flaga onlyFailures ogranicza wyniki do powiadomień, które nigdy nie dotarły do twojego serwera.
- Czy Apple ponawia powiadomienie, gdy mój serwer zwraca HTTP 400?
- Według dokumentacji Apple tak. Apple ponawia próbę, gdy serwer zwraca status 40x lub 50x, a kody od 200 do 206 uznaje za sukces. Każdy inny status również liczy się jako niepowodzenie.
- Czy mogę odzyskać przegapioną weryfikację obciążenia zwrotnego w Google Play?
- Tylko dopóki wiadomość Pub/Sub nadal istnieje. pendingRefundToken potrzebny do orders.reviewrefund przychodzi w PendingRefundReviewNotification, a Google nie dokumentuje API, które listowałoby oczekujące weryfikacje. Niepotwierdzone wiadomości w subskrypcji, domyślnie przechowywane przez 7 dni, są więc twoją jedyną kopią.
- Jak znaleźć zwroty w Google Play, które przegapił mój serwer?
- Wywołaj Voided Purchases API. Zwraca unieważnione zakupy z ostatnich 30 dni, w tym zwroty, cofnięcia i obciążenia zwrotne, do 1000 wyników na stronę, z limitem 6000 zapytań dziennie na aplikację. Przekaż type 1, aby uwzględnić subskrypcje.
Źródła i materiały dodatkowe
- Apple Developer: Responding to App Store Server Notifications
- Apple Developer: Get Notification History
- Apple Developer: NotificationHistoryRequest
- Apple Developer: Send Consumption Information
- Android Developers: Real-time developer notifications reference
- Android Developers: Help Google dispute chargebacks
- Google Play Developer API: Voided Purchases API
- Google Cloud: Pub/Sub subscription properties
- Play Console Help: Updates to refund protection and chargeback cost responsibility
RefundHalt
Autopilot zwrotów dla App Store i Google Play
Czytaj dalej
Nadmierne prośby o zwrot mogą kosztować więcej niż same zwroty, bo oba sklepy z aplikacjami traktują je jako sygnał jakości
Wytyczna 5.6.4 Apple wprost wskazuje nadmierne prośby o zwrot jako oznakę, że aplikacja nie spełnia standardów jakości, a umowa dystrybucyjna Google pozwala usuwać aplikacje nowych deweloperów z powodu wskaźnika zwrotów. Oto co piszą oba sklepy, ile kosztuje usunięcie i jak trzymać się z dala od kłopotów.
Weryfikuj powiadomienia serwera App Store, zanim zareagujesz na zwrot, bo każdy może wysłać żądanie na Twój adres webhooka
Powiadomienie o zwrocie to tylko żądanie HTTPS, dopóki nie sprawdzisz jego podpisu. Oto jak weryfikować powiadomienia serwera App Store i wiadomości RTDN z Google Play, co podpisuje każdy ze sklepów i ile kosztuje Cię sfałszowany lub błędnie odrzucony zwrot.