Bu belgede, ürün satmaya başlamak için Google Play Faturalandırma Kitaplığı'nı uygulamanıza nasıl entegre edeceğiniz açıklanmaktadır.
Satın alma işleminin ömrü
Tek seferlik satın alma veya abonelik için tipik bir satın alma süreci aşağıda verilmiştir.
- Kullanıcıya satın alabileceği ürünleri gösterin.
- Kullanıcının satın alma işlemini kabul etmesi için satın alma sürecini başlatın.
- Satın alma işlemini sunucunuzda doğrulayın.
- Kullanıcıya içerik sunma
- İçeriğin teslim edildiğini onaylayın. Tüketilebilir ürünlerde, kullanıcının öğeyi 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ı iyi durumdadır ve aboneliğe erişebilir.
- İptal edildi: Kullanıcı aboneliği iptal etti ancak abonelik süresi dolana kadar erişimi devam eder.
- Ek süre içinde: Kullanıcı ödeme sorunu yaşadı ancak Google ödeme yöntemini tekrar denerken erişimi devam ediyor.
- Beklemede: Kullanıcı bir ödeme sorunu yaşadı ve Google ödeme yöntemini tekrar denerken artık erişimi yok.
- Duraklatıldı: Kullanıcı erişimini duraklatmıştır ve devam ettirene kadar erişimi yoktur.
- Süresi doldu: Kullanıcı aboneliği iptal etti ve aboneliğe erişimini kaybetti. Kullanıcı, abonelik süresi dolduğunda kaybedilmiş olarak kabul edilir.
Google Play ile bağlantı başlatma
Google Play'in faturalandırma sistemiyle entegrasyonun ilk adımı, Google Play Faturalandırma Kitaplığı'nı uygulamanıza 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 gösterildiği şekilde ekleyin:
Groovy
dependencies { def billing_version = "9.1.0" implementation "com.android.billingclient:billing:$billing_version" }
Kotlin
dependencies { val billing_version = "9.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ş yordam 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 gibi ekleyin:
Modern
dependencies { def billing_version = "9.1.0" implementation "com.android.billingclient:billing-ktx:$billing_version" }
Kotlin
dependencies { val billing_version = "9.1.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
BillingClient'ı başlatma
Google Play Faturalandırma Kitaplığı'na bağımlılık ekledikten sonra bir BillingClient örneği 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, birçok yaygın faturalandırma işlemi için hem eşzamanlı hem de eşzamansız kolaylık yöntemleri sunar. Aşağıdakileri göz önünde bulundurun:
- Tek bir etkinlik için birden fazla
PurchasesUpdatedListenergeri çağırma işlemi yapılmasını önlemek amacıyla aynı anda tek bir etkinBillingClientbağlantınızın açık olması önerilir. - Uygulamanızın satın alma işlemlerini zamanında gerçekleştirmesi için uygulamanız başlatıldığında veya ön plana geldiğinde BillingClient için bir bağlantı başlatmanız önerilir. Bunu yapmak için
registerActivityLifecycleCallbackstarafından kaydedilenActivityLifecycleCallbackskullanabilir ve bir etkinliğin devam ettirildiğini ilk kez algıladığınızda bağlantı başlatmak için onActivityResumed'i dinleyebilirsiniz. Bu en iyi uygulamanın neden takip edilmesi gerektiği hakkında daha fazla bilgi için satın alma işlemlerini işleme bölümüne bakın. Uygulamanız kapatıldığında bağlantıyı sonlandırmayı da unutmayın.
BillingClient oluşturmak için newBuilder kullanın. newBuilder()'e herhangi bir bağlam iletebilirsiniz. BillingClient, uygulama bağlamı almak için bu bağlamı kullanır. Bu sayede bellek sızıntıları konusunda endişelenmenize gerek kalmaz. Satın alma işlemleriyle ilgili güncellemeleri almak için setListener işlevini de çağırmanız ve PurchasesUpdatedListener referansını iletmeniz 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 yöntemini çağırın. Bağlantı işlemi eşzamansızdır. İstemcinin kurulumu tamamlandıktan ve daha fazla istek yapmaya hazır olduktan sonra geri çağırma almak için bir BillingClientStateListener uygulamanız gerekir.
Otomatik hizmet yeniden bağlantısı özelliğini etkinleştirmediyseniz Google Play ile bağlantı kesildiğinde 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'nin başka istekler göndermeden önce Google Play'e yeniden bağlanmak için startConnection() yöntemini çağırdığından emin olun. Otomatik hizmet yeniden bağlantısını etkinleştirdiyseniz bu yöntemi işlem yapılmadan uygulayabilirsiniz.
Aşağıdaki örnekte, bir bağlantının nasıl başlatılacağı ve kullanıma hazır olup olmadığının 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() { // If automatic service reconnection is enabled, this can be left empty (no-op) // because the library handles retries. You can still use this for non-retry // tasks like logging or updating the UI to reflect a disconnected state. // Otherwise, 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. // It's a good practice to query products after the connection is established. queryProductDetails(); } } @Override public void onBillingServiceDisconnected() { // Try to restart the connection on the next request to // Google Play by calling the startConnection() method. // This is automatically handled by the library when you call a method that requires a connection. } });
Bağlantıyı Otomatik Olarak Yeniden Kurma
8.0.0 sürümünde BillingClient.Builder sınıfına enableAutoServiceReconnection() yönteminin eklenmesiyle Google Play Faturalandırma Kitaplığı, hizmet bağlantısı kesikken API çağrısı yapıldığında hizmet bağlantısını otomatik olarak yeniden kurabilir. Yeniden bağlanma işlemi, API çağrısı yapılmadan önce dahili olarak gerçekleştirildiğinden SERVICE_DISCONNECTED yanıtlarında azalma olabilir.
Otomatik yeniden bağlanmayı etkinleştirme
Bir BillingClient örneği oluştururken otomatik yeniden bağlanmayı etkinleştirmek için BillingClient.Builder içindeki enableAutoServiceReconnection() yöntemini kullanın.
Kotlin
val billingClient = BillingClient.newBuilder(context) .setListener(listener) .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()) .enableAutoServiceReconnection() // Add this line to enable reconnection .build()
Java
BillingClient billingClient = BillingClient.newBuilder(context)
.setListener(listener)
.enablePendingPurchases()
.enableAutoServiceReconnection() // Add this line to enable reconnection
.build();
Satın alınabilecek ürünleri göster
Google Play ile bağlantı kurduktan sonra mevcut ürünlerinizi sorgulamaya ve kullanıcılarınıza göstermeye hazır olursunuz.
Ürün ayrıntılarını sorgulamak, ürünlerinizi kullanıcılarınıza göstermeden önce önemli bir adımdır. Bu sorgu, yerelleştirilmiş ürün bilgilerini döndürür. Abonelikler için ürün gösteriminizin tüm Google Play politikalarına uyduğundan emin olun.
Tek seferlik ürün ayrıntılarını sorgulamak için queryProductDetailsAsync yöntemini çağırın. Bu yöntem, tek seferlik ürün yapılandırmanıza bağlı olarak birden fazla fırsat döndürebilir. Daha fazla bilgi için Tek seferlik ürünler için birden fazla satın alma seçeneği ve fırsat başlıklı makaleyi inceleyin.
Eşzamansız 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 yöntemini geçersiz kılabilirsiniz:
Kotlin
val queryProductDetailsParams = QueryProductDetailsParams.newBuilder() .setProductList( listOf( Product.newBuilder() .setProductId("product_id_example") .setProductType(ProductType.SUBS) .build() ) ) .build() billingClient.queryProductDetailsAsync(queryProductDetailsParams) { billingResult, queryProductDetailsResult -> if (billingResult.responseCode == BillingResponseCode.OK) { for (productDetails in queryProductDetailsResult.productDetailsList) { // Process successfully retrieved product details here. } for (unfetchedProduct in queryProductDetailsResult.unfetchedProductList) { // Handle any unfetched products as appropriate. } } }
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,
QueryProductDetailsResult queryProductDetailsResult) {
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
for (ProductDetails productDetails : queryProductDetailsResult.getProductDetailsList()) {
// Process successfully retrieved product details here.
}
for (UnfetchedProduct unfetchedProduct : queryProductDetailsResult.getUnfetchedProductList()) {
// Handle any unfetched products as appropriate.
}
}
}
}
)
Ürün ayrıntılarını sorgularken Google Play Console'da oluşturulan ürün kimliği dizelerinin listesini ve ProductType değerini 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ını kullanıyorsanız queryProductDetails() uzantı işlevini çağırarak tek seferlik ürün ayrıntılarını sorgulayabilirsiniz.
queryProductDetails(), Kotlin eş yordamlarından yararlanır. Bu sayede ayrı bir dinleyici tanımlamanız gerekmez. Bunun yerine, işlev sorgulama tamamlanana kadar askıya alınır ve 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. }
Nadir durumlarda, genellikle Google Play Hizmetleri'nin eski sürümleri nedeniyle bazı cihazlar ProductDetails ve queryProductDetailsAsync()'yi destekleyemez. Bu senaryoya uygun destek sağlamak için Google Play Faturalandırma Kitaplığı 7 geçiş rehberinde geriye dönük uyumluluk özelliklerini nasıl kullanacağınızı öğrenin.
Sonucu işleme
Google Play Faturalandırma Kitaplığı, sorgu sonuçlarını bir QueryProductDetailsResult nesnesinde depolar. QueryProductDetailsResult, ProductDetails nesnelerinin bir List öğesini içerir. Ardından, başarıyla getirilen tek seferlik ürünle ilgili fiyat veya açıklama gibi alakalı bilgileri görüntülemek için listedeki her bir ProductDetails nesnesinde çeşitli yöntemleri çağırabilirsiniz. Mevcut ürün ayrıntı bilgilerini görüntülemek için ProductDetails sınıfındaki yöntemler listesine bakın.
QueryProductDetailsResult, UnfetchedProduct nesnelerinin List değerini de içerir. Ardından, her UnfetchedProduct için sorgu göndererek getirme hatasının nedenine karşılık gelen durum kodunu alabilirsiniz.
Mevcut getirilmemiş ürün bilgilerini görüntülemek için UnfetchedProduct sınıfındaki yöntemlerin listesine bakın.
Bir öğeyi satışa sunmadan önce kullanıcının bu öğeye zaten sahip olup olmadığını kontrol edin. Kullanıcının öğe kitaplığında hâlâ bir tüketilebilir ürün varsa tekrar satın alabilmesi için önce bu ürünü tüketmesi gerekir.
Abonelik sunmadan önce kullanıcının abone olup olmadığını doğrulayın. Ayrıca aşağıdakileri de göz önünde bulundurun:
Abonelikler için
queryProductDetailsAsync()yöntemi, abonelik ürünü ayrıntılarını ve abonelik başına en fazla 50 kullanıcıya uygun teklifi döndürür. Kullanıcı uygun olmayan bir teklifi satın almaya çalışırsa (örneğin, uygulama uygun tekliflerin güncel olmayan bir listesini gösteriyorsa) Google Play, kullanıcıya uygun olmadığını bildirir ve kullanıcı bunun yerine temel planı satın almayı seçebilir.Tek seferlik ürünlerde
queryProductDetailsAsync()yöntemi yalnızca kullanıcının yararlanabileceği teklifleri döndürür. Kullanıcı, uygun olmadığı bir teklifi satın almaya çalışırsa (örneğin, kullanıcı satın alma miktar sınırına ulaştıysa) Google Play, kullanıcıyı uygun olmadığı konusunda bilgilendirir ve kullanıcı bunun yerine satın alma seçeneği teklifini satın almayı seçebilir.
Satın alma sürecini 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 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) // Get the offer token: // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList() // for a list of offers that are available to the user. // b. For subscriptions, call ProductDetails.getSubscriptionOfferDetails() // 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<BillingFlowParams.ProductDetailsParams> productDetailsParamsList = ImmutableList.of( BillingFlowParams.ProductDetailsParams.newBuilder() // retrieve a value for "productDetails" by calling queryProductDetailsAsync() .setProductDetails(productDetails) // Get the offer token: // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList() // for a list of offers that are available to the user. // b. For subscriptions, 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 bölümünde listelenen yanıt kodlarından birini döndürür. Satın alma sürecini başlatırken hata oluşmadığını doğrulamak için bu sonucu kontrol edin. OK değerindeki BillingResponseCode, başarılı bir lansmanı gösterir.
launchBillingFlow() için başarılı bir çağrı yapıldığında 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() yöntemini ç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() yöntemini 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) { // Process the purchase as described in the next section. } } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user canceling 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) {
// Process the purchase as described in the next section.
}
} else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
// Handle an error caused by a user canceling the purchase flow.
} else {
// Handle any other error codes.
}
}
Başarılı bir satın alma işlemi, Şekil 2'dekine benzer bir Google Play satın alma başarı ekranı oluşturur.
Başarılı bir satın alma işlemi, satın alma jetonu da oluşturur. Bu jeton, kullanıcıyı ve satın aldığı tek seferlik ürünün ürün kimliğini temsil eden benzersiz bir tanımlayıcıdır. Uygulamalarınız satın alma jetonunu yerel olarak depolayabilir ancak jetonu güvenli arka uç sunucunuza iletmenizi önemle tavsiye ederiz. Bu şekilde satın alma işlemini doğrulayabilir ve sahtekarlığa karşı koruma sağlayabilirsiniz. Bu işlem, Satın Alma İşlemlerini Algılama ve İşleme bölümünde daha ayrıntılı bir şekilde açıklanmıştır.
Kullanıcıya ayrıca, sipariş kimliğini veya işlemin benzersiz kimliğini içeren bir işlem makbuzu e-postayla gönderilir. Kullanıcılar, her tek seferlik ürün satın alma işlemi, 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ş fiyat belirtme
Uygulamanız Avrupa Birliği'ndeki kullanıcılara dağıtılabiliyorsa launchBillingFlow yöntemini çağırırken setIsOfferPersonalized() yöntemini kullanarak kullanıcılara bir öğenin fiyatının otomatik karar alma kullanılarak kişiselleştirildiğini açıklayın.
DSA Madde 21(2) uyarınca, Kullanıcılara sunduğunuz fiyatın kişiselleştirilmiş olup olmadığını belirlemek için lütfen Tüketici Hakları Yönergesi'nin 2011/83/EU 6. (1) (ea) maddesine bakın.
setIsOfferPersonalized(), Boole girişi alır. true olduğunda Google Play kullanıcı arayüzünde açıklama gösterilir. false olduğunda kullanıcı arayüzü açıklamayı göstermez. Varsayılan değer: false.
Daha fazla bilgi için Tüketici Yardım Merkezi'ne göz atabilirsiniz.
Kullanıcı kimlikleri ekleme
Satın alma sürecini başlattığınızda uygulamanız, obfuscatedAccountId veya obfuscatedProfileId kullanarak satın alma işlemini gerçekleştiren kullanıcı için sahip olduğunuz tüm kullanıcı kimliklerini ekleyebilir. Örnek bir tanımlayıcı, kullanıcının sisteminizdeki giriş bilgilerinin gizlenmiş bir sürümü olabilir. Bu parametreleri ayarlamak, Google'ın sahtekarlığı tespit etmesine yardımcı olabilir. Ayrıca, kullanıcılara hak verme bölümünde açıklandığı gibi, satın alma işlemlerinin doğru kullanıcıyla ilişkilendirilmesini sağlamanıza yardımcı olabilir.
Satın alma işlemlerini algılama ve işleme
Bu bölümde açıklanan satın alma işleminin algılanması ve işlenmesi, promosyon kullanımları gibi uygulama dışı satın alma işlemleri de dahil olmak üzere her tür satın alma işlemi için geçerlidir.
Uygulamanız, yeni satın alma işlemlerini ve tamamlanan bekleyen satın alma işlemlerini aşağıdaki yöntemlerden biriyle algılar:
- Uygulamanızın
launchBillingFlowyöntemini çağırması sonucundaonPurchasesUpdatedyöntemi çağrıldığında (önceki bölümde açıklandığı gibi) veya uygulamanızın dışında bir satın alma işlemi yapıldığında ya da bekleyen bir satın alma işlemi tamamlandığında uygulamanız etkin bir Faturalandırma Kitaplığı bağlantısıyla çalışıyorsa. Örneğin, bir aile üyesi başka bir cihazda bekleyen bir satın alma işlemini onaylar. - Uygulamanız, kullanıcının satın alma işlemlerini sorgulamak için queryPurchasesAsync yöntemini çağırdığında.
1 numaralı yöntem için, uygulamanız çalıştığı ve etkin bir Google Play Faturalandırma Kitaplığı bağlantısı olduğu sürece yeni veya tamamlanmış satın alma işlemleri için onPurchasesUpdated otomatik olarak çağrılır. Uygulamanız çalışmıyorsa veya uygulamanızda etkin bir Google Play Faturalandırma Kitaplığı bağlantısı yoksa onPurchasesUpdated çağrılmaz. Uygulamanızın satın alma güncellemelerini zamanında alabilmesi için uygulamanız ön planda olduğu sürece etkin bir bağlantı sürdürmeye çalışmasının önerildiğini unutmayın.
2. adımda, uygulamanızın tüm satın alma işlemlerini işlediğinden emin olmak için BillingClient.queryPurchasesAsync() yöntemini çağırmanız gerekir. Bu işlemi, uygulamanız Google Play Faturalandırma Kitaplığı ile başarılı bir şekilde bağlantı kurduğunda yapmanız önerilir (BillingClient başlatma bölümünde açıklandığı gibi, uygulamanız başlatıldığında veya ön plana geldiğinde yapmanız önerilir). Bu, onServiceConnected için başarılı bir sonuç alındığında queryPurchasesAsync çağrılarak yapılabilir. Bu öneriyi uygulamak, aşağıdaki gibi etkinlik ve durumları yönetmek için çok önemlidir:
- Satın alma işlemi sırasında ağ sorunları: Kullanıcı başarılı bir satın alma işlemi gerçekleştirip Google'dan onay alabilir ancak cihazı ve uygulamanız
PurchasesUpdatedListenerüzerinden satın alma bildirimi almadan önce cihazının ağ bağlantısı kesilebilir. - Birden fazla cihaz: Kullanıcı bir cihazda satın aldığı öğeyi başka bir cihaza geçtiğinde de görmek isteyebilir.
- Uygulamanızın dışında yapılan satın alma işlemlerini işleme: Promosyon kullanma gibi bazı satın alma işlemleri uygulamanızın dışında yapılabilir.
- Satın alma durumu geçişlerini işleme: Kullanıcı, uygulamanız çalışmıyorken BEKLEMEDE olan bir bekleyen satın alma işleminin ödemesini tamamlayabilir ve uygulamanızı açtığında satın alma işlemini tamamladığına dair onay almayı bekleyebilir.
- Askıya alınmış abonelikler: Bir abonelik, abonelik yaşam döngüsü sırasında askıya alınabilir. BillingClient.queryPurchasesAsync(), yalnızca
includeSuspendedSubscriptionsparametresiQueryPurchasesParams.Builderolarak ayarlanmışsa askıya alınmış abonelikleri döndürür. Askıya alınmış aboneliklerPurchasesUpdatedListeneriçinde döndürülmez.
Uygulamanız yeni veya tamamlanmış bir satın alma işlemi algıladığında şunları yapmalıdır:
- Satın alma işlemini doğrulayın.
- Tamamlanan satın alma işlemleri için kullanıcıya içerik erişimi verme
- Kullanıcıyı bilgilendirin.
- Uygulamanızın tamamlanan satın alma işlemlerini işlediğini Google'a bildirin.
Bu adımlar aşağıdaki bölümlerde ayrıntılı olarak ele alınmakta ve ardından tüm adımları özetleyen bir bölüm yer almaktadır.
Satın alma işlemini doğrulama
Uygulamanız, kullanıcıya avantaj sağlamadan önce her zaman satın alma işlemlerinin meşruiyetini doğrulamalıdır. Bunu yapmak için Yararlanma hakkı vermeden önce satın alma işlemlerini doğrulama bölümünde açıklanan yönergeleri uygulayabilirsiniz. Uygulamanız, satın alma işlemini yalnızca doğruladıktan sonra işleme devam etmeli ve kullanıcıya yetki vermelidir. Bu konu bir sonraki bölümde ele alınmaktadır. Bir satın alma işlemi doğrulama, uygunluk veya kötüye kullanım kontrollerinizden geçemezse Reddedilen veya yerine getirilmeyen satın alma işlemlerini yönetme başlıklı makaleyi inceleyin.
Kullanıcıya yararlanma hakkı verme
Uygulamanız bir satın alma işlemini doğruladıktan sonra kullanıcıya yararlanma hakkı vermeye ve kullanıcıyı bilgilendirmeye devam edebilir. Yararlanma hakkı vermeden önce uygulamanızın satın alma durumunun PURCHASED olduğunu kontrol ettiğinden emin olun. Satın alma işlemi BEKLEMEDE durumundaysa uygulamanız, kullanıcıya yararlanma hakkı verilmeden önce satın alma işlemini tamamlamak için hâlâ işlem yapması gerektiğini bildirmelidir.
Yalnızca satın alma işlemi BEKLEMEDE durumundan SATIN ALINDI durumuna geçtiğinde yararlanma hakkı verin.
Daha fazla bilgiyi Bekleyen işlemleri işleme bölümünde bulabilirsiniz.
Kullanıcı kimlikleri ekleme bölümünde açıklandığı gibi satın alma işlemine kullanıcı kimlikleri eklediyseniz bunları alabilir ve sisteminizdeki doğru kullanıcıyla ilişkilendirmek için kullanabilirsiniz. Bu teknik, uygulamanızın bir satın alma işleminin hangi kullanıcıya ait olduğuyla ilgili bağlamı kaybetmiş olabileceği satın alma işlemlerini mutabık kılarken kullanışlıdır. Google Play, kötüye kullanıma karşı korunmak için hakları vermeden önce güvenli arka ucunuzda bu tanımlayıcıları doğrulamanızı önerir. Daha fazla bilgi için Yararlanma hakkı vermeden önce satın alma işlemlerini doğrulama başlıklı makaleyi inceleyin. Uygulamanızın dışında yapılan satın alma işlemlerinde bu tanımlayıcıların ayarlanmayacağını unutmayın. Bu durumda uygulamanız, giriş yapmış kullanıcıya yararlanma hakkı verebilir veya kullanıcıdan tercih ettiği hesabı seçmesini isteyebilir.
Ön siparişlerde, satın alma işlemi yayınlanma zamanına ulaşılmadan önce BEKLEMEDE durumundadır. Ön sipariş satın alma işlemi, yayınlanma zamanında tamamlanır ve ek işlem yapmadan durumu SATIN ALINDI olarak değiştirir.
Kullanıcıyı bilgilendirme
Kullanıcıya yetki verdikten sonra uygulamanız, satın alma işleminin başarılı olduğunu onaylayan bir bildirim göstermelidir. Bildirim sayesinde kullanıcının satın alma işleminin başarıyla tamamlanıp tamamlanmadığı konusunda kafası karışmaz. Bu durum, kullanıcının uygulamanızı kullanmayı bırakmasına, kullanıcı desteğiyle iletişime geçmesine veya sosyal medyada bu konuda şikayette bulunmasına neden olabilir. Uygulamanızın, uygulama yaşam döngünüzün herhangi bir noktasında satın alma güncellemelerini algılayabileceğini unutmayın. Örneğin, bir ebeveyn başka bir cihazda bekleyen bir satın alma işlemini onayladığında uygulamanız, kullanıcıyı uygun bir zamanda bilgilendirmek isteyebilir. Gecikmenin uygun olacağı bazı örnekler şunlardır:
- Oyunun aksiyon bölümünde veya ara sahnelerde mesaj göstermek kullanıcının dikkatini dağıtabilir. Bu durumda, işlem bölümü bittikten sonra kullanıcıyı bilgilendirmeniz gerekir.
- Oyunun ilk eğitim ve kullanıcı kurulumu bölümlerinde. Örneğin, bir kullanıcı uygulamanızı yüklemeden önce uygulamanızın dışında bir satın alma işlemi yapmış olabilir. Yeni kullanıcıları, oyunu açtıktan hemen sonra veya ilk kullanıcı kurulumu sırasında ödül hakkında bilgilendirmenizi öneririz. Uygulamanız, kullanıcıya hak vermeden önce hesap oluşturmasını veya giriş yapmasını gerektiriyorsa satın alma işlemini tamamlamak için hangi adımları uygulaması gerektiğini kullanıcıya bildirmeniz önerilir. Uygulamanız satın alma işlemini işlemediyse satın alma işlemleri 3 gün sonra geri ödendiğinden bu çok önemlidir.
Google Play, kullanıcıyı bir satın alma işlemi hakkında bilgilendirirken aşağıdaki mekanizmaları önerir:
- Uygulama içi iletişim kutusu gösterme
- İletiyi uygulama içi mesaj kutusuna teslim edin ve uygulama içi mesaj kutusunda yeni bir mesaj olduğunu açıkça belirtin.
- İşletim sistemi bildirim mesajı kullanın.
Bildirim, kullanıcıyı aldığı avantaj hakkında bilgilendirmelidir. Örneğin, "100 altın para satın aldınız!". Ayrıca, satın alma işlemi Play Pass gibi bir programın avantajı sonucunda gerçekleştiyse uygulamanız bunu kullanıcıya bildirir. Örneğin, "Öğeler alındı!" Google Play Pass ile 100 mücevher kazandınız. Devam et." Her programda, kullanıcılara avantajları anlatmak için gösterilecek önerilen metinle ilgili rehberlik sunulabilir.
Satın alma işleminin işlendiğini Google'a bildirme
Uygulamanız kullanıcıya yetki verdikten ve işlemin başarılı olduğunu bildirdikten sonra satın alma işleminin başarıyla işlendiğini Google'a bildirmelidir. Bu işlem, satın alma işlemini onaylayarak yapılır ve üç gün içinde tamamlanmalıdır. Aksi takdirde satın alma işlemi için otomatik olarak geri ödeme yapılır ve hak iptal edilir. Farklı satın alma türlerini onaylama süreci aşağıdaki bölümlerde açıklanmıştır.
Tüketim ürünleri
Tüketilebilir ürünler için 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ının sonucundaki consumptionState değerini kontrol ederek satın alma işleminin daha önce kullanılmadığından emin olun. Uygulamanız arka ucu olmayan, yalnızca istemci tarafında çalışan bir uygulamaysa Google Play Faturalandırma Kitaplığı'ndaki consumeAsync() yöntemini 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 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ığı ile bir ürünün tüketilmesi gösterilmektedir:
Kotlin
val consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build() val consumeResult = withContext(Dispatchers.IO) { client.consumePurchase(consumeParams) }
Java
ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build(); ConsumeResponseListener listener = (billingResult, purchaseToken) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK) { // Handle the success of the consume operation. } }; billingClient.consumeAsync(consumeParams, listener);
Tüketilemeyen ürünler
Tüketilemeyen satın alma işlemlerini onaylamak için uygulamanızın güvenli bir arka ucu varsa satın alma işlemlerini güvenilir bir şekilde onaylamak için Purchases.products:acknowledge kullanmanızı öneririz. Purchases.products:get çağrısının sonucundan acknowledgementState değerini kontrol ederek satın alma işleminin daha önce onaylanmadığından emin olun.
Uygulamanız yalnızca istemci tarafındaysa 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 onaylanacağı gösterilmektedir:
Kotlin
val client: BillingClient = billingClient val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) val ackPurchaseResult = withContext(Dispatchers.IO) { client.acknowledgePurchase(acknowledgePurchaseParams.build()) }
Java
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) { if (!purchase.isAcknowledged()) { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); billingClient.acknowledgePurchase(acknowledgePurchaseParams, (billingResult) -> { // Acknowledgment handled. }); } }
Abonelikler
Abonelikler, tüketilemeyen ürünlere benzer şekilde işlenir. Mümkünse satın alma işlemini güvenli arka ucunuzdan güvenilir bir şekilde onaylamak için Google Play Developer API'den Purchases.subscriptions.acknowledge yöntemini kullanın. Purchases.subscriptions:get adresindeki satın alma kaynağında acknowledgementState değerini kontrol ederek satın alma işleminin daha önce onaylanmadığını doğrulayın. Aksi takdirde, isAcknowledged() değerini kontrol ettikten sonra Google Play Faturalandırma Kitaplığı'ndaki BillingClient.acknowledgePurchase() yöntemini 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.
Reddedilen veya tamamlanmamış satın alma işlemlerini yönetme
Bir satın alma işlemi arka uç doğrulamanızdan, kullanıcı uygunluk kontrollerinden, sahtekarlık ve kötüye kullanım kontrollerinden geçemezse veya sisteminiz hakkı yerine getiremezse hakkı vermeyin ve satın alma işlemini onaylamayın ya da tüketmeyin.
Onaylanmamış satın alma işlemleri, onay süresi sona erdikten sonra tüketici güvenliği önlemi olarak otomatik olarak geri ödenir ve iptal edilir. Ancak satın alma işlemlerini reddetmek için bu sürenin dolmasını beklemeyin. Onay penceresinin süresinin dolmasına izin vermek, siparişi onaylanmamış durumda bırakır ve Google Play için belirsizliğe neden olur. Google Play, geliştiricinin kasıtlı olarak reddetmesi ile arka uç işleme zaman aşımı arasındaki farkı ayırt edemez.
Bunun yerine, Google Play Developer API'yi kullanarak reddedilen satın alma işlemlerini arka ucunuzdan hemen iptal edip geri ödeme yapın:
- Abonelikler:
revocationContextiçinde"fullRefund": {}ilepurchases.subscriptionsv2.revokeyöntemini çağırın. Bu işlem, aboneliği hemen sonlandırır, erişimi iptal eder ve eksiksiz geri ödeme başlatır. - Tek seferlik ürünler: Bir siparişi hemen geri ödemek ve hakkını iptal etmek için
revokeparametresitrueolarak ayarlanmış şekildeorders.refundyöntemini çağırın. Bu yöntemi çağırırkenPurchase.getOrderId()veyapurchases.productsv2.getproductpurchasev2kullanarak alabileceğiniz satın alma işleminin sipariş kimliğini iletmeniz gerekir. Reddedilen satın alma işlemlerinde hiçbir zamanconsumeAsync(),acknowledgePurchase(),Purchases.products:consumeveyaPurchases.products:acknowledgeyöntemlerini çağırmayın. - RTDN ve Voided Purchases API davranışı: Geliştirici tarafından başlatılan iptaller ve geri ödemeler (
revoke,trueolarak ayarlanmış şekildepurchases.subscriptionsv2.revokeveorders.refund), gerçek zamanlı geliştirici bildirimlerini tetikler ve Voided Purchases API'ye kaydedilir (voidedSourceyanıt alanı, geliştirici için1olarak ayarlanmış şekildepurchases.voidedpurchases.list):- Abonelikler: Hem
SUBSCRIPTION_REVOKEDbildirimi hem deVoidedPurchaseNotificationgönderir. - Tek seferlik ürünler:
VoidedPurchaseNotification(ve uygulamanız Google Play Console'da tüm tek seferlik ürün bildirimlerini alacak şekilde yapılandırılmışsaONE_TIME_PRODUCT_CANCELEDbildirimi) gönderir. orders.refund,revokeparametresitrueolarak ayarlanmadan çağrıldığında yararlanma hakkı iptal edilmeden sipariş için geri ödeme yapılır ve iptal veya geçersiz satın alma bildirimi tetiklenmez. Daha fazla bilgi için Abonelikleri ve tek seferlik satın alma işlemlerini yönetme başlıklı makaleyi inceleyin.
- Abonelikler: Hem
Özet
Bu adımların özeti aşağıda verilmiştir.
Yararlanma hakkı vermeden önce satın alma işlemlerini doğrulamak için satın alma işlemini güvenli arka ucunuza gönderin.
Satın alma işlemiyle yararlanma hakkı depolama alanınızı güncelleyin. Satın alma işlemi BEKLEMEDE durumundaysa yararlanma hakkının beklemede olarak işaretlendiğinden ve kullanıcının henüz avantajlardan yararlanmadığından emin olun. Bu adımın güvenli arka ucunuzda yapılması önerilir ve 1. adımda arka ucunuza yapılan API çağrısıyla birleştirilebilir.
Uygun mesajlaşma yöntemini kullanarak kullanıcıyı bilgilendirin (gerekirse bildirimi daha önce açıklandığı şekilde geciktirin).
Satın alma işlemlerinin işlenmesi bölümünde açıklanan adımları uygulayarak satın alma işleminin işlendiğini Google'a bildirin.
Uygulamanızın bu adımları doğru şekilde uyguladığını doğrulamak için test kılavuzunu inceleyebilirsiniz.
Bekleyen işlemleri yönetme
Google Play, bekleyen işlemleri veya kullanıcının satın alma işlemini 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ı size bildirene kadar uygulamanız bu tür satın alma işlemleri için hak vermemelidir.
Örneğin, kullanıcı daha sonra nakit ödeme yapacağı fiziksel bir mağaza seçerek işlem başlatabilir. Kullanıcı hem bildirim hem de e-posta yoluyla bir kod alır. Kullanıcı fiziksel mağazaya geldiğinde kodu kasiyere göstererek kullanabilir ve nakit ödeme yapabilir. Google daha sonra hem size hem de kullanıcıya ödemenin alındığını bildirir. Uygulamanız daha sonra kullanıcıya yararlanma hakkı verebilir.
Uygulamanızda bekleyen işlemleri etkinleştirmek için BillingClient başlatma işleminin bir parçası olarak enablePendingPurchases() yöntemini ç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ısı sonucunda yeni bir satın alma işlemi aldığında, satın alma durumunun PURCHASED veya PENDING olup olmadığını belirlemek için getPurchaseState() yöntemini kullanın. Yararlanma hakkını yalnızca durum PURCHASED olduğunda vermeniz gerekir.
Uygulamanız çalışıyorsa ve kullanıcı satın alma işlemini tamamladığında etkin bir Google Play Faturalandırma Kitaplığı bağlantınız varsa PurchasesUpdatedListener tekrar çağrılır ve PurchaseState artık PURCHASED olur. Bu noktada uygulamanız, Satın Alma İşlemlerini Algılama ve İşleme için standart yöntemi kullanarak satın alma işlemini gerçekleştirebilir. Uygulamanız çalışmıyorken PURCHASED durumuna geçen satın alma işlemlerini işlemek için uygulamanızın onResume() yönteminde queryPurchasesAsync() yöntemini de çağırmalıdır.
Satın alma işlemi PENDING durumundan PURCHASED durumuna geçtiğinde real_time_developer_notifications istemciniz ONE_TIME_PRODUCT_PURCHASED veya SUBSCRIPTION_PURCHASED bildirimi alır. 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 tamamlamadığında ortaya çıkabilir. Bir satın alma işleminin mevcut durumunu kontrol etmek için her zaman Google Play Developer API'yi kullanabileceğinizi unutmayın.
Çoklu satın alma işlemlerini yönetme
Google Play Faturalandırma Kitaplığı'nın 4.0 ve sonraki sürümlerinde desteklenen bu özellik sayesinde Google Play, müşterilerin alışveriş sepetinden miktar belirterek tek bir işlemde aynı tek seferlik üründen birden fazla satın almasına olanak tanır. Uygulamanızın, çoklu satın alma işlemlerini işlemesi ve belirtilen satın alma miktarına göre yararlanma hakkı vermesi beklenir.
Çoklu satın alma işlemlerini yerine getirmek 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'lerden 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şlemek için mantık ekledikten sonra Google Play Console'daki tek seferlik ü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 sağlar.
BillingClient oluşturduktan sonra kullanıcının faturalandırma yapılandırmasını sorgulayabilirsiniz. Aşağıdaki kod snippet'inde, getBillingConfigAsync() için nasıl çağrı yapılacağı açıklanmaktadır. BillingConfigResponseListener yöntemini uygulayarak yanıtı işleyin. Bu dinleyici, uygulamanızdan başlatılan tüm faturalandırma yapılandırması sorgularıyla ilgili güncellemeleri alır.
Döndürülen BillingResult hata içermiyorsa kullanıcının Play ülkesini öğrenmek 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 { // Handle errors } } } )
Java
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build(); billingClient.getBillingConfigAsync( getBillingConfigParams, (billingResult, billingConfig) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK && billingConfig != null) { String countryCode = billingConfig.getCountryCode(); } else { // TODO: Handle errors } });