Bu konu, ürün satmaya başlamak için Google Play Faturalandırma Kitaplığı'nı uygulamanıza nasıl entegre edeceğinizi açıklamaktadır.
Bir satın alma süreci
Tek seferlik satın alma işlemi veya abonelik için tipik bir satın alma akışı aşağıda verilmiştir.
- Kullanıcıya neler satın alabileceklerini 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 sunun.
- İçeriğin teslim edildiğini onaylama. Tüketilebilir ürünlerde, kullanıcının ürünü tekrar satın alabilmesi için satın alma işlemini tüketin.
Abonelikler, iptal edilene kadar otomatik olarak yenilenir. Abonelikler aşağıdaki durumlardan geçebilir:
- Etkin: Kullanıcının durumu iyidir ve aboneliğe erişimi vardır.
- İptal edildi: Kullanıcı aboneliğini iptal etmiş ancak geçerlilik süresi sona erene kadar erişmeye devam edebilir.
- Ek süre içinde: Kullanıcı ödeme sorunuyla karşılaşmış ancak Google ödeme yöntemini tekrar denemeye devam ederken erişime devam etmektedir.
- Askıya alındı: Kullanıcı ödeme sorunuyla karşılaştı ve Google ödeme yöntemini tekrar dener. Bu sırada kullanıcının erişimi kaldırılır.
- Duraklatıldı: Kullanıcı erişimini duraklatmıştır ve erişimi, duraklatma işlemini geri alana kadar devam etmez.
- Süresi doldu: Kullanıcı, aboneliği iptal etti ve aboneliğe erişimi kaybetti. Kullanıcı, süre sona erdiğinde kullanımdan kaldırılmış olarak kabul edilir.
Google Play bağlantısını ilk kullanıma hazırlayın
Google Play'in faturalandırma sistemiyle entegrasyona ilk adım olarak Google Play Faturalandırma Kitaplığı'nı uygulamanıza eklemeniz ve bir bağlantı başlatmanız gerekir.
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 gösterildiği gibi ekleyin:
Eski
dependencies { def billing_version = "7.0.0" implementation "com.android.billingclient:billing:$billing_version" }
Kotlin
dependencies { val billing_version = "7.0.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ş yordam desteği içerir. Bu uzantıları projenize dahil etmek için uygulamanızın build.gradle
dosyasına aşağıdaki bağımlılığı ekleyin:
Eski
dependencies { def billing_version = "7.0.0" implementation "com.android.billingclient:billing-ktx:$billing_version" }
Kotlin
dependencies { val billing_version = "7.0.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
BillingClient'ı başlatma
Google Play Faturalandırma Kitaplığı'na bir 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şimin ana arayüzüdür. BillingClient
, birçok yaygın faturalandırma işlemi için hem senkronize hem de eşzamansız kolaylık yöntemleri sağlar. Tek bir etkinlik için birden fazla PurchasesUpdatedListener
geri çağırma işlemini önlemek amacıyla aynı anda bir etkin BillingClient
bağlantınızın açık olması önemle tavsiye edilir.
BillingClient
oluşturmak için newBuilder()
simgesini kullanın. newBuilder()
'e herhangi bir bağlam iletebilirsiniz. BillingClient
, uygulama bağlamı almak için bu bağlamı kullanır.
Bu nedenle, bellek sızıntıları konusunda endişelenmenize gerek yoktur. Satın alma işlemleriyle ilgili güncellemeleri almak için setListener()
numaralı telefonu arayıp bir PurchasesUpdatedListener
öğesine referans vermeniz gerekir. Bu dinleyici, uygulamanızdaki tüm satın alma işlemleriyle ilgili güncellemeleri alır.
Kotlin
private val purchasesUpdatedListener = PurchasesUpdatedListener { billingResult, purchases -> // To be implemented in a later section. } private var billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) // Configure other settings. .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) // Configure other settings. .build();
Google Play'e bağlanma
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ı süreci eşzamansızdır. İstemci kurulumu tamamlandıktan sonra ve istemci başka istekler yapmaya hazır olduğunda geri çağırma almak için bir BillingClientStateListener
uygulamanız gerekir.
Google Play ile bağlantı kaybını ele almak için yeniden deneme mantığını da uygulamanız gerekir.
Tekrar deneme mantığını uygulamak için onBillingServiceDisconnected()
geri çağırma yöntemini geçersiz kılın ve BillingClient
'ın başka istek göndermeden önce Google Play'e yeniden bağlanmak için startConnection()
yöntemini çağırdığından emin olun.
Aşağıdaki örnekte, bir bağlantının nasıl başlatılacağı ve kullanıma hazır olup olmadığı nasıl test edileceği 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österme
Google Play ile bağlantı kurduktan sonra, mevcut ürünlerinizi sorgulamaya ve kullanıcılarınıza göstermeye hazırsınız demektir.
Ürün ayrıntılarını sorgulamak, yerelleştirilmiş ürün bilgileri döndürdüğü için ürünlerinizi kullanıcılarınıza göstermeden önce atmanız gereken ö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.
Asenkron işlemin sonucunu işlemek için ProductDetailsResponseListener
arayüzünü uygulayan bir dinleyici de belirtmeniz gerekir.
Ardından, aşağıdaki örnekte gösterildiği gibi, sorgu tamamlandığında dinleyiciyi bilgilendiren onProductDetailsResponse()
işlevini 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 bir ProductType
ile birlikte belirten QueryProductDetailsParams
örneğini iletin. ProductType
, tek seferlik ürünler için ProductType.INAPP
veya abonelikler için ProductType.SUBS
olabilir.
Kotlin uzantılarıyla sorgu oluşturma
Kotlin uzantılarını kullanıyorsanız queryProductDetails()
uzantı işlevini çağırarak uygulama içi ürün ayrıntılarını sorgulayabilirsiniz.
queryProductDetails()
, ayrı bir dinleyici tanımlamanıza gerek kalmaması için Kotlin coroutine'lerinden yararlanır. Bunun yerine işlev, sorgulama tamamlanıncaya kadar askıya alınır, ardından sonucu işleyebilirsiniz:
suspend fun processPurchases() {
val productList = listOf(
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.
}
Bazı cihazlar, genellikle Google Play Hizmetleri'nin eski sürümleri nedeniyle nadiren ProductDetails
ve queryProductDetailsAsync()
'ü destekleyemez. Bu senaryoda uygun destek alabilmeniz için Play Faturalandırma Kitaplığı 5'e geçiş kılavuzundaki geriye dönük uyumluluk özelliklerini nasıl kullanacağınızı öğrenin.
Sonucu işleme
Google Play Faturalandırma Kitaplığı, sorgu sonuçlarını ProductDetails
nesnelerinden oluşan bir List
içinde saklar. Ardından, uygulama içi bir ürünle ilgili alakalı bilgileri (ör. fiyat veya açıklama) görüntülemek için listedeki her ProductDetails
nesnesi üzerinde çeşitli yöntemler çağırabilirsiniz. Mevcut ürün ayrıntısı bilgilerini görüntülemek için ProductDetails
sınıfındaki yöntemlerin listesine bakın.
Bir öğeyi satışa sunmadan önce, kullanıcının söz konusu öğeye sahip olup olmadığını kontrol edin. Kullanıcının öğe kitaplığında hâlâ bir tüketim öğesi varsa yeniden satın almadan önce öğeyi tüketmesi gerekir.
Abonelik sunmadan önce kullanıcının abone olmadığından emin olun. 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 teklifi satın almaya çalışırsa (ör. uygulama, uygun tekliflerin güncel olmayan bir listesini gösteriyorsa) Play kullanıcıyı uygun olmadığını bilgilendirir 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ığında launchBillingFlow()
yöntemini çağırın. Bu yöntem, queryProductDetailsAsync()
çağrıldıktan sonra elde edilen ilgili ProductDetails
nesnesini içeren bir BillingFlowParams
nesnesine referans alır. 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) // For One-time product, "setOfferToken" method shouldn't be called. // For subscriptions, 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 = ...; ImmutableList<ProductDetailsParams> productDetailsParamsList = ImmutableList.of( ProductDetailsParams.newBuilder() // retrieve a value for "productDetails" by calling queryProductDetailsAsync() .setProductDetails(productDetails) // For one-time products, "setOfferToken" method shouldn't be called. // For subscriptions, to get an offer token, call // ProductDetails.subscriptionOfferDetails() 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
içinde listelenen çeşitli yanıt kodlarından birini döndürür. Satın alma akışı başlatılırken hata olmadığından emin olmak için bu sonucu kontrol edin. BillingResponseCode
OK
, başarılı bir lansmanı gösterir.
launchBillingFlow()
çağrısı başarılı olduğunda sistem Google Play satın alma ekranını gösterir. Şekil 1'de bir aboneliğin satın alma ekranı gösterilmektedir:
Google Play, satın alma işleminin sonucunu PurchasesUpdatedListener
arayüzünü uygulayan bir dinleyiciye iletmek için onPurchasesUpdated()
işlevini çağırır. Dinleyici, 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()
değerinin 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 işlemi başarılı ekranı oluşturur.
Başarılı satın alma işlemleri, 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, satın alma işlemini doğrulayıp sahtekarlığa karşı koruma sağlayabileceğiniz güvenli arka uç sunucunuza aktarmanızı öneririz. Bu süreç aşağıdaki bölümde daha ayrıntılı olarak açıklanmıştır.
Kullanıcıya, işlemin sipariş kimliğinin veya benzersiz kimliğinin yer aldığı bir fatura e-postası da gönderilir. Kullanıcılar, her tek seferlik ürün satın alma işleminin yanı sıra ilk abonelik satın alma işlemi ve 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ğini kullanabilirsiniz.
Kişiselleştirilmiş bir fiyat belirtme
Uygulamanız Avrupa Birliği'ndeki kullanıcılara dağıtılabiliyorsa kullanıcılara bir öğenin fiyatının otomatik karar verme sistemi kullanılarak kişiselleştirildiğini açıklamak için setIsOfferPersonalized()
yöntemini kullanın.
Google, DSA Madde 21(2) 2011/83/AB Tüketici Hakları Yönergesi'nin 6. (1) (ea) maddesine bakın.
setIsOfferPersonalized()
, boole girişi alır. Açıklama, true
olduğunda Play kullanıcı arayüzünde
yer alır. false
olduğunda kullanıcı arayüzü açıklamayı atlar. Varsayılan değer false
'tir.
Daha fazla bilgi için Tüketici Yardım Merkezi'ne göz atın.
Satın alma işlemleri
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ız satın alma işlemleriyle ilgili bildirimleri PurchasesUpdatedListener
üzerinden alır. Bununla birlikte, Satın alma işlemlerini getirme bölümünde açıklandığı gibi, uygulamanızın BillingClient.queryPurchasesAsync()
çağrısı yapılarak satın alma işlemlerinden haberdar edileceği durumlar vardır.
Ayrıca, güvenli arka ucunuzda Gerçek Zamanlı Geliştirici Bildirimleri istemcisi varsa yeni bir satın alma işlemi konusunda sizi uyaran bir subscriptionNotification
veya oneTimeProductNotification
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, satın alma işlemlerini aşağıdaki şekilde işlemelidir:
- Satın alma işlemini doğrulayın.
- Kullanıcıya içerik verin ve içeriğin teslim edildiğini onaylayın. İsteğe bağlı olarak, kullanıcının öğeyi tekrar satın alabilmesi için öğeyi kullanılmış olarak işaretleyin.
Bir satın alma işlemini doğrulamak için önce satın alma durumunun PURCHASED
olduğunu kontrol edin. Satın alma işlemi PENDING
ise satın alma işlemini Bekleyen işlemleri yönetme bölümünde açıklandığı şekilde işlemeniz gerekir. onPurchasesUpdated()
veya queryPurchasesAsync()
'ten alınan satın alma işlemleri için, uygulamanızın uygunluk izni vermeden önce satın alma işleminin meşru olduğundan emin olmak üzere işlemi daha ayrıntılı bir şekilde doğrulamanız gerekir. Bir satın alma işlemini nasıl doğrulayacağınızı öğrenmek için Haklardan yararlanma hakkı vermeden önce satın alma işlemlerini doğrulama başlıklı makaleyi inceleyin.
Satın alma işlemini doğruladıktan sonra uygulamanız, kullanıcıya erişim izni vermeye hazırdır. Satın alma işlemiyle ilişkili kullanıcı hesabı, sunucu tarafında uygulama içi ürün satın alma işlemleri için Purchases.products:get
tarafından döndürülen ProductPurchase.obfuscatedExternalAccountId
ve abonelikler için Purchases.subscriptions:get
tarafından döndürülen SubscriptionPurchase.obfuscatedExternalAccountId
ile veya satın alma işlemi yapılırken setObfuscatedAccountId
ile ayarlanmışsa istemci tarafında Purchase.getAccountIdentifiers()
'ten gelen obfuscatedAccountId
ile tanımlanabilir.
Yetki verdikten sonra uygulamanız satın alma işlemini onaylamalıdır. Bu onay işlemi, satın alma için yetki verdiğinizi Google Play'e bildirir.
Kullanım hakkı verme ve satın alma işlemini onaylama süreci, satın alınan öğenin tüketim amaçlı, tüketim amaçlı olmayan veya abonelik olup olmadığına bağlıdır.
Tüketim Ürünleri
Uygulamanızda güvenli bir arka uç varsa tüketim ürünleri için satın alma işlemlerini güvenilir bir şekilde kullanmak üzere Purchases.products:consume
kullanmanızı öneririz. Purchases.products:get
çağrısının sonucundaki consumptionState
değerini kontrol ederek satın alma işleminin daha önce tüketilmediğinden emin olun. Uygulamanız arka uç olmadan yalnızca istemci ise Google Play Faturalandırma Kitaplığı'ndan consumeAsync()
işlevini kullanın. Her iki yöntem de onay şartını karşılar ve uygulamanızın kullanıcıya yararlanma hakkı verdiğini gösterir.
Bu yöntemler, uygulamanızın giriş satın alma jetonuna karşılık gelen tek seferlik ürünü yeniden satın alınabilir hale getirmesini de sağlar. consumeAsync()
ile birlikte ConsumeResponseListener
arayüzünü uygulayan bir nesne de göndermeniz gerekir. Bu nesne, tüketim işleminin sonucunu işler. Google Play Faturalandırma Kitaplığı'nın işlem tamamlandığında çağırdığı onConsumeResponse()
yöntemini geçersiz kılabilirsiniz.
Aşağıdaki örnekte, ilişkili satın alma jetonunu kullanarak Google Play Faturalandırma Kitaplığı ile bir ürünün nasıl kullanılacağı 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ızda güvenli bir arka uç varsa tüketilemeyen satın alma işlemlerini onaylamak için Purchases.products:acknowledge
yöntemini kullanarak satın alma işlemlerini güvenilir bir şekilde onaylamanızı öneririz. Purchases.products:get
çağrısının sonucundaki acknowledgementState
öğesini kontrol ederek satın alma işleminin daha önce onaylanmadığından emin olun.
Uygulamanız yalnızca istemci ise uygulamanızda Google Play Faturalandırma Kitaplığı'ndan BillingClient.acknowledgePurchase()
yöntemini kullanın. Uygulamanız, bir satın alma işlemini onaylamadan önce Google Play Faturalandırma Kitaplığı'ndaki isAcknowledged()
yöntemini kullanarak işlemin daha önce onaylanıp onaylanmadığını kontrol etmelidir.
Aşağıdaki örnekte, Google Play Faturalandırma Kitaplığı kullanılarak bir satın alma işleminin nasıl onaylandığı 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üketilmeyen öğelere benzer şekilde işlenir. Mümkünse güvenli arka uçtan satın alma işlemini güvenilir bir şekilde onaylamak için Google Play Developer API'deki Purchases.subscriptions.acknowledge
yöntemini kullanın. Purchases.subscriptions:get
kaynağındaki satın alma kaynağında acknowledgementState
değerini kontrol ederek satın alma işleminin daha önce kabul edilmediğinden emin olun. Aksi takdirde, isAcknowledged()
'i işaretledikten sonra Google Play Faturalandırma Kitaplığı'ndan BillingClient.acknowledgePurchase()
'ü 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 alma işlemlerini getirme
PurchasesUpdatedListener
kullanarak satın alma güncellemelerini 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 yaptığı tüm satın alma işlemlerinden haberdar olmayabilir. Uygulamanızın satın alma işlemlerini takip edemeyeceği veya satın alma işlemlerinden haberdar olmayacağı bazı senaryolar aşağıda verilmiştir:
- Satın alma işlemi sırasında 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 ağ bağlantısını kaybeder. - Birden fazla cihaz: Kullanıcı bir cihazda ürün satın alır ve ardından cihaz değiştirdiğinde ürünü görmeyi bekler.
- Uygulamanız dışında yapılan satın alma işlemlerini yönetme: Promosyon kullanımları gibi bazı satın alma işlemleri uygulamanızın dışında yapılabilir.
Bu durumları ele almak için uygulamanızın, tüm satın alma işlemlerinin satın alma işlemlerini işleme bölümünde açıklandığı şekilde başarıyla işlenmesini sağlamak amacıyla onResume()
yönteminizde BillingClient.queryPurchasesAsync()
çağrısında bulunduğundan emin olun.
Aşağıdaki örnekte, bir kullanıcının abonelik satın alma işlemlerinin nasıl getirileceği gösterilmektedir.
queryPurchasesAsync()
işlevinin yalnızca etkin abonelikleri ve tüketilmemiş tek seferlik satın alma işlemlerini 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, List<Purchase> purchases) { // check billingResult // process returned purchase list, e.g. display the plans user owns } } );
Uygulamanızın dışından yapılan satın alma işlemlerini işleme
Promosyon kullanımları veya Google Play Games uygulama içi satın alma işlemleri (UİSA) için alışveriş sepetini terk etme hatırlatıcıları gibi bazı satın alma işlemleri uygulamanızın dışında gerçekleşebilir. Kullanıcılar uygulamanızın dışında satın alma işlemi yaptığında, uygulamanızın bir uygulama içi mesaj göstermesini veya satın alma işleminin doğru şekilde alındığını ve işlendiğini bildirmek için bir tür bildirim mekanizması kullanmasını bekler. Kabul edilen mekanizmalardan bazıları şunlardır:
- Uygulama içi pop-up göster.
- İletiyi bir uygulama içi mesaj kutusuna gönderin ve uygulama içi mesaj kutusunda yeni bir ileti olduğunu açıkça belirtin.
- OS bildirim mesajı kullanın.
Uygulamanız, satın alma işlemini tanıdığında herhangi bir durumda olabilir. Satın alma işlemi yapıldığında uygulamanızın yüklü olmaması bile mümkündür. Kullanıcılar, uygulamanın durumundan bağımsız olarak uygulamayı devam ettirdiklerinde satın aldıkları ürünü elde etmeyi beklerler.
Uygulamanın satın alma işleminin yapıldığı durumlardan bağımsız olarak satın alma işlemlerini algılamanız gerekir. Ancak, kullanıcıyı ürünün elinize ulaştığı konusunda hemen bilgilendirmemenizin kabul edilebilir olabileceği bazı istisnalar vardır. Örnek:
- Oyunun işlem bölümünde mesaj göstermek, kullanıcının dikkatini dağıtabilir. Bu durumda, işlem bölümü sona erdikten sonra kullanıcıyı bilgilendirmeniz gerekir.
- Mesaj göstermenin kullanıcının dikkatini dağıtabileceği ara sahneler sırasında. 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ıları, oyunu açtıktan hemen sonra veya ilk kullanıcı ayarlaması sırasında ödül hakkında bilgilendirmenizi öneririz. Ancak kullanıcıyı bilgilendirmek için ana oyun sekansı hazır olana kadar beklemek kabul edilebilir.
Kullanıcılarınızı uygulamanız dışında yapılan satın alma işlemleri hakkında ne zaman ve nasıl bilgilendireceğinize karar verirken her zaman kullanıcıyı göz önünde bulundurun. Kullanıcılar hemen bildirim almadığında kafaları karışabilir, uygulamanızı kullanmayı bırakabilir, kullanıcı desteğiyle iletişime geçebilir veya sosyal medyada bu konuda şikayette bulunabilir.
Google Play Games ana sayfasında Alışveriş Sepetini Terk Etme Hatırlatıcıları (varsayılan olarak etkindir)
IAP üzerinden para kazanan oyun geliştiricileri, Google Play Console'da etkin olan stok tutma birimlerini (SKU'ları) uygulamalarının dışında satmanın bir yolu olarak alışveriş sepetini terk etme hatırlatıcısı özelliğini kullanabilir. Bu özellik, kullanıcıları Google Play Store'da gezinirken daha önce terk ettikleri satın alma işlemlerini tamamlamaya teşvik eder. Bu satın alma işlemleri, uygulamanızın dışında, Google Play Store'daki Google Play Games ana sayfasından gerçekleşir.
Kullanıcıların kalkıştıkları yerden devam etmelerine ve geliştiricilerin satışları en üst düzeye çıkarmalarına yardımcı olmak için bu özellik varsayılan olarak etkindir. Ancak Alışveriş sepetini terk etme hatırlatıcısı özelliğini devre dışı bırakma formunu göndererek uygulamanızı bu özelliğin kapsamı dışında tutabilirsiniz. Google Play Console'da SKU'ları yönetmeyle ilgili en iyi uygulamalar için Uygulama içi ürün oluşturma başlıklı makaleyi inceleyin.
Aşağıdaki resimlerde, Google Play Store'da görünen Alışveriş Sepetini Terk Etme Hatırlatıcısı gösterilmektedir:
Beklemedeki işlemleri işleme
Google Play, beklemedeki işlemleri veya kullanıcının satın alma işlemini başlattığı ile satın alma işleminin ödeme yönteminin işlendiği 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şlemleri için yararlanma hakkı vermemelidir.
Örneğin, bir kullanıcı daha sonra nakit ödeme yapacağı fiziksel bir mağaza seçerek işlem başlatabilir. Kullanıcıya hem bildirim hem de e-posta yoluyla bir kod gönderilir. Kullanıcı fiziksel mağazaya geldiğinde kodu kasiyerle değiştirip nakit ödeme yapabilir. Daha sonra Google, ödemenin alındığını hem size hem de kullanıcıya bildirir. Ardından uygulamanız kullanıcıya hak verebilir.
Uygulamanız için bekleyen işlemleri etkinleştirmek üzere BillingClient
'ı başlatmanın bir parçası olarak enablePendingPurchases()
'i çağırın. Uygulamanız, tek seferlik ürünler için bekleyen işlemleri etkinleştirmeli ve desteklemelidir. Destek eklemeden önce bekleyen işlemler için satın alma yaşam döngüsünü anladığınızdan emin olun.
Uygulamanız PurchasesUpdatedListener
aracılığıyla veya queryPurchasesAsync()
çağrılması sonucunda yeni bir satın alma işlemi aldığında, satın alma durumunun PURCHASED
mı yoksa PENDING
mi olduğunu belirlemek için getPurchaseState()
yöntemini kullanın. Yararlanma hakkını yalnızca durum PURCHASED
olduğunda vermeniz gerekir.
Kullanıcı satın alma işlemini tamamladığında uygulamanız çalışıyorsa PurchasesUpdatedListener
işlevi tekrar çağrılır ve PurchaseState
, PURCHASED
olur. Uygulamanız bu noktada satın alma işlemlerini işlemek için standart yöntemi kullanarak satın alma işlemini gerçekleştirebilir. Uygulamanız, uygulamanız çalışırken PURCHASED
durumuna geçen satın alma işlemlerini işlemek için uygulamanızın onResume()
yönteminde queryPurchasesAsync()
işlevini de çağırmalıdır.
Satın alma işlemi PENDING
ürününden PURCHASED
sürümüne geçtiğinde, Gerçek zamanlı geliştirici bildirimleri müşterinize ONE_TIME_PRODUCT_PURCHASED
veya SUBSCRIPTION_PURCHASED
bildirimi gönderilir. Satın alma işlemi iptal edilirse ONE_TIME_PRODUCT_CANCELED
veya SUBSCRIPTION_PENDING_PURCHASE_CANCELED
bildirimi alırsınız. Bu durum, müşteriniz ödemeyi gerekli zaman aralığında tamamlamazsa ortaya çıkabilir. Bir satın alma işleminin mevcut durumunu kontrol etmek için dilediğiniz zaman Google Play Developer API'yi kullanabileceğinizi unutmayın.
Çoklu satın alma işlemlerini işleme
Google Play, Google Play Faturalandırma Kitaplığı'nın 4.0 ve sonraki sürümlerinde desteklenen bir özellik olarak müşterilerin, alışveriş sepetinden bir miktar belirterek tek bir işlemde aynı uygulama içi üründen birden fazla 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.
Çok miktarda satın alma işlemlerini kabul etmek için uygulamanızın temel hazırlama mantığının öğe miktarını kontrol etmesi gerekir. quantity
alanına aşağıdaki API'lerden birinden erişebilirsiniz:
getQuantity()
'yı Google Play Faturalandırma Kitaplığı'ndan indirin.Purchases.products.quantity
Google Play Developer API'sinden.
Birden fazla miktarda satın alma işlemlerini işlemek için mantık ekledikten sonra, Google Play Developer Console'daki 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 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()
adresine nasıl çağrı yapılacağı açıklanmaktadır. BillingConfigResponseListener
özelliğini uygulayarak yanıtı yönetin. Bu dinleyici, uygulamanızdan başlatılan tüm faturalandırma yapılandırması sorguları için güncelleme alır.
Döndürülen BillingResult
hatası içermiyorsa kullanıcının Play Ülkesi bilgisini almak için BillingConfig
nesnesindeki countryCode
alanını kontrol edebilirsiniz.
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
}
}
});