Bu konuda, ürün satmaya başlamak için Google Play Faturalandırma Kitaplığı'nı uygulamanıza nasıl entegre edeceğiniz açıklanmaktadır.
Bu konu, GitHub'daki resmi örnek uygulamaları temel alan kod örneklerini içerir. Örnek uygulamaların tam listesi ve entegrasyon sırasında kullanabileceğiniz diğer kaynaklar için ek kaynaklara göz atın.
Satın alma işleminin ömrü
Tek seferlik satın alım veya abonelik için tipik bir satın alma akışı aşağıda verilmiştir.
- Kullanıcıya neler satın alabileceğini gösterin.
- Kullanıcının satın alma işlemini kabul etmesi için satın alma akışını başlatın.
- Satın alma işlemini sunucunuzda doğrulayın.
- Kullanıcıya içerik verin.
- İçeriğin yayınlandığını onaylayın. Tüketilebilir ürünler söz konusu olduğunda, kullanıcının öğeyi tekrar satın alabilmesi için satın alma işlemini gerçekleştirin.
Abonelikler, iptal edilene kadar otomatik olarak yenilenir. Bir abonelik aşağıdaki durumlardan geçebilir:
- Etkin: Kullanıcı iyi durumda ve aboneliğe erişebiliyor.
- İptal edildi: Kullanıcı, işlemi iptal etmiştir ancak geçerlilik süresi sona erene kadar erişimi devam etmektedir.
- Ek yayınlanma süresinde: Kullanıcı bir ödeme sorunu yaşadı ancak Google ödeme yöntemini yeniden denerken kullanıcı erişimi devam ediyor.
- Beklemede: Kullanıcı bir ödeme sorunuyla karşılaşmıştır ve Google ödeme yöntemini yeniden denerken artık erişimi yoktur.
- Duraklatıldı: Kullanıcı erişimini duraklatır ve devam edene kadar erişemez.
- Süresi doldu: Kullanıcı aboneliği iptal etmiştir ve aboneliği kaybetti. Kullanıcı, geçerlilik süresi sona erdiğinde uygulamayı kullanmayı bırakmış olarak kabul edilir.
Google Play bağlantısını başlatın
Google Play'in faturalandırma sistemiyle entegrasyonun ilk adımı, uygulamanıza Google Play Faturalandırma Kitaplığı'nı eklemek ve bir bağlantı başlatmaktır.
Google Play Faturalandırma Kitaplığı bağımlılığını ekleme
Google Play Faturalandırma Kitaplığı bağımlılığını uygulamanızın build.gradle
dosyasına aşağıda gösterildiği gibi ekleyin:
Eskitme
dependencies { def billing_version = "6.1.0" implementation "com.android.billingclient:billing:$billing_version" }
Kotlin
dependencies { val billing_version = "6.1.0" implementation("com.android.billingclient:billing:$billing_version") }
Kotlin kullanıyorsanız Google Play Faturalandırma Kitaplığı KTX modülü, Google Play Faturalandırma Kitaplığı'nı kullanırken deyimsel Kotlin yazmanıza olanak tanıyan Kotlin uzantıları ve eş yordamlar desteği içerir. Bu uzantıları projenize dahil etmek için aşağıdaki bağımlılığı uygulamanızın build.gradle
dosyasına gösterildiği şekilde ekleyin:
Eskitme
dependencies { def billing_version = "6.1.0" implementation "com.android.billingclient:billing-ktx:$billing_version" }
Kotlin
dependencies { val billing_version = "6.1.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
Bir BillingClient'ı başlatma
Google Play Faturalandırma Kitaplığı'na bağımlılık ekledikten sonra bir BillingClient
örneğini başlatmanız gerekir. BillingClient
, Google Play Faturalandırma Kitaplığı ile uygulamanızın geri kalanı arasındaki iletişim için ana arayüzdür. BillingClient
, yaygın olarak kullanılan birçok faturalandırma işlemi için hem eşzamanlı hem de eşzamansız olarak pratik yöntemler sunar. Tek bir etkinlik için birden fazla PurchasesUpdatedListener
geri çağırmasını önlemek istiyorsanız aynı anda bir etkin BillingClient
bağlantınızın açık olması kesinlikle önerilir.
BillingClient
oluşturmak için newBuilder()
kullanın. newBuilder()
öğesine herhangi bir bağlamı iletebilirsiniz. BillingClient
, bunu uygulama bağlamı almak için kullanır.
Diğer bir deyişle, bellek sızıntıları konusunda endişelenmenize gerek yoktur. Satın alma işlemleriyle ilgili güncellemeleri almak için setListener()
yöntemini çağırarak PurchasesUpdatedListener
referansını da iletmeniz gerekir. Bu dinleyici, uygulamanızdaki tüm
satın alma işlemleri için güncelleme alır.
Kotlin
private val purchasesUpdatedListener = PurchasesUpdatedListener { billingResult, purchases -> // To be implemented in a later section. } private var billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .build()
Java
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() { @Override public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) { // To be implemented in a later section. } }; private BillingClient billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .build();
Google Play'e bağlan
BillingClient
oluşturduktan sonra Google Play ile bağlantı kurmanız gerekir.
Google Play'e bağlanmak için startConnection()
numaralı telefonu arayın. Bağlantı işlemi eşzamansızdır ve istemci kurulumu tamamlanıp istemci başka istekler yapmaya hazır olduğunda geri çağırma almak için bir BillingClientStateListener
uygulamanız gerekir.
Google Play ile kaybedilen bağlantıları ele almak için yeniden deneme mantığını da uygulamanız gerekir.
Yeniden deneme mantığını uygulamak için onBillingServiceDisconnected()
geri çağırma yöntemini geçersiz kılın ve BillingClient
başka isteklerde bulunmadan önce Google Play'e yeniden bağlanmak için startConnection()
yöntemini çağırdığından emin olun.
Aşağıdaki örnekte bağlantı başlatma ve bağlantının kullanıma hazır olup olmadığını test etme gösterilmektedir:
Kotlin
billingClient.startConnection(object : BillingClientStateListener { override fun onBillingSetupFinished(billingResult: BillingResult) { if (billingResult.responseCode == BillingResponseCode.OK) { // The BillingClient is ready. You can query purchases here. } } override fun onBillingServiceDisconnected() { // Try to restart the connection on the next request to // Google Play by calling the startConnection() method. } })
Java
billingClient.startConnection(new BillingClientStateListener() { @Override public void onBillingSetupFinished(BillingResult billingResult) { if (billingResult.getResponseCode() == BillingResponseCode.OK) { // The BillingClient is ready. You can query purchases here. } } @Override public void onBillingServiceDisconnected() { // Try to restart the connection on the next request to // Google Play by calling the startConnection() method. } });
Satın alınabilecek ürünleri gösterin
Google Play ile bağlantı kurduktan sonra, kullanılabilir ürünlerinizi sorgulamaya ve kullanıcılarınıza göstermeye hazırsınızdır.
Ürün ayrıntılarını sorgulamak, yerelleştirilmiş ürün bilgileri döndürdüğünden ürünlerinizi kullanıcılarınıza göstermeden önce önemli bir adımdır. Aboneliklerde ürün ekranınızın tüm Play politikalarına uyduğundan emin olun.
Uygulama içi ürün ayrıntılarını sorgulamak için queryProductDetailsAsync()
numaralı telefonu arayın.
Eşzamansız işlemin sonucunu işlemek için ProductDetailsResponseListener
arayüzünü uygulayan bir işleyici belirtmeniz de gerekir.
Daha sonra, aşağıdaki örnekte gösterildiği gibi sorgu tamamlandığında işleyiciyi bilgilendiren onProductDetailsResponse()
öğesini geçersiz kılabilirsiniz:
Kotlin
val queryProductDetailsParams = QueryProductDetailsParams.newBuilder() .setProductList( ImmutableList.of( Product.newBuilder() .setProductId("product_id_example") .setProductType(ProductType.SUBS) .build())) .build() billingClient.queryProductDetailsAsync(queryProductDetailsParams) { billingResult, productDetailsList -> // check billingResult // process returned productDetailsList } )
Java
QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder() .setProductList( ImmutableList.of( Product.newBuilder() .setProductId("product_id_example") .setProductType(ProductType.SUBS) .build())) .build(); billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { public void onProductDetailsResponse(BillingResult billingResult, List<ProductDetails> productDetailsList) { // check billingResult // process returned productDetailsList } } )
Ürün ayrıntılarını sorgularken, Google Play Console'da oluşturulan ürün kimliği dizelerinin listesini ve ProductType
ile birlikte belirten bir QueryProductDetailsParams
örneği iletin. ProductType
, tek seferlik ürünler için ProductType.INAPP
veya abonelikler için ProductType.SUBS
olabilir.
Kotlin uzantılarıyla sorgulama
Kotlin uzantıları kullanıyorsanız, queryProductDetails()
uzantı işlevini çağırarak uygulama içi ürün ayrıntılarını sorgulayabilirsiniz.
queryProductDetails()
, ayrı bir işleyici tanımlamanıza gerek kalmaması için Kotlin eş yordamlarından yararlanır. Bunun yerine, işlev, sorgulama tamamlanana kadar askıya alınır. Bu işlemin ardından sonucu işleyebilirsiniz:
suspend fun processPurchases() {
val productList = ArrayList<String>()
productList.add(
QueryProductDetailsParams.Product.newBuilder()
.setProductId("product_id_example")
.setProductType(BillingClient.ProductType.SUBS)
.build()
)
val params = QueryProductDetailsParams.newBuilder()
params.setProductList(productList)
// leverage queryProductDetails Kotlin extension function
val productDetailsResult = withContext(Dispatchers.IO) {
billingClient.queryProductDetails(params.build())
}
// Process the result.
}
Nadiren de olsa, bazı cihazlar genellikle Google Play Hizmetleri'nin eski sürümlerinden dolayı ProductDetails
ve queryProductDetailsAsync()
sürümlerini destekleyemez. Bu senaryoya yönelik uygun desteği sağlamak için Play Faturalandırma Kitaplığı 5 taşıma kılavuzundan geriye dönük uyumluluk özelliklerinin nasıl kullanılacağını öğrenin.
Sonucu işleyin
Google Play Faturalandırma Kitaplığı, sorgu sonuçlarını ProductDetails
nesneden List
tanesinde depolar. Daha sonra, bir uygulama içi ürünle ilgili fiyatı veya açıklaması gibi alakalı bilgileri görüntülemek için listedeki her ProductDetails
nesnesinde çeşitli yöntemleri çağırabilirsiniz. Mevcut ürün ayrıntıları bilgilerini görüntülemek için ProductDetails
sınıfındaki yöntem listesine bakın.
Bir öğeyi satışa sunmadan önce kullanıcının öğeye zaten sahip olup olmadığını kontrol edin. Kullanıcının öğe kitaplığında hâlâ bulunan bir sarf malzemeleri varsa tekrar satın almadan önce öğeyi tüketmesi gerekir.
Abonelik sunmadan önce kullanıcının zaten abone olmadığını doğrulayın. Ayrıca aşağıdakileri de unutmayın:
queryProductDetailsAsync()
, abonelik ürün ayrıntılarını ve abonelik başına en fazla 50 teklif döndürür.queryProductDetailsAsync()
, yalnızca kullanıcının uygun olduğu teklifleri döndürür. Kullanıcı, uygun olmadığı bir fırsatı satın almaya çalışırsa (örneğin, uygulamada uygun fırsatların eski bir listesini gösteriyorsa) Play kullanıcıya uygun olmadığını bildirir ve kullanıcı bunun yerine temel planı satın almayı seçebilir.
Satın alma akışını başlatma
Uygulamanızdan satın alma isteği başlatmak için uygulamanızın ana iş parçacığından launchBillingFlow()
yöntemini çağırın. Bu yöntem, queryProductDetailsAsync()
çağrısından alınan ilgili ProductDetails
nesnesini içeren bir BillingFlowParams
nesnesine referans verir. BillingFlowParams
nesnesi oluşturmak için BillingFlowParams.Builder
sınıfını kullanın.
Kotlin
// An activity reference from which the billing flow will be launched. val activity : Activity = ...; val productDetailsParamsList = listOf( BillingFlowParams.ProductDetailsParams.newBuilder() // retrieve a value for "productDetails" by calling queryProductDetailsAsync() .setProductDetails(productDetails) // to get an offer token, call ProductDetails.subscriptionOfferDetails() // for a list of offers that are available to the user .setOfferToken(selectedOfferToken) .build() ) val billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build() // Launch the billing flow val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)
Java
// An activity reference from which the billing flow will be launched. Activity activity = ...; ImmutableListproductDetailsParamsList = ImmutableList.of( ProductDetailsParams.newBuilder() // retrieve a value for "productDetails" by calling queryProductDetailsAsync() .setProductDetails(productDetails) // to get an offer token, call ProductDetails.getSubscriptionOfferDetails() // for a list of offers that are available to the user .setOfferToken(selectedOfferToken) .build() ); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build(); // Launch the billing flow BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
launchBillingFlow()
yöntemi, BillingClient.BillingResponseCode
öğesinde listelenen çeşitli yanıt kodlarından birini döndürür. Satın alma akışını başlatırken herhangi bir hata olmadığından emin olmak için bu sonucu kontrol ettiğinizden emin olun. OK
değerinin BillingResponseCode
olması, lansmanın başarılı olduğunu gösterir.
launchBillingFlow()
numaralı telefona başarılı bir arama yapıldığında sistem, Google Play satın alma ekranını görüntüler. Şekil 1'de bir abonelik için satın alma ekranı gösterilmektedir:

Google Play, satın alma işleminin sonucunu PurchasesUpdatedListener
arayüzünü uygulayan bir işleyiciye iletmek için onPurchasesUpdated()
işlevini çağırır. İşleyici, istemcinizi başlattığınızda setListener()
yöntemi kullanılarak belirtilir.
Olası yanıt kodlarını işlemek için onPurchasesUpdated()
uygulamanız gerekir. Aşağıdaki örnekte, onPurchasesUpdated()
öğesinin nasıl geçersiz kılınacağı gösterilmektedir:
Kotlin
override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) { if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) { for (purchase in purchases) { handlePurchase(purchase) } } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user cancelling the purchase flow. } else { // Handle any other error codes. } }
Java
@Override void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) { if (billingResult.getResponseCode() == BillingResponseCode.OK && purchases != null) { for (Purchase purchase : purchases) { handlePurchase(purchase); } } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user cancelling the purchase flow. } else { // Handle any other error codes. } }
Başarılı bir satın alma işlemi, Şekil 2'ye benzer bir Google Play satın alma başarısı ekranı oluşturur.

Başarılı bir satın alma işlemi aynı zamanda kullanıcıyı ve satın alınan uygulama içi ürünün ürün kimliğini temsil eden benzersiz bir tanımlayıcı olan satın alma jetonu da oluşturur. Uygulamalarınız satın alma jetonunu yerel olarak depolayabilir ancak jetonu güvenli arka uç sunucunuza iletmenizi öneririz. Burada, satın alma işlemini doğrulayabilir ve sahtekarlığa karşı koruma sağlayabilirsiniz. Bu süreç aşağıdaki bölümde daha ayrıntılı olarak açıklanmaktadır.
Kullanıcıya ayrıca işlemin Sipariş Kimliği veya benzersiz kimliğini içeren işlem makbuzu e-postayla gönderilir. Kullanıcılar, her tek seferlik ürün satın alma işlemi ve ayrıca ilk abonelik satın alma işlemi ve daha sonraki yinelenen otomatik yenilemeler için benzersiz bir Sipariş Kimliği içeren bir e-posta alır. Google Play Console'da geri ödemeleri yönetmek için Sipariş Kimliği'ni kullanabilirsiniz.
Kişiselleştirilmiş bir fiyat belirtin
Uygulamanız Avrupa Birliği'ndeki kullanıcılara dağıtılabiliyorsa bir öğenin fiyatının otomatik karar verme sistemi kullanılarak kişiselleştirildiğini kullanıcılara bildirmek için setIsOfferPersonalized()
yöntemini kullanın.

Sanat'a danışmalısınız. 6 (1) (ea) Kullanıcılara sunduğunuz fiyatın kişiselleştirilmiş olup olmadığını belirlemek için Tüketici Hakları Direktifi'nin CRD'si (2011/83/EU)
setIsOfferPersonalized()
bir boole girişi alır. true
durumunda, Play kullanıcı arayüzü
açıklamayı içerir. false
ise kullanıcı arayüzü açıklamayı atlar. Varsayılan değer false
olarak ayarlanmıştır.
Daha fazla bilgi için Tüketici Yardım Merkezi'ne göz atın.
Satın alma işlemleri işleniyor
Kullanıcı bir satın alma işlemini tamamladıktan sonra uygulamanızın bu satın alma işlemini işlemesi gerekir.
Çoğu durumda, uygulamanıza PurchasesUpdatedListener
aracılığıyla yapılan satın alma işlemleri bildirilir. Bununla birlikte, Satın almaları getirme bölümünde açıklandığı gibi uygulamanızda BillingClient.queryPurchasesAsync()
araması yaparak satın alma işlemlerinden haberdar olabileceğiniz durumlar vardır.
Ayrıca, güvenli arka ucunuzda Gerçek Zamanlı Geliştirici Bildirimleri istemciniz varsa yeni satın alma işlemi konusunda sizi uyaran bir subscriptionNotification
veya oneTimeProductNotification
(yalnızca bekleyen satın alma işlemleri için) alarak yeni satın alma işlemleri kaydedebilirsiniz. Bu bildirimleri aldıktan sonra tam durumu almak ve kendi arka uç durumunuzu güncellemek için Google Play Developer API'yi çağırın.
Uygulamanız bir satın alma işlemini aşağıdaki şekilde işlemelidir:
- Satın alma işlemini doğrulayın.
- Kullanıcıya içerik sağlayın ve içeriği teslim ettiğini onaylayın. İsteğe bağlı olarak, kullanıcının öğeyi tekrar satın alabilmesi için öğeyi tüketildi olarak işaretleyin.
Bir satın alma işlemini doğrulamak için önce satın alma durumunun PURCHASED
olduğundan emin olun. Satın alma işlemi PENDING
ise satın alma işlemini Bekleyen işlemleri işleme bölümünde açıklandığı gibi işlemeniz gerekir. onPurchasesUpdated()
veya queryPurchasesAsync()
üzerinden yapılan satın alma işlemleriyle ilgili olarak, uygulamanız yararlanma hakkı vermeden önce meşruluğundan emin olmak için satın alma işlemini daha ayrıntılı olarak doğrulamanız gerekir. Bir satın alma işlemini uygun şekilde nasıl doğrulayacağınızı öğrenmek için Yararlanma hakkı vermeden önce satın alma işlemlerini doğrulama bölümüne bakın.
Satın alma işlemini doğrulamanızın ardından uygulamanız kullanıcıya yararlanma hakkı vermek için hazır hale gelir. Satın alma işlemiyle ilişkili kullanıcı hesabı, uygulama içi ürün satın alma işlemleri için Purchases.products:get
tarafından iade edilen ProductPurchase.obfuscatedExternalAccountId
ile, sunucu tarafındaki abonelikler için Purchases.subscriptions:get
tarafından iade edilen SubscriptionPurchase.obfuscatedExternalAccountId
ile veya Purchase.getAccountIdentifiers()
tarafından ile birlikte ayarlanmışsa istemci tarafında obfuscatedAccountId
tarafından iade edilen obfuscatedAccountId
ile tanımlanabilir.setObfuscatedAccountId
Yararlanma hakkı verdikten sonra uygulamanızın satın alma işlemini onaylaması gerekir. Bu onay, satın alma işlemi için yararlanma hakkı verdiğinizi Google Play'e bildirir.
Yararlanma hakkı verme ve satın alma işlemini onaylama süreci, satın alma işleminin tüketilebilir mi, tüketilemez veya abonelik olduğuna bağlıdır.
Tüketim Ürünleri
Tüketilebilir öğeler söz konusu olduğunda, uygulamanızın güvenli bir arka ucu varsa satın alma işlemlerini güvenilir bir şekilde tüketmek için Purchases.products:consume
kullanmanızı öneririz. Purchases.products:get
çağrısı sonucunda consumptionState
değerini kontrol ederek satın alma işleminin daha önce kullanılmadığından emin olun. Uygulamanız, arka uç olmadan yalnızca müşteri kullanıyorsa Google Play Faturalandırma Kitaplığı'ndaki consumeAsync()
aracını kullanın. Her iki yöntem de onay şartını karşılar ve uygulamanızın kullanıcıya yararlanma hakkı verdiğini belirtir.
Bu yöntemler, uygulamanızın yeniden satın alma için kullanılabilen giriş satın alma jetonuna karşılık gelen tek seferlik ürünü sunmasını da sağlar. consumeAsync()
ile ConsumeResponseListener
arayüzünü uygulayan bir nesne de iletmeniz gerekir. Bu nesne, tüketim işleminin sonucunu işler. İşlem tamamlandığında Google Play Faturalandırma Kitaplığı'nın çağırdığı onConsumeResponse()
yöntemini geçersiz kılabilirsiniz.
Aşağıdaki örnekte, ilişkili satın alma jetonu kullanılarak Google Play Faturalandırma Kitaplığı'nda bir ürünün tüketilmesi gösterilmektedir:
Kotlin
suspend fun handlePurchase(purchase: Purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener. val purchase : Purchase = ...; // Verify the purchase. // Ensure entitlement was not already granted for this purchaseToken. // Grant entitlement to the user. val consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build() val consumeResult = withContext(Dispatchers.IO) { client.consumePurchase(consumeParams) } }
Java
void handlePurchase(Purchase purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener. Purchase purchase = ...; // Verify the purchase. // Ensure entitlement was not already granted for this purchaseToken. // Grant entitlement to the user. ConsumeParams consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); ConsumeResponseListener listener = new ConsumeResponseListener() { @Override public void onConsumeResponse(BillingResult billingResult, String purchaseToken) { if (billingResult.getResponseCode() == BillingResponseCode.OK) { // Handle the success of the consume operation. } } }; billingClient.consumeAsync(consumeParams, listener); }
Sarf Malzemesi Olmayan Ürünler
Uygulamanızın güvenli bir arka ucu varsa tüketilemez satın alma işlemlerini onaylamak için Purchases.products:acknowledge
kullanarak satın alma işlemlerini güvenilir bir şekilde onaylamanızı öneririz. Purchases.products:get
araması sonucunda gösterilen acknowledgementState
değerini kontrol ederek satın alma işleminin daha önce onaylanmadığından emin olun.
Uygulamanız yalnızca müşterilere yönelikse uygulamanızdaki Google Play Faturalandırma Kitaplığı'nda bulunan BillingClient.acknowledgePurchase()
öğesini kullanın. Bir satın alma işlemini onaylamadan önce Google Play Faturalandırma Kitaplığı'ndaki isAcknowledged()
yöntemini kullanarak uygulamanızın onaylanıp onaylanmadığını kontrol etmesi gerekir.
Aşağıdaki örnekte, bir satın alma işleminin Google Play Faturalandırma Kitaplığı kullanılarak nasıl onaylanacağı gösterilmektedir:
Kotlin
val client: BillingClient = ... val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ... suspend fun handlePurchase() { if (purchase.purchaseState === PurchaseState.PURCHASED) { if (!purchase.isAcknowledged) { val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) val ackPurchaseResult = withContext(Dispatchers.IO) { client.acknowledgePurchase(acknowledgePurchaseParams.build()) } } } }
Java
BillingClient client = ... AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ... void handlePurchase(Purchase purchase) { if (purchase.getPurchaseState() == PurchaseState.PURCHASED) { if (!purchase.isAcknowledged()) { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener); } } }
Abonelikler
Abonelikler, tüketilebilir olmayan öğelere benzer şekilde işlenir. Mümkünse güvenli arka ucunuzdan satın alma işlemini güvenilir bir şekilde onaylamak için Google Play Developer API'sindeki Purchases.subscriptions.acknowledge
aracını kullanın. Purchases.subscriptions:get
alanındaki satın alma kaynağındaki acknowledgementState
öğesini kontrol ederek satın alma işleminin daha önce onaylanmadığını doğrulayın. Aksi takdirde, isAcknowledged()
adresini kontrol ettikten sonra Google Play Faturalandırma Kitaplığı'nda BillingClient.acknowledgePurchase()
öğesini kullanarak aboneliği onaylayabilirsiniz. Tüm ilk abonelik satın alma işlemlerinin onaylanması gerekir. Abonelik yenilemelerinin onaylanması gerekmez. Aboneliklerin ne zaman onaylanması gerektiği hakkında daha fazla bilgi için Abonelik satma konusuna bakın.
Satın alınanlar getiriliyor
Satın alma güncellemelerini PurchasesUpdatedListener
kullanarak dinlemek, uygulamanızın tüm satın alma işlemlerini işlemesini sağlamak için yeterli değildir. Uygulamanız, kullanıcının gerçekleştirdiği tüm satın alma işlemlerinden haberdar olmayabilir. Uygulamanızın takip edilememesine yol açabilecek veya satın alma işlemlerinin farkında olmayabilecek bazı senaryolar aşağıda verilmiştir:
- Satın alma işlemi sırasında karşılaşılan Ağ Sorunları: Kullanıcı, başarılı bir satın alma işlemi gerçekleştirir ve Google'dan onay alır, ancak cihazı
PurchasesUpdatedListener
üzerinden satın alma işlemiyle ilgili bildirim almadan önce cihazının ağ bağlantısı kesilir. - Birden fazla cihaz: Kullanıcı bir cihazdan bir öğe satın alır ve daha sonra cihaz değiştirdiğinde bu öğeyi görmeyi bekler.
- Uygulamanızın dışında yapılan satın alma işlemlerini işleme: Promosyon kullanımı gibi bazı satın alma işlemleri, uygulamanızın dışında yapılabilir.
Bu durumların üstesinden gelmek için uygulamanızın onResume()
yönteminizde BillingClient.queryPurchasesAsync()
çağrısı yaptığından ve tüm satın alma işlemlerinin satın alma işlemlerini işleme bölümünde açıklandığı gibi başarıyla işlendiğinden emin olun.
Aşağıdaki örnekte, bir kullanıcının abonelik satın alma işlemlerinin nasıl getirileceği gösterilmektedir.
queryPurchasesAsync()
hizmetinin yalnızca etkin abonelikleri ve tüketilmemiş tek seferlik satın alımları döndürdüğünü unutmayın.
Kotlin
val params = QueryPurchasesParams.newBuilder() .setProductType(ProductType.SUBS) // uses queryPurchasesAsync Kotlin extension function val purchasesResult = billingClient.queryPurchasesAsync(params.build()) // check purchasesResult.billingResult // process returned purchasesResult.purchasesList, e.g. display the plans user owns
Java
billingClient.queryPurchasesAsync( QueryPurchasesParams.newBuilder() .setProductType(ProductType.SUBS) .build(), new PurchasesResponseListener() { public void onQueryPurchasesResponse(BillingResult billingResult, Listpurchases) { // check billingResult // process returned purchase list, e.g. display the plans user owns } } );
İşlem geçmişi getiriliyor
queryPurchaseHistoryAsync()
, kullanıcının her ürün için yaptığı en son satın alma işlemini döndürür (satın alma işleminin süresi dolmuş, iptal edilmiş veya tüketilmiş olsa bile).
Kotlin uzantılarını kullanıyorsanız queryPurchaseHistory()
uzantı işlevini kullanabilirsiniz.
Kotlin
val params = QueryPurchaseHistoryParams.newBuilder() .setProductType(ProductType.SUBS) // uses queryPurchaseHistory Kotlin extension function val purchaseHistoryResult = billingClient.queryPurchaseHistory(params.build()) // check purchaseHistoryResult.billingResult // process returned purchaseHistoryResult.purchaseHistoryRecordList, e.g. display purchase
Java
billingClient.queryPurchaseHistoryAsync( QueryPurchaseHistoryParams.newBuilder() .setProductType(ProductType.SUBS) .build(), new PurchaseHistoryResponseListener() { public void onPurchaseHistoryResponse( BillingResult billingResult, ListpurchasesHistoryList) { // check billingResult // process returned purchase history list, e.g. display purchase history } } );
Uygulamanızın dışında yapılan satın alma işlemlerini işleme
Promosyon kullanımları gibi bazı satın alma işlemleri, uygulamanızın dışında gerçekleşebilir. Bir kullanıcı, uygulamanızın dışında satın alma işlemi gerçekleştirdiğinde, uygulamanızın uygulama içi bir mesaj göstermesini bekler veya uygulamanın satın alma işlemini doğru bir şekilde aldığını ve işlediğini kullanıcıya bildirmek için bir tür bildirim mekanizması kullanır. Kabul edilebilir mekanizmalardan bazıları şunlardır:
- Uygulama içi pop-up göster.
- Mesajı uygulama içi mesaj kutusuna iletin ve bu uygulama içi mesaj kutusunda yeni bir mesaj olduğunu açıkça belirtin.
- İşletim sistemi bildirim mesajı kullanın.
Uygulamanızın satın alma işlemini algıladığı herhangi bir durumda olabileceğini unutmayın. Hatta satın alma işlemi yapıldığında uygulamanız yüklenmemiş olabilir. Kullanıcılar, uygulamanın durumundan bağımsız olarak uygulamayı devam ettirdiklerinde satın alma işlemlerini almayı beklerler.
Satın alma işlemlerini, uygulamanın satın alma işleminin yapıldığı eyaletten bağımsız olarak tespit etmeniz gerekir. Bununla birlikte, öğenin alındığını kullanıcıya hemen bildirmemenin kabul edilebilir olduğu bazı istisnalar vardır. Örneğin:
- Oyunun, mesaj göstermenin kullanıcının dikkatini dağıtabileceği aksiyon kısmı. Bu durumda, işlem bölümü bittikten sonra kullanıcıyı bilgilendirmeniz gerekir.
- Ara sahnelerde mesaj göstermek kullanıcının dikkatini dağıtabilir. Bu durumda, ara sahne sona erdikten sonra kullanıcıyı bilgilendirmeniz gerekir.
- Oyunun ilk eğitim ve kullanıcı kurulumu kısımları sırasında. Yeni kullanıcılara, oyunu açtıktan hemen sonra veya ilk kullanıcı kurulumu sırasında ödül hakkında bilgi vermenizi öneririz. Bununla birlikte, kullanıcıyı bilgilendirmek için ana oyun sırasının hazır olmasını bekleyebiliriz.
Uygulamanızın dışında yapılan satın alma işlemlerini kullanıcılarınıza ne zaman ve nasıl bildireceğinize karar verirken her zaman kullanıcıyı aklınızda bulundurun. Bir kullanıcı hemen bir bildirim almadığında kafası karışabilir ve uygulamanızı kullanmayı bırakabilir, kullanıcı desteğiyle iletişime geçebilir veya sosyal medyada şikayette bulunabilir. Not: PurchasesUpdatedListener
, uygulamanızın dışında başlatılan satın alma işlemleri de dahil olmak üzere satın alma güncellemelerini işlemek için uygulama bağlamınıza kaydedilmiştir. Bu, uygulama işleminiz mevcut değilse PurchasesUpdatedListener
cihazınıza bildirilmeyeceği anlamına gelir. Bu nedenle uygulamanız, Satın Alma İşlemleri bölümünde belirtildiği gibi onResume()
yöntemini kullanarak BillingClient.queryPurchasesAsync()
çağırmalıdır.
Bekleyen işlemleri yönetme
Google Play, bekleyen işlemleri veya kullanıcının satın alma işlemi başlatması ile satın alma işleminin ödeme yönteminin işlenmesi arasında bir veya daha fazla ek adım gerektiren işlemleri destekler. Google, kullanıcının ödeme yönteminden başarıyla ödeme alındığını bildirene kadar uygulamanız bu tür satın alma işlemlerinde yetki vermemelidir.
Örneğin, bir kullanıcı ödeme şekli olarak nakit seçeneğini belirleyerek bir uygulama içi öğe için PENDING
satın alma işlemi oluşturabilir. Kullanıcı daha sonra işlemi tamamlayacağı ve hem bildirim hem de e-posta yoluyla bir kod alacağı fiziksel bir mağaza seçebilir. Kullanıcı fiziksel mağazaya geldiğinde kodu kasiyere kullanabilir ve nakit ödeme yapabilir. Google daha sonra hem size hem de kullanıcıya nakit alındığını bildirir. Uygulamanız daha sonra
kullanıcıya yararlanma hakkı verebilir.
Uygulamanız, başlatma işleminin bir parçası olarak enablePendingPurchases()
çağrısı yaparak beklemedeki işlemleri desteklemelidir.
Uygulamanız PurchasesUpdatedListener
cihazınızla veya queryPurchasesAsync()
çağrısının sonucu olarak yeni bir satın alma işlemi aldığında satın alma durumunun PURCHASED
veya PENDING
olduğunu belirlemek için getPurchaseState()
yöntemini kullanın.
Kullanıcı satın alma işlemini tamamladığında uygulamanız çalışıyorsa PurchasesUpdatedListener
yeniden çağrılır ve PurchaseState
artık PURCHASED
olur. Bu noktada, uygulamanız satın alma işlemini tek seferlik satın alma işlemlerini işleme için standart yöntemi kullanarak işleyebilir. Uygulamanız ayrıca,
çalışmadığı sırada PURCHASED
durumuna geçirilen satın alma işlemlerini gerçekleştirmek için uygulamanızın onResume()
yönteminde queryPurchasesAsync()
çağrısı yapmalıdır.
Uygulamanız ayrıca OneTimeProductNotifications
dinleyerek bekleyen satın alma işlemleri için Gerçek zamanlı geliştirici bildirimlerini kullanabilir. Satın alma işlemi PENDING
tarihinden PURCHASED
uygulamasına geçtiğinde, uygulamanız bir ONE_TIME_PRODUCT_PURCHASED
bildirimi alır. Satın alma işlemi iptal edilirse uygulamanız bir ONE_TIME_PRODUCT_CANCELED
bildirimi alır. Bu durum, müşteriniz ödemeyi gereken süre içinde tamamlamazsa ortaya çıkabilir. Bu bildirimleri alırken, Purchases.products
için PENDING
durumunu içeren Google Play Developer API'yi kullanabilirsiniz.
Bu senaryonun nasıl test edileceğiyle ilgili ayrıntılı adımları Bekleyen satın alma işlemlerini test etme bölümünde bulabilirsiniz.
Çoklu miktar satın alma işlemlerini yönetme
Google Play Faturalandırma Kitaplığı'nın 4.0 ve sonraki sürümlerinde desteklenen Google Play, müşterilerin satın alma sepetindeki bir miktarı belirterek aynı uygulama içi üründen birden fazla işlem satın almasına olanak tanır. Uygulamanızın çoklu miktar satın alma işlemlerini gerçekleştirmesi ve belirtilen satın alma miktarına göre yararlanma hakkı vermesi beklenir.
Çoklu miktar satın alma işlemlerini karşılamak için uygulamanızın temel hazırlık mantığının öğe miktarını kontrol etmesi gerekir. quantity
alanına aşağıdaki API'lerin birinden erişebilirsiniz:
- Google Play Faturalandırma Kitaplığı'ndan
getQuantity()
. - Google Play Developer API'den
Purchases.products.quantity
.
Çoklu miktar satın alma işlemlerini işleme mantığını ekledikten sonra, Google Play Geliştirici Konsolu'ndaki uygulama içi ürün yönetimi sayfasında ilgili ürün için çoklu miktar özelliğini etkinleştirmeniz gerekir.
Kullanıcının Faturalandırma Yapılandırmasını Sorgulama
getBillingConfigAsync()
, kullanıcının Google Play için kullandığı ülkeyi belirtir.
BillingClient
oluşturduktan sonra kullanıcının faturalandırma yapılandırmasını sorgulayabilirsiniz. Aşağıdaki kod snippet'inde getBillingConfigAsync()
çağrısının nasıl yapılacağı açıklanmaktadır. BillingConfigResponseListener
uygulayarak yanıtı ele alın. Bu işleyici, uygulamanızdan başlatılan tüm faturalandırma yapılandırması sorguları için güncelleme alır.
Döndürülen BillingResult
hiç hata içermiyorsa BillingConfig
nesnesindeki countryCode
alanını kontrol ederek kullanıcının Play Country'sini edinebilirsiniz.
Kotlin
// Use the default GetBillingConfigParams.
val getBillingConfigParams = GetBillingConfigParams.newBuilder().build()
billingClient.getBillingConfigAsync(getBillingConfigParams,
object : BillingConfigResponseListener {
override fun onBillingConfigResponse(
billingResult: BillingResult,
billingConfig: BillingConfig?
) {
if (billingResult.responseCode == BillingResponseCode.OK
&& billingConfig != null) {
val countryCode = billingConfig.countryCode
...
} else {
// TODO: Handle errors
}
}
})
Java
// Use the default GetBillingConfigParams.
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build();
billingClient.getBillingConfigAsync(getBillingConfigParams,
new BillingConfigResponseListener() {
public void onBillingConfigResponse(
BillingResult billingResult, BillingConfig billingConfig) {
if (billingResult.getResponseCode() == BillingResponseCode.OK
&& billingConfig != null) {
String countryCode = billingConfig.getCountryCode();
...
} else {
// TODO: Handle errors
}
}
});