StoreKit 2'de iade tespiti işlemdeki tek bir özelliğe iner, o da revocationDate
Apple müşterilerinizden birine iade yaptığında, iade sunucu göreviniz çalışmadan önce zaten uygulamanızın içinde, işlemin revocationDate özelliğinde durmaktadır. İşte StoreKit 2 iade tespitinin cihazda nerede ortaya çıktığı, revocationDate ve revocationReason'ın size ne söylediği ve neden istemcinin hız için, sunucunun gerçek için olduğu.

Önemli noktalar
- StoreKit 2'de iade edilmiş bir satın alma, Transaction'ında nil olmayan bir revocationDate taşır, böylece uygulamanız sunucunuzu çağırmadan iadeyi kendi başına tespit edebilir.
- revocationDate, App Store bir işleme iade yaptığında veya bir müşteri onu Family Sharing üzerinden kaybettiğinde ayarlanır, bu yüzden nil olmayan bir tarih her zaman iade anlamına gelmez.
- revocationReason nedenini söyler: developerIssue müşterinin uygulamanızdaki bir sorunu belirttiği anlamına gelir ve other kalan tüm iade nedenlerini kapsar.
- Transaction.currentEntitlements iade edilmiş ve iptal edilmiş satın almaları zaten hariç tutar, bu yüzden erişim için en temiz istemci taraflı kontrol, bir ürünün orada hâlâ görünüp görünmediğidir.
- Transaction.updates, uygulamanız kapalıyken gerçekleşen bir iadeyi yalnızca başlangıçta dinlemeye başlarsanız iletir, bu yüzden eksik bir Task kaçırılmış bir iade demektir.
- İstemci taraflı tespit yalnızca uygulama açıkken tetiklenir, bu yüzden App Store Server Notifications V2 REFUND, iade edilmiş bir kullanıcıya hizmet vermek için ödeme yapmanızı durduran yetkili sinyal olarak kalır.
- Bir iade tersine çevrilebilir ve çevrildiğinde, iptal alanları işlemden kaldırılır ve kestiğiniz erişimi geri yüklemeniz beklenir.
Çoğu uygulama bir Apple iadesini sunucusundan, bir App Store Server Notification aracılığıyla öğrenir ve aynı iadenin zaten uygulamanın içinde durduğunu fark etmez. İşlemin içinde, revocationDate adlı bir özelliktedir ve onu okumak, uygulamanızın bir arka uç görevini beklemek yerine, iade edilmiş bir müşterinin erişimini bir sonraki açılışta kesmesini sağlar. StoreKit 2 iade tespiti, çoğu ekibin atladığı istemci taraflı bir sinyaldir. İşte bir iadenin cihazda tam olarak nerede ortaya çıktığı, size ne söylediği, ne söylemediği ve neden sunucu bildirimlerinizin yerine değil, yanında durması gerektiği.
Bir iade StoreKit 2'nin içinde nerede görünür
StoreKit 2 size işlemleri imzalı değerler olarak verir ve bir iade işlemi silmez. Onu işaretler. Transaction üzerindeki iki özellik bu işareti taşır ve ikisi de sağlıklı bir satın almanın tüm ömrü boyunca nil kalır. Biri nil olmadığında, App Store satın almayı geri almıştır.
revocationDate, değişen alandır
revocationDate, isteğe bağlı bir Date'tir. Apple'ın kendi açıklaması nettir: App Store'un işleme iade yaptığı veya onu Family Sharing'den iptal ettiği tarihtir. Hâlâ geçerli bir satın alma için nil'dir. Bir iade işlendiği anda, o iadenin zaman damgasını tutar. O tek kontrol, revocationDate nil değil mi, istemci taraflı iade tespitinin tamamıdır. Geri kalan her şey onun üzerine yığılmış inceliktir.
revocationReason Apple'ın neden geri çektiğini söyler
revocationReason tarihin yanında durur ve nedeni açıklar. StoreKit ona iadeler için önemli olan iki değer verir. developerIssue, müşterinin Apple'a iadenin uygulamanızdaki gerçek veya algılanan bir sorun nedeniyle olduğunu söylediği anlamına gelir. other kalan her nedeni kapsar. Üçüncü bir değer, upgradedToBundle, hiç iade değildir; App Store'un müşteri bir abonelik paketine geçtiği için iptal ettiği bir işlemi işaret eder. Harekete geçmeden önce nedeni okuyun, çünkü saymaya değer olan developerIssue'dur: bir yığını, ürününüzün nerede bozulduğunu size söyleyen kendi ürününüzdür.
| Özellik | Tür | nil olmayan bir değer ne anlama gelir |
|---|---|---|
revocationDate | Date? | App Store bu işleme iade yaptı veya onu bu tarihte Family Sharing üzerinden iptal etti |
revocationReason developerIssue ise | neden | Müşteri uygulamanızdaki gerçek veya algılanan bir sorunu belirtti |
revocationReason other ise | neden | İade, Apple'ın ayrıntılandırmadığı başka bir nedenle gerçekleşti |
revocationReason upgradedToBundle ise | neden | İade değil; müşteri bir abonelik paketine geçtiği için işlem iptal edildi |
currentEntitlements iade edilmiş bir satın almayı zaten düşürür
İptal alanlarını her zaman kendiniz okumak zorunda değilsiniz. Transaction.currentEntitlements, bir müşterinin şu anda hâlâ hak sahibi olduğu satın almaların dizisidir ve Apple onu, onurlandırmamanız gerekenleri dışarıda bırakacak şekilde oluşturur. App Store'un iade ettiği veya iptal ettiği bir ürün onda görünmez. Süresi dolmuş abonelikler veya bitirildikleri anda yok olan tüketilebilirler de görünmez.
Bu, currentEntitlements'i erişim için en temiz kontrol yapar. Ona müşterinin neye sahip olduğunu sorun, tam olarak onu verin ve bir iade, tek bir revocationDate kontrolü olmadan hakkı sizin için kaldırır. İptal alanları, olayı kaydetmek veya ona tepki vermek için ayrıntıyı, tarihi ve nedeni istediğinizde işe yarar. Hak listesi, ışıkları açık tutup tutmama gibi basit soru içindir.
StoreKit 2 iade tespiti pratikte, başlangıçtan ve uygulama çalışırken
Uygulamanızın cihazda bir iadeyi yakalayabileceği iki an vardır ve farklı kod gerektirirler. Biri, uygulama açıkken ve bir iade canlı olarak veya başka bir cihazda gerçekleşirken. Diğeri, başlangıçta, kapalıyken değişen her şeyi yakalarken. İkincisini kaçırın ve StoreKit 2 iade tespitinizde tam olarak çoğu iadenin düştüğü yerde bir delik olur, çünkü müşteriler bir iade isterken uygulamanız nadiren açıktır.
Başlangıçta dinlemeye başlayın yoksa kapalıyken gerçekleşen iadeleri kaçırırsınız
Transaction.updates, sistem bir işlemi uygulamanızın dışında veya başka bir cihazda oluşturduğunda veya güncellediğinde, iade dahil, bir işlem yayan asenkron dizidir. Apple'ın talimatı açıktır: uygulamanız başlar başlamaz onu yineleyen bir Task başlatın, yoksa yalnızca başlangıçta bir kez ilettiği işlemleri kaçırabilirsiniz. Gece gelen bir iade, uygulama bir sonraki açılışında updates üzerinden gelir, ancak yalnızca onu almak için bir dinleyici zaten çalışıyorsa. Dinleyici yok, olay yok ve iade, başka bir şey onu uzlaştırana kadar görünmez kalır.
Aynı cihazdaki bir satın alma updates üzerinden gelmez
Bir tuzak, iadeleri elle test edenleri yakalar. Aynı cihazda yapılan normal bir satın alma updates üzerinden gelmez; StoreKit onu doğrudan satın alma çağrısının sonucundan döndürür. updates, bant dışı değişiklikler içindir: iadeler, Ask to Buy onayları, teklif kodu kullanımları ve başka bir yerde yapılan satın almalar. Bu yüzden iade işlemenizi satın alma akışı etrafında değil, updates ve currentEntitlements etrafında kurun, çünkü iade asla satışın gittiği yoldan geri yürümez.

İstemci taraflı tespitin sizin için yapamayacakları
İadeleri cihazda okumak hızlı ve ücretsizdir, ama bir tavanı vardır ve olmadığını varsaymak, gelirin nasıl sızdığıdır. Cihaz yalnızca StoreKit'in ona söylediğini bilir ve StoreKit yalnızca uygulamanız çalışırken konuşur. Bir iade alan ve uygulamanızı bir daha asla açmayan bir müşteri, istemci taraflı kontrolünüzün asla görmediği bir müşteridir.
Bir revocationDate her zaman iade değildir
Aynı alan Family Sharing için değişir. Bir müşteri paylaşılan bir satın almaya erişimini kaybettiğinde, çünkü düzenleyici onu kaldırdı veya paylaşım sona erdi, o işlem de bir revocationDate alır. Yani nil olmayan bir tarih, müşterinin artık bu satın almaya sahip olmadığı anlamına gelir, ki bu tam olarak erişim kontrolü için ihtiyacınız olan şeydir, ama her zaman paranın geri çıktığı anlamına gelmez. Gelir için iadeleri sayıyorsanız, sayıya güvenmeden önce Family Sharing iptallerini gerçek olanlardan ayırın.
Bir iade tersine çevrilebilir
Bir iade her zaman kesin değildir. Apple onu tersine çevirebilir ve çevirdiğinde, iptal alanları işlemden kaldırılır ve satın alma tekrar geçerli olur. İade üzerine erişimi kestiyseniz, tersine çevirme üzerine onu geri yüklemeniz beklenir. Cihazda bu, temiz bir işlemle başka bir updates olayı olarak görünür; sunucunuzda ayrı bir REFUND_REVERSED bildirimidir. Yalnızca iadeyi ele alın ve ödeme yapan bir müşteriyi erişimsiz ama çalışan bir fişle mahsur bırakırsınız.
Geç bir iptalin gerçek maliyeti
Bir iade nadiren yalnızca satış fiyatının hesabınızdan çıkmasıdır. O temizlendiğinde, genellikle o satın almaya hizmet vermek için zaten gerçek para harcamışsınızdır ve o harcama geri gelmez. Oluşturulan görüntüler GPU dakikalarına mal olur. Sohbet yanıtları, token başına faturalandırıldığınız model API çağrılarına mal olur. Yüklemeler, tutmak için hâlâ ödediğiniz depolamaya mal olur. Satın alma bir içerik üreticisine yapılan bir ödemeyi finanse ettiyse, o para çoktan gitmiştir. Hiçbiri iadeyle geri dönmez.
İstemci taraflı tespit, hâlâ kontrol edebileceğiniz tek kısımdaki pencereyi daraltır, ki o da gelecekteki harcamadır. Bir satın almanın iade edildiğini ne kadar erken bilirseniz, ona hizmet vermeyi o kadar erken durdurursunuz. Ama cihaz size yalnızca uygulama açıkken söyler, bu yüzden bir daha geri gelmeyen iade edilmiş bir kullanıcı, verdiğiniz sunucu taraflı erişimi korur ve bir arka plan görevi veya senkronize bir cihaz onun adına her hareket ettiğinde sessizce size maliyet çıkarır. İstemci iptali hızlı yapar. Onu garantili yapmaz.
Hız için istemciyi, gerçek için sunucuyu kullanın
Temiz tasarım her iki sinyali de her birinin iyi olduğu şey için kullanır. Cihazda, Transaction.updates ve currentEntitlements, iade edilmiş bir müşteri uygulamayı açtığı anda size anlık, yerel bir tepki verir, arayüz için ve bir gidiş dönüş olmadan hak değişikliklerini tamamlamak için iyidir. Sunucuda, App Store Server Notifications V2, uygulama bir daha açılsın ya da açılmasın gelen bir REFUND mesajı gönderir, ki bu, arka ucunuzun iade edilmiş bir hesaba harcama yapmasını güvenilir şekilde durduran tek sinyaldir.
| Sinyal | Nerede bulunur | Ne zaman tetiklenir | Şunun için güvenin |
|---|---|---|---|
işlemdeki revocationDate | Cihaz, StoreKit 2 | Uygulamanız işlemi okur | Belirli bir satın almanın iade edildiğini veya iptal edildiğini söylemek |
Transaction.updates | Cihaz, StoreKit 2 | Uygulama çalışırken bir iade gelir veya dinlerseniz başlangıçta | Mevcut bir müşteri için anında tepki vermek |
currentEntitlements | Cihaz, StoreKit 2 | Müşterinin şimdi neye sahip olduğunu kontrol edersiniz | İadeleri kendiniz izlemeden erişimi kontrol etmek |
REFUND bildirimi | Sunucunuz, App Store Server Notifications V2 | Apple iadeyi işler, uygulama açık olsun ya da olmasın | Asla geri dönmeyen bir müşteriye sunucu taraflı harcamayı durdurmak |
Telefonu tutan müşteri için cihaz sinyallerini, tutmayan için sunucu bildirimini kurun. İade her iki yerde de bilerek görünür. Yalnızca birini okumak, iade edilmiş bir hesabın satış çoktan gittikten sonra size maliyet çıkarmaya devam etmesinin yoludur.
Sık sorulan sorular
- StoreKit 2'de bir iadeyi nasıl tespit ederim?
- İşlemin revocationDate'ini kontrol edin. Geçerli bir satın alma için nil'dir ve App Store işleme iade yaptığında bir tarih tutar, bu yüzden nil olmayan bir revocationDate, bir satın almanın iade edildiği veya iptal edildiği sinyalidir.
- revocationDate ile revocationReason arasındaki fark nedir?
- revocationDate, App Store'un satın almayı geri aldığı andır ve revocationReason nedenidir. Neden, müşteri uygulamanızdaki bir sorunu belirttiğinde developerIssue ve başka her şey için other'dır.
- İade edilmiş bir satın alma hâlâ currentEntitlements'te görünür mü?
- Hayır. Transaction.currentEntitlements, App Store'un iade ettiği veya iptal ettiği satın almaları hariç tutar, bu yüzden iade edilmiş bir ürün müşterinin haklarından kendi başına düşer, bu da onu erişim için güvenli bir kontrol yapar.
- StoreKit uygulamama, uygulama kapalıyken gerçekleşen bir iadeyi söyler mi?
- Yalnızca başlangıçtan dinlerseniz. Transaction.updates bu değişiklikleri başlangıçta bir kez iletir, bu yüzden uygulamanız başlarken onu yineleyen bir Task başlatmalısınız yoksa başka bir şey onu uzlaştırana kadar iade kaçırılır.
- İstemci taraflı iade tespiti tek başına yeterli mi?
- Hayır. Cihaz bir iadeyi yalnızca uygulamanız çalışırken öğrenir, bu yüzden uygulamayı bir daha asla açmayan bir müşteri ona görünmezdir. App Store Server Notifications V2 REFUND, ne olursa olsun size ulaşan sinyaldir.
- Bir revocationDate her zaman müşterinin iade aldığı anlamına mı gelir?
- Hayır. revocationDate, bir müşteri bir satın almayı Family Sharing üzerinden kaybettiğinde de ayarlanır, bu yüzden nil olmayan bir tarih, artık satın almaya sahip olmadıkları anlamına gelir ama her zaman paranın iade edildiği anlamına gelmez.
Kaynaklar ve ek okumalar
- Apple Developer: Transaction.revocationDate (StoreKit)
- Apple Developer: Transaction.RevocationReason (StoreKit)
- Apple Developer: Transaction.currentEntitlements (StoreKit)
- Apple Developer: Transaction.updates (StoreKit)
- Apple Developer: App Store Server Notifications V2 notificationType (REFUND, REFUND_REVERSED)
- Apple Developer Tech Talk: Support customers with StoreKit 2 and App Store Server API
RefundHalt
App Store ve Google Play için geri ödeme otomatik pilotu
Okumaya devam edin
Her App Store ve Google Play iade penceresi bir geri sayımdır ve her biri sana kaç saat tanıyor işte burada
App Store ve Google Play'deki her iade bir saati başlatır ve çoğu sen olmadan işler. Apple'ın en kısa iade penceresi 12 saat, Google'ın ters ibraz penceresi 24 saattir ve 3 Ağustos 2026'dan itibaren kaçırılan bir ters ibraz penceresi yalnızca kayıp bir satış değil, ödenecek bir faturadır. Hesabına dokunan her son tarih burada.
Geçersiz kılınmış satın alma bildirimi, bir iade geldiği anda Google Play sunucunuzun erişimi iptal etmesini sağlar
Google Play, bir satın alma iade edildiği, ters ibraza uğradığı ya da geçersiz kılındığı anda sunucunuza bir geçersiz kılınmış satın alma bildirimi gönderebilir. purchaseToken, orderId, productType ve refundType taşır ve tek bir şey ifade eder, erişimi iptal et. İşte onu okuma ve bağlama yöntemi.