Google Play'de bir iade sessizce gerçekleşir. Ücret geri alınır, müşteri uygulamayı kullanmaya devam eder ve siz bilerek kontrol etmedikçe sizin tarafınızda hiçbir şey değişmez. Voided Purchases API tam olarak bu kontrolü yapmak içindir. İptal edilmiş, iade edilmiş veya chargeback yapılmış siparişleri döndürür; böylece müşterinin artık ödemediği şeye erişimi geri alabilirsiniz. Buna zamanlanmış bir görev bağlayın, dönen sonucu okuyun ve hak tanımasını (entitlement) iptal edin. Mekanizmanın tamamı bu kadar.
Neredeyse her ekibi yakalayan bir şey var ve bu şey kodda değil, politikada yaşıyor. Bu API yalnızca gerçekten revoke edilmiş siparişleri listeler. Play Console'da bir satın almayı revoke seçeneğini işaretlemeden iade ederseniz, o sipariş burada hiçbir zaman görünmez; böylece göreviniz tertemiz çalışırken, iade alan bir müşteri sattığınız her şeyi elinde tutarak çekip gider. Aşağıda API'yi alan alan, onu sınırlayan limitleri ve bağlantısı kurulmadığında paranın sessizce nereden aktığını ele alıyoruz.
Önemli noktalar
purchases.voidedpurchases.list metodu üzerinden erişilen Voided Purchases API, Google Play'in iptal ettiği, iade ettiği veya chargeback yaptığı siparişleri listeler; bu da müşterinin artık sahip olmadığı satın almalara erişimi kaldıran bir sistem kurmanızı sağlar.
Yalnızca revoke edilmiş siparişleri gösterir. Revoke edilmeden yapılan bir geliştirici iadesi burada görünmez kalır; dolayısıyla erişimi geri almak, revoke açıkken iade yapmak anlamına gelir.
Erişim aralığı kayan bir 30 günlük penceredir. startTime 30 günden daha geriye gidemediği için, bir aydan uzun süre çevrim dışı kalan herhangi bir sunucu bu void'leri kalıcı olarak kaybeder; bu yüzden polling'in bir programa göre çalışması gerekir.
voidedSource, void'i kimin tetiklediğini belirtir: kullanıcı için 0, geliştirici için 1, Google için 2. voidedReason ise nedenini açıklar; 0 (Other/Diğer) ile başlayıp 7 (Chargeback) ve 8'e (Unacknowledged_purchase) kadar uzanır.
Gerçek zamanlı geliştirici bildirimleri, bir satın alma void edildiği anda bir VoidedPurchaseNotification tetikler; ancak bunu bir uyarı olarak ele alın. Herhangi bir şeyi revoke etmeden önce Voided Purchases API üzerinden doğrulayın.
Abonelik yenilemelerini purchaseToken ile değil, orderId ile birbirinden ayırt edin. Tek bir purchaseToken bir aboneliğin her yenilemesini kapsar; bu yüzden token tek başına bir dönemi diğerinden ayıramaz.
Üst sınırlar günde 6.000 sorgu ve herhangi bir 30 saniyelik aralıkta 30 sorgudur; bu yüzden her isteği bir zaman penceresiyle sınırlayın ve devam belirteci (continuation token) kullanarak sayfalar arasında ilerleyin, asla sipariş başına bir istek yapmayın.
API neyi geri döndürür
Bu endpoint tek bir soruyu yanıtlar: bu uygulamanın siparişlerinden hangileri son zamanlarda void edildi. Bir void, müşterinin parasını geri döndüren üç sonucu bir araya getirir: iptal, iade veya chargeback. Hem tek seferlik uygulama içi ürünlere hem de aboneliklere ulaşır ve tek bir parametre kapsamı belirler. type değerini varsayılan olan 0'da bırakırsanız yalnızca void edilmiş uygulama içi ürün satın almaları döner. type değerini 1 yaparsanız void edilmiş uygulama içi satın almalarla void edilmiş abonelik satın almalarını birlikte alırsınız.
Yanıttaki her öğe, kısa ama değerli bir alan kümesine sahip bir voided purchase (iptal edilmiş satın alma) nesnesidir:
orderId, tek seferlik bir satın almayı, bir aboneliği veya onun içindeki tek bir yenilemeyi benzersiz şekilde işaretler. Bunu birleştirme (join) anahtarınız olarak kullanın.
purchaseToken, tek seferlik bir satın almayı veya bir aboneliği tanımlar, ancak yenilemeleri birbirinden ayırmaz; bu yüzden yenilemeler için orderId'ye dayanın.
purchaseTimeMillis, satın almanın ne zaman gerçekleştiğini epoch'tan bu yana geçen milisaniye cinsinden kaydeder.
voidedTimeMillis, iptal, iade veya chargeback zamanını, yine epoch'tan bu yana geçen milisaniye cinsinden kaydeder.
voidedSource, void'i kimin başlattığını belirtir; burada 0 kullanıcıyı, 1 geliştiriciyi ve 2 Google'ı ifade eder.
voidedReason, nedeni 0 ile 8 arasında bir tam sayı olarak verir.
voidedQuantity, miktar bazlı kısmi bir iadeden gelen void edilmiş adedi taşır ve yalnızca includeQuantityBasedPartialRefund true olduğunda görünür.
Tek bir purchaseToken bir aboneliğin tamamını kapsarken her yenileme yepyeni bir orderId aldığından, hak tanımalarınızı token üzerinden anahtarlamanız yanlış dönemi revoke etmenize yol açar. Bunun yerine orderId üzerinden anahtarlayın.
Herhangi bir şeye dokunmadan önce voidedReason'ı okuyun
voidedReason, sıradan bir listeyi gerçek bir karara dönüştüren alandır; çünkü bir fikir değişikliği iadesiyle bir banka chargeback'i aynı akışı paylaşsa da birbirine hiç benzemez. Tam liste şöyledir:
1. Other (Diğer) atanmış bir kategori taşımaz. Revoke edin ve devam edin.
2. Remorse (Pişmanlık), fikrini değiştiren bir müşteridir; sıradan bir iadedir.
3. Not_received, ürünün hiç ulaşmadığına dair bir iddiadır; teslimatınızı gözden geçirmeye değer.
4. Defective, ürünün çalışmadığı anlamına gelir; kaydetmeniz gereken bir kalite sinyalidir.
5. Accidental_purchase, sıklıkla paylaşılan bir cihazda yapılan istem dışı bir satın almadır.
6. Fraud, Google'ın dolandırıcılık olarak işaretlediği bir işlemdir.
7. Friendly_fraud, gerçek kart sahibinin fiilen yaptığı bir ücretlendirmeye itiraz ettiği bir chargeback'tir.
8. Chargeback, müşterinin bankasının ödemeyi geri almasıdır; banka nezdinde kesindir ve artık size fatura edilir.
9. Unacknowledged_purchase, uygulamanızın hiç onaylamadığı bir satın almayı Google'ın otomatik olarak iade etmesidir.
9 numaralı neden, kendi kendinize neden olduğunuz bir iadedir. Uygulamanızın onaylamadan bıraktığı her satın almanın parası Google tarafından iade edilir; bu yüzden bu akıştaki bir unacknowledged_purchase, alıcının herhangi bir tercihinden değil, atlanan tek bir çağrıdan vazgeçilmiş bir gelirdir.
Listeyi sessizce boşaltan 30 günlük pencere
API, geçmişe doğru en fazla son 30 güne kadar gidebilir. startTime varsayılan olarak şu andan 30 gün öncesine ayarlıdır ve daha erken bir değere ayarlanmasına izin vermez; endTime ise varsayılan olarak şu andır. Yani elinizdeki şey kalıcı bir arşiv değil, kayan bir aylık bir penceredir.
Bunun sonucu çarpıcıdır. Bir polling görevinin beş hafta boyunca bozulup fark edilmeden kalmasına izin verirseniz, ilk haftanın void'leri API'den çoktan düşmüş olur ve hiçbir çağrı onları geri getiremez. Bu siparişler revoke edilmeden kalır ve başka bir yerde kaydetmediyseniz gerçekleştiklerini bile bilemezsiniz. Ağınızdaki delik, en uzun kesintinizle tam olarak aynı genişliktedir. En az günde bir kez poll yapın ve gerçek zamanlı bildirimlerle mutabakat sağlayın; 30 günü olduğu gibi, katı bir silinme saati olarak ele alın.
Bir siparişin görünüp görünmeyeceği revoke'a bağlıdır
Ekiplerin API'yi "bozuk" olarak nitelendirmesinin bir numaralı nedeni budur. API yalnızca revoke edilmiş siparişleri döndürür, başka hiçbir şeyi değil. Kullanıcıların başlattığı iadeler, iptaller, chargeback'ler ve Google tarafından başlatılan iadeler otomatik olarak revoke edilir; bu yüzden her zaman akışta yer alır. Geliştirici tarafından başlatılan bir iade ise istisnadır. İster Play Console'dan ister Orders API üzerinden iadeyi kendiniz yaparsanız, revoke seçeneği ayrıca vermeniz gereken bir karar olarak kalır. Bunu reddederseniz sipariş müşteriyle kapanır ama bu akışta hiçbir zaman görünmez.
Çıkarım kısa. Amacınız erişimi kesmekse, revoke açıkken iade yapın. Bunu atlarsanız, parayı iade edip kapıyı açık bırakmış olursunuz; revoke göreviniz ne kadar özenle kurulmuş olursa olsun, üzerinde çalışacak hiçbir şey bulamaz.
Kotaya takılmadan polling yapmak
Bu endpoint oran sınırlıdır (rate limited) ve üst sınırlar, dikkatsiz bir döngünün onları kolayca aşabileceği kadar düşüktür. Pasifik Saati'ne göre sayılan günde 6.000 sorgu hakkınız vardır ve herhangi bir 30 saniyelik aralıkta 30'dan fazlasına asla izin verilmez. Bu bütçe, pencerelenmiş polling'e uygundur ve sipariş başına bir çağrı tasarlayan herhangi bir yapıyı cezalandırır.
Zaman pencereleri ve devam belirteci
maxResults varsayılan olarak 1.000'dir ve ulaşabileceği en yüksek değer de budur. Bir pencere, bir sayfanın alabileceğinden daha fazla void içeriyorsa, yanıt nextPageToken içeren bir tokenPagination nesnesiyle gelir. Sayfalar arasında ilerlemek için bir sonraki çağrınızda bu belirteci geri gönderin. Pencerenin sınırlarını startTime ve endTime ile sabitleyin, belirteç tükenene kadar sayfalamaya devam edin ve ancak o zaman pencereyi ileri kaydırın. Bu ritim, hem 30 saniyelik ani yükleniş sınırından hem de günlük kotadan uzak durmanızı sağlar.
Gerçek zamanlı bildirimler günlük açığı kapatır
Günlük bir poll bile sizi 24 saate kadar kör bırakır ve tam olarak 30 günlük pencerenin cezalandırdığı şey uzun boşluklardır. Gerçek zamanlı geliştirici bildirimleri bu gecikmeyi kapatır. Bir satın alma void edildiği anda, kontrolünüz altındaki bir Cloud Pub/Sub konusuna bir VoidedPurchaseNotification yayınlanır ve backend'iniz bunu saniyeler içinde tüketir. Yükü (payload) kompakt kalır:
purchaseToken, orijinal satın almadan gelen belirteçtir.
orderId, void edilen işlemin kimliğidir; her abonelik yenilemesinde yeniden oluşturulur.
productType, abonelik için 1, tek seferlik satın alma için 2'dir.
refundType, 1 ile işaretlenen tam iadeyi 2 ile işaretlenen miktar bazlı kısmi iadeden ayırır.
Bildirimi kesin gerçek değil, bir uyarı olarak alın. Bir VoidedPurchaseNotification geldiğinde, siparişin gerçekte nerede durduğunu doğrulamak için Voided Purchases API'yi sorgulayın ve ancak o zaman revoke edin. Uyarı size kontrol etmenizi söyler; API ise size gerçeği söyler.
Size parasal olarak maliyeti
API bir altyapı borusudur, ama bu boruyu döşemenin nedeni bir faturadır ve üzerindeki iki rakam yükseliyor.
3 Ağustos 2026'dan itibaren chargeback faturası size ait
3 Ağustos 2026 itibarıyla Google, bir chargeback'in maliyetini geliştiriciye taşır. Satın alma bedelinden vazgeçersiniz ve üstüne bankanın chargeback ücretini de karşılarsınız. voidedReason değeri 7 olan bir işlem artık sadece kaybedilmiş bir satış olmaktan çıkıp, üzerinde bir ücret bulunan bir kalem hâline gelir. Chargeback'in kendisi geri alınamaz, çünkü banka nezdinde kesindir; ancak void'i hızlıca yakalamak, hak tanımasını revoke etmenizi ve hâlâ teslim edilmekte olan her şey için, iade edilip ardından tersine çevrilmiş bir müşteriye harcama yapmayı durdurmanızı sağlar.
Zaten iade almış bir müşteriyi finanse etmeye devam ediyorsunuz
Bir void geldiği anda satış bedeli çoktan gitmiştir. Hâlâ kontrol edebileceğiniz şey, teslimatı sürdürmenin maliyetidir. İade edilmiş bir hak tanıması aktif kaldığı her saat için, müşterinin artık karşılamadığı faturalar sizin tarafınıza gelmeye devam eder: hesaplama (compute) maliyeti, model sağlayıcı çağrıları, depolama ve müşterinin etkinliğinin tetiklediği her türlü içerik üreticisi veya iş ortağı ödemesi. Bu API üzerine kurulan revoke hattı, bu harcamanın kapatılmasını sağlayan şeydir. Bunu atlarsanız, mağazanın çoktan geri ödediği kişiler için ürünü finanse etmeye devam edersiniz.
Friendly fraud bir olay değil, bir eğilimdir
voidedReason değeri 5 veya 6 olan bir işlem nadiren tek başına kalır. Fraud ve friendly fraud, hesaplar, cihazlar ve zaman zaman belirli promosyonlar etrafında kümelenir. API her void'e voidedSource ve voidedReason eklediği için, her tersine çevirmeyi tek başına bir kayıp olarak kabul etmek yerine, hesap bazında kötüye kullanım eğilimini izleyecek kadar veriye sahip olursunuz. İkinci kez chargeback yapan bir hesap, ilk iadenin size söylemediğini söylüyordur.
Hepsini bir araya getirmek
Parçalar elinizde olduğunda tüm model küçüktür. Hiçbir şeyin tam bir gün beklememesi için VoidedPurchaseNotification'ı gerçek zamanlı dinleyin. Voided Purchases API'yi, yenilemelerin asla birbirine karışmaması için orderId üzerinden anahtarlanmış tek gerçek kaynağı olarak ele alın. Bir chargeback'in bir pişmanlık iadesinden ayrı ele alınması için voidedSource ve voidedReason'ı okuyun. 30 günlük pencerenin sizi hiç ısırmayacağı kadar sıkı bir ritimde poll yapın ve erişimi kesmek istediğiniz her seferinde revoke açıkken iade yapın.
Refund Sensor'ın sizin adınıza çalıştırdığı katman tam olarak budur. Gerçek zamanlı bildirimleri tüketir, her void'i API'ye karşı mutabakata tabi tutar, ürünün tamamı yerine tam olarak doğru siparişi revoke eder ve bir banka chargeback'ini sıradan bir iadeden ayrı tutarak maliyetli olanların gizlenmek yerine görünür olmasını sağlar. Kurmanız gereken bir Pub/Sub hattı veya polling görevi olmadan, erişimin saniyeler içinde kesildiğini ve kimin neyi neden void ettiğine dair eksiksiz bir kayıt elde edersiniz.
Bu kuralların belgelendiği yerler
Sık sorulan sorular
Çünkü bu akış yalnızca iptal edilmiş (revoke edilmiş) siparişleri içerir. Kullanıcının başlattığı iadeler, iptaller, chargeback'ler ve Google tarafından başlatılan iadeler kendiliğinden revoke edilir ve her zaman görünür. Sizin başlattığınız bir iade ise, yalnızca onu da revoke etmeyi seçtiyseniz görünür. Revoke etmeden iade yaparsanız sipariş kapanır ama burada görünmez kalır; bu yüzden amacınız erişimi geri almaksa revoke seçeneğini mutlaka açın.
Otuz gün, daha fazlası değil. startTime varsayılan olarak şu anki zamandan 30 gün öncesine ayarlıdır ve bundan daha erken bir değeri kabul etmez; bu yüzden endpoint bir arşiv gibi değil, kayan bir aylık pencere gibi davranır. Bir void 30 günü geçtiğinde artık geri getirilemez şekilde kaybolur; tam da bu yüzden düzenli bir programla poll yapmanız ve bunu gerçek zamanlı bildirimlerle desteklemeniz gerekir.
İkisinin de bir rolü var. Bir VoidedPurchaseNotification size saniyeler içinde ulaşır ve kontrol etmeniz gerektiğini söyler, ancak Google'ın önerisi bunu gerçeğin kendisi değil bir sinyal olarak ele almanızdır. Mevcut durumu Voided Purchases API üzerinden doğrulayın, ardından revoke edin. Bildirim gecikmeyi ortadan kaldırır; API ise gerçekten üzerine hareket edeceğiniz güvenilir voidedSource ve voidedReason bilgisini sağlar.
voidedReason alanına bakın. 7, müşterinin bankasının ödemeyi geri aldığı bir chargeback'i, 6 ise dostane dolandırıcılığı (friendly fraud) gösterir. 1 ise sıradan bir fikir değişikliği iadesidir. Bu ayrım önemlidir çünkü 3 Ağustos 2026'dan itibaren Google, chargeback tutarını ve banka ücretini geliştiriciye yansıtır, bu yüzden bir 7 size düz bir iadeden daha pahalıya mal olur.
Evet, kapsıyor. type parametresini 1 olarak ayarlarsanız, iptal edilmiş uygulama içi satın almalarla birlikte iptal edilmiş abonelik satın almalarını da alırsınız; varsayılan değer olan 0 ise yalnızca uygulama içi ürünleri döndürür. Abonelikler için, iptal edilen dönemi tam olarak belirlemek üzere orderId kullanın; çünkü tek bir purchaseToken her yenilemeyi kapsarken, her yenileme işlemi kendi orderId'sini alır.






