Bir iade üzerine işlem yapmadan önce App Store sunucu bildirimlerini doğrulayın, çünkü webhook URL'nize herkes istek gönderebilir
Bir iade bildirimi, imzasını kontrol edene kadar yalnızca bir HTTPS isteğidir. App Store sunucu bildirimlerini ve Google Play RTDN mesajlarını nasıl doğrulayacağınızı, her mağazanın neyi imzaladığını ve sahte ya da yanlışlıkla reddedilen bir iadenin size neye mal olduğunu anlatıyoruz.

Önemli noktalar
- Apple, her version 2 App Store sunucu bildirimini bir signedPayload olarak gönderir. Bu, üç Base64URL parçadan oluşan bir JSON Web Signature'dır: bir header, bir payload ve bir signature.
- Bir App Store sunucu bildiriminin JWS header'ı, üç sertifikadan oluşan bir x5c sertifika zinciri taşır: bir imzalama leaf sertifikası, Apple Worldwide Developer Relations uzantısı 1.2.840.113635.100.6.2.1'i taşıyan bir Apple ara sertifikası ve bir Apple kök sertifikası.
- Apple'ın App Store Server Library'si bildirimleri bir SignedDataVerifier ile doğrular. Bu doğrulayıcı sertifika zincirini, bundle ID'yi, ortamı ve production'da appAppleId'yi kontrol eder, ayrıca sertifika iptalini çevrimiçi olarak denetleyebilir.
- Google Play Real-time developer notifications, Google Play tarafından imzalanmaz. Bir push aboneliğinde Pub/Sub, Authorization header'ına imzalı bir OpenID Connect token'ı ekleyebilir ve sunucunuz bu token'ın imzasını, audience ve email claim'lerini kontrol eder.
- Google, bir RTDN'nin yalnızca bir satın alma durumunun değiştiğini söylediğini belirtir. Bu nedenle herhangi bir iade bildirimine verilecek güvenli yanıt, erişimi kaldırmadan önce bunu Google Play Developer API ile teyit etmektir.
- Apple, App Store sunucu bildirimlerini 17.0.0.0/8 alt ağından gönderir, ancak bir IP izin listesi yalnızca uç noktanıza kimin ulaşabileceğini daraltır. Mesajın Apple'dan geldiğini kanıtlayan şey imzadır.
- Gerçek mesajları yanlışlıkla reddeden bir doğrulayıcı, sahteleri kabul eden kadar maliyetlidir, çünkü kaçırdığınız bir CONSUMPTION_REQUEST'in 12 saatlik yanıt süresi, bir Google Play chargeback incelemesinin ise 24 saatlik süresi vardır.
Webhook URL'nizi öğrenen herkes ona bir iade gönderebilir. Her App Store sunucu bildiriminin ve her Google Play Real-time developer notification'ın ardındaki rahatsız edici gerçek budur: siz doğrulayana kadar mesaj, içinde biraz JSON bulunan bir HTTPS POST'tan ibarettir. Sunucunuz bir istek REFUND dediği için bir aboneliği iptal ediyor, kredileri geri alıyor ya da bir hesabı yasaklıyorsa, bu yetkiyi bir curl komutu yazabilen herkese vermişsiniz demektir.
İki mağaza da size bir kontrol yolu sunar. Apple bildirimin kendisini imzalar, bu yüzden App Store sunucu bildirimlerini yalnızca Apple'ın kök sertifikasıyla doğrulayabilirsiniz. Google Play farklı bir yol izler. Mesaj imzalı değildir, ancak Pub/Sub teslimatı imzalı olabilir ve Google zaten her değişikliği kendi API'siyle teyit etmenizi söyler. Aşağıda her birinin neyi kanıtladığını ve iki yönden birinde hata yaptığınızda bunun neye mal olduğunu bulacaksınız.
Her mağaza gerçekte neyi imzalar
| Soru | App Store Server Notifications V2 | Google Play RTDN |
|---|---|---|
| Mesajın kendisi imzalı mı? | Evet, signedPayload bir JWS'dir | Hayır, data alanı base64 ile kodlanmış JSON'dur |
| Göndereni ne kanıtlar | Bir Apple köküne uzanan x5c sertifika zinciri | Push'ta Pub/Sub OIDC token'ı veya kendi kimliği doğrulanmış pull işleminiz |
| İç içe imzalı nesneler | signedTransactionInfo ve signedRenewalInfo, her biri kendi JWS'i | Yok |
| Uygulamanızla eşleşmesi gereken alanlar | bundleId, appAppleId, environment | packageName |
| Kaynak ağ | 17.0.0.0/8, sandbox ve production | Google Cloud Pub/Sub |
| İşlem öncesi teyit | İsteğe bağlı, imzalı veri kaydın kendisidir | Zorunlu, Google Developer API'nin çağrılmasını söyler |
| Taşıma | HTTPS, TLS 1.2 veya üstü | HTTPS push veya istemci kütüphanesiyle pull |
App Store sunucu bildirimleri nasıl doğrulanır
Apple'ın belgeleri signedPayload'u noktalarla ayrılmış, Base64URL ile kodlanmış üç bileşenden oluşan bir dize olarak tanımlar: bir header, bir payload ve bir signature, JSON Web Signature spesifikasyonuna göre imzalanmış. Payload'u çözmek kolaydır. Ona güvenmek ise dört kontrol gerektirir.
- Çözülmüş header'dan x5c dizisini okuyun. Apple sırayı belgeler: önce imzalama anahtarını taşıyan sertifika, ardından bir Apple ara sertifikası, ardından bir Apple kök sertifikası.
- Bu zinciri, Apple'ın PKI sitesinden kendiniz indirdiğiniz bir Apple köküne, pratikte Apple Root CA - G3'e karşı doğrulayın. Mesajın içinde gelen köke asla güvenmeyin, çünkü sahtekâr oraya istediği sertifikayı koyabilir.
- Ara sertifikanın Apple Worldwide Developer Relations uzantısı 1.2.840.113635.100.6.2.1'i taşıdığını teyit edin, ardından JWS imzasını leaf sertifikanın açık anahtarıyla doğrulayın.
- Çözülmüş veriyi uygulamanızla karşılaştırın: bundleId, production'da appAppleId ve environment. Başka bir geliştiricinin uygulamasındaki ya da production uç noktanıza ulaşan bir sandbox satın alımındaki geçerli bir Apple imzası, yine de sizin iadeniz değildir.
Ardından aynısını içerideki için tekrarlayın. data nesnesi signedTransactionInfo ve signedRenewalInfo'yu barındırır ve her biri kendi x5c zinciri olan ayrı bir JWS'dir. Zarfı doğrulayıp işlemi doğrulamadan okuyan bir REFUND işleyicisi, ortada bir açık bırakmıştır.
Kendiniz yazmak yerine Apple'ın kütüphanesini kullanın
Apple, Swift, Java, Python ve Node için App Store Server Library'yi yayımlar. Kütüphanenin SignedDataVerifier'ı kök sertifikalarınızı, bir çevrimiçi kontrol bayrağını, ortamı, bundle ID'nizi ve production için appAppleId'nizi alır. Node kaynak kodu neyi zorunlu kıldığını gösterir: zincirde tam olarak üç sertifika, Apple leaf uzantısı 1.2.840.113635.100.6.11.1 ve ara sertifika uzantısı, sertifika geçerlilik tarihleri ve eşleşen bundle ID, app ID ve ortam. Çevrimiçi kontroller açıkken, leaf ve ara sertifikaların iptal edilip edilmediğini OCSP yanıtlayıcısına da sorar.

IP izin listesi yeterli mi?
Hayır. Apple, sunucunuzun bir izin listesine ihtiyacı varsa 17.0.0.0/8 alt ağını eklemeniz gerektiğini ve bunun hem sandbox hem production için geçerli olduğunu söyler. Bu, gürültüyü azaltır. Bir mesajın gerçek olduğunu kanıtlamaz ve Apple'ın ağı sizin haberiniz olmadan değiştiği anda bozulur. Gerçek kapı olarak imza kontrolünü koruyun.
Google Play iade bildirimleri nasıl doğrulanır
Google Play, RTDN mesajlarını size ait bir Pub/Sub konusuna yayımlar ve bu konuda Pub/Sub Publisher rolüne yalnızca google-play-developer-notifications@system.gserviceaccount.com hizmet hesabı sahip olmalıdır. Aboneliğiniz mesajları daha sonra iki yoldan biriyle teslim eder ve her birinin kendi kanıtı vardır.
- Pull aboneliği: sunucunuz Pub/Sub'a kimliği doğrulanmış bir bağlantı açar ve mesajları çeker. Herkese açık bir uç nokta yoktur, dolayısıyla bir yabancının istek gönderebileceği bir şey de yoktur.
- Kimlik doğrulaması açık push aboneliği: Pub/Sub bir JSON Web Token imzalar ve onu Authorization header'ında Bearer token olarak gönderir. Google'ın kılavuzu, token'ın imzasını doğrulamanızı ve email ile audience claim'lerinin yapılandırdığınız değerlerle eşleştiğini kontrol etmenizi söyler, örnek kodu da email_verified değerinin true olmasını şart koşar. Token en fazla bir saat eski olabilir.
- Kimlik doğrulaması olmayan push aboneliği: URL'ye ulaşabilen her şey RTDN biçiminde bir mesaj gönderebilir.
Google neden API ile teyit etmenizi istiyor
Kimliği kusursuz biçimde doğrulanmış bir RTDN bile hikâyenin tamamını taşımaz. Google'ın kurulum kılavuzu, bu bildirimlerin yalnızca bir satın alma durumunun değiştiğini söylediğini ve tam durumu almak için Google Play Developer API'yi çağırmanız gerektiğini açıkça belirtir. Bir voidedPurchaseNotification için bu, herhangi bir şeyi kaldırmadan önce satın alımı Voided Purchases API'de bulmak ya da güncel durumunu çekmek anlamına gelir. API çağrısı kendi hizmet hesabınızla kimlik doğrulamasından geçer, bu yüzden verdiği yanıtı bir sahtekâr taklit edemez.
Sahte veya reddedilen bir iadenin parasal maliyeti
Güvendiğiniz sahte bir iade bildirimi size ödeme yapan bir müşteriye mal olur. Parası hâlâ sizde olan birini dışarıda bırakırsınız, o kişi bir destek talebi açar ve bazıları mağazaya gidip sisteminizin zaten vermiş gibi yaptığı iadeyi ister. Sahte bir satın alma veya yenileme ise ters yönde maliyet çıkarır: hiç var olmamış bir gelir karşılığında GPU hesaplama gücü, ücretli üçüncü taraf API çağrıları, depolama ve içerik üreticisi ödemeleri sağlarsınız.
Ters yöndeki hata daha sessizdir ve çoğu zaman daha büyüktür. Yanlış bir appAppleId, production'da kalmış bir sandbox ayarı ya da güncelliğini yitirmiş bir kök sertifika yüzünden gerçek mesajları reddeden bir doğrulayıcı, kanıtlarınızın önemli olduğu iki iade akışını da düşürür. Apple, bir CONSUMPTION_REQUEST'ten sonraki 12 saat içinde tüketim verisi ister. Google, orders.reviewrefund üzerinden bir chargeback incelemesine yanıt vermeniz için 24 saat tanır ve August 3, 2026 sonrasında verilen siparişlerde kaybedilen bir Google Play chargeback'i size, Play'in hizmet ücreti düşülmüş satın alma fiyatına ek olarak alıcının bankasının kestiği ücrete mal olur.
| Hata | Ne olur | Maliyeti |
|---|---|---|
| Sahte REFUND kabul edildi | Ödeme yapan bir müşteri erişimini kaybeder | Destek zamanı ve kendi davet ettiğiniz gerçek bir iade talebi |
| Sahte satın alma kabul edildi | Ücretli özelliklere ücretsiz erişim | Gelir olmadan hesaplama, API çağrıları, depolama ve ödemeler |
| Gerçek CONSUMPTION_REQUEST reddedildi | Apple verileriniz olmadan karar verir | Satış ve onu sunmak için zaten harcanan her şey |
| Gerçek chargeback incelemesi reddedildi | Google kanıtlarınız olmadan karar verir | August 3, 2026 sonrasındaki siparişlerde satın alma fiyatı ve banka ücretleri |
Bir doğrulama hatasının süreyi yutmasına izin vermeyin
- Ham isteği doğrulamadan önce saklayın, böylece reddedilen bir mesaj hiçbir zaman gerçekten kaybolmaz.
- Her doğrulama hatasında uyarı verin. Tek bir sahte mesaj gürültüdür. Tüm mesajların aynı anda başarısız olması ise sizin kendi hatanızdır.
- Apple'da reddettiklerinizi yeniden oynatabilirsiniz. Get Notification History, son 180 güne ait orijinal signedPayload'u döndürür, bu yüzden doğrulayıcıyı düzeltin ve saklanan ya da kurtarılan payload'ları yeniden ondan geçirin.
- Google'da bekleyen bir chargeback incelemesi yalnızca kendi bildiriminde yaşar, dolayısıyla yanlış yapılandırılmış bir push audience kaçırılmış bir inceleme demektir. Her değişiklikten sonra Play Console'daki Send Test Message ile test edin.
RefundHalt her iki mağazanın bildirimlerini doğrular, herhangi bir şey değişmeden önce iadeleri mağaza API'leriyle teyit eder ve CONSUMPTION_REQUEST ile chargeback incelemelerini süreleri içinde yanıtlar. Böylece sahte bir mesaj size bir müşteriye mal olamaz, gerçek bir mesaj da gözden kaçamaz.
Sık sorulan sorular
- Bir App Store sunucu bildirimini nasıl doğrularım?
- signedPayload'u bir JSON Web Signature olarak doğrulayın. Header'ından x5c sertifika zincirini okuyun, Apple'ın PKI sitesinden indirdiğiniz bir Apple kök sertifikasına karşı doğrulayın, imzayı leaf sertifikanın anahtarıyla doğrulayın, ardından bundleId, appAppleId ve environment değerlerinin uygulamanızla eşleştiğini kontrol edin. Apple'ın App Store Server Library'si bunların hepsini SignedDataVerifier içinde yapar.
- App Store sunucu bildirimlerini doğrulamak için hangi anahtarı kullanırım?
- App Store Connect'ten bir anahtara ihtiyacınız yoktur. Açık anahtar, JWS header'ındaki x5c zincirinin ilk sertifikasındadır ve ona yalnızca zinciri kendiniz edindiğiniz bir Apple kök sertifikasına kadar doğruladıktan sonra güvenirsiniz. In-App Purchase anahtarınız Apple'ın API'lerini çağırmak içindir, bildirimleri kontrol etmek için değil.
- Google Play Real-time developer notifications imzalı mı?
- Hayır, Google Play RTDN mesajının kendisini imzalamaz. Kimlik doğrulamalı bir push aboneliğinde Pub/Sub, Authorization header'ında sizin doğruladığınız imzalı bir OpenID Connect token'ı gönderir ve Google, satın alımın tam durumunu almak için her bildirimden sonra Google Play Developer API'yi çağırmanızı söyler.
- Bir bildirim doğrulamadan geçemediğinde sunucum hata döndürmeli mi?
- Önce ham isteği saklayın, sonra karar verin. Apple, 40x veya 50x yanıtından sonra bir version 2 bildirimini önceki denemeden 1, 12, 24, 48 ve 72 saat sonra yeniden dener. Hata sizin kendi yapılandırmanızdan kaynaklanıyorsa, Get Notification History orijinal signedPayload'u 180 gün boyunca kurtarmanıza ve düzelttikten sonra yeniden doğrulamanıza olanak tanır.
- Yalnızca Apple'ın IP aralığına izin veriyorsam bildirimleri yine de doğrulamam gerekir mi?
- Evet. Apple, izin listesi olan sunuculardan 17.0.0.0/8 alt ağını kabul etmelerini ister. Bu, kimin bağlanabileceğini sınırlar ancak bir mesajın gerçek olduğunu kanıtlamaz. Bir bildirimi Apple'a ve uygulamanıza bağlayan kontrol JWS imzasıdır.
Kaynaklar ve ek okumalar
- Apple Developer: signedPayload
- Apple Developer: JWSDecodedHeader
- Apple Developer: Enabling App Store Server Notifications
- Apple Developer: Responding to App Store Server Notifications
- Apple on GitHub: App Store Server Library (Node)
- Android Developers: Get ready (Real-time developer notifications setup)
- Google Cloud: Authentication for push subscriptions
- Play Console Help: Updates to refund protection and chargeback cost responsibility
RefundHalt
App Store ve Google Play için geri ödeme otomatik pilotu
Okumaya devam edin
Aşırı iade talepleri size iadelerin kendisinden daha pahalıya patlayabilir, çünkü iki uygulama mağazası da bunları bir kalite sinyali olarak görür
Apple'ın 5.6.4 numaralı yönergesi aşırı iade taleplerini bir uygulamanın kalite standartlarını karşılamadığının işareti olarak sayar. Google'ın Dağıtım Sözleşmesi de yeni geliştiricilerin uygulamalarını iade oranlarına göre kaldırma yetkisi verir. Her mağazanın ne dediğini, kaldırılmanın neye mal olduğunu ve riskten nasıl uzak durulacağını anlatıyoruz.
Kaçırılan iade bildirimleri, itiraz edebildiğiniz tek iadeleri size kaybettirebilir. Zamanında bakarsanız iki mağaza da onları geri almanıza izin verir
Sunucunuz bir iade bildirimini kaçırdığında, kanıtınızı isteyen iki iade akışı siz olmadan kapanır. Apple ve Google Play'in nasıl yeniden denediğini, kaçırılan iade bildirimlerini ne kadar geriye kadar kurtarabileceğinizi ve kurtarmadaki boşlukların nerede olduğunu anlatıyoruz.