Google Play Faturalandırma Kitaplığı'nı uygulamanıza entegre etme

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.

Satın alma işleminin ömrü

Tek seferlik satın alma işlemi veya abonelik için tipik bir satın alma akışı aşağıda verilmiştir.

  1. Kullanıcıya neler satın alabileceklerini gösterin.
  2. Kullanıcının satın alma işlemini kabul etmesi için satın alma akışını başlatın.
  3. Satın alma işlemini sunucunuzda doğrulayın.
  4. Kullanıcıya içerik sunun.
  5. İçeriğin yayınlandığını onaylayın. 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şebilir.
  • İptal edildi: Kullanıcı iptal etmiş olsa da geçerlilik süresi sona erene kadar erişmeye devam eder.
  • 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ınmış: Kullanıcı ödeme sorunuyla karşılaştı ve Google ödeme yöntemini tekrar dener.
  • Duraklatıldı: Kullanıcı erişimini duraklatmıştır ve erişimi, yeniden etkinleştirene 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 kullanmayı bırakmış olarak kabul edilir.

Google Play'e bağlantı oluşturma

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 aşağıdaki 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 idiomatik Kotlin yazmanızı sağlayan Kotlin uzantılarını ve iş parçacığı desteğini içerir. Bu uzantıları projenize dahil etmek için uygulamanızın build.gradle dosyasına aşağıdaki bağımlılığı ekleyin:

Groovy

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. Aşağıdakileri göz önünde bulundurun:

  • 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 olması önerilir.
  • Uygulamanızın satın alma işlemlerini zamanında işlediğinden emin olmak için uygulamanız başlatılırken veya ön plana geldiğinde BillingClient için bağlantı başlatmanız önerilir. Bu, registerActivityLifecycleCallbacks tarafından kaydedilen ActivityLifecycleCallbacks kullanılarak ve bir etkinliğin devam ettirildiğini ilk kez algıladığınızda bağlantıyı başlatmak için onActivityResumed dinlenerek yapılabilir. Bu en iyi uygulamanın neden uygulanması gerektiği hakkında daha fazla bilgi için satın alma işlemlerini işleme bölümüne bakın. Ayrıca, uygulamanız kapalıyken bağlantıyı sonlandırmayı unutmayın.

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, bellek sızıntıları konusunda endişelenmenize gerek olmadığı anlamına gelir. Satın alma işlemleriyle ilgili güncellemeler almak için PurchasesUpdatedListener referansı göndererek setListener'u da çağırmanız 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ı işlemi eşzamanlı değildir ve istemcinin kurulumu tamamlanıp başka istek göndermeye hazır olduğunda geri arama 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 belirten bir QueryProductDetailsParams örneğini ve bir ProductType geçirin. 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, sorgu tamamlanana 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 depolar. 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 öğeye sahip olup olmadığını kontrol edin. Kullanıcının öğe kitaplığında hâlâ tüketilmemiş bir öğesi varsa öğeyi tekrar satın almadan önce 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.
başlıklı makaleyi inceleyin.

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 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()
)

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ı olursa 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 ekranında, satın alınabilecek bir abonelik gösteriliyor
Şekil 1. Google Play satın alma ekranında, satın alınabilecek bir abonelik gösteriliyor.

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) {
           // 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'ye benzer bir Google Play satın alma işlemi başarı ekranı oluşturur.

google play&#39;in satın alma işleminin başarılı olduğu ekranı
Şekil 2. Google Play'in satın alma işleminin başarılı olduğu ekranı.

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ı önemle tavsiye ederiz. Bu süreç Satın Alma İşlemlerini Tespit Etme ve İşleme bölümünde 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 bir öğenin fiyatının otomatik karar verme kullanılarak kişiselleştirildiğini kullanıcılara bildirmek için launchBillingFlow çağrısı yaparken setIsOfferPersonalized() yöntemini kullanın.

Fiyatın kullanıcı için özelleştirildiğini belirten Google Play satın alma ekranı.
Şekil 3. Fiyatın kullanıcı için özelleştirildiğini belirten Google Play satın alma ekranı.

Google, DSA Madde 21(2) 6 (1) (ea) CRD of the Consumer Rights Directive 2011/83/EU to determine whether the price you are offering to users is personalized.

setIsOfferPersonalized(), boole girişi alır. true olduğunda Play kullanıcı arayüzünde açıklama 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 bakın.

Kullanıcı tanımlayıcıları ekleme

Satın alma akışını başlattığınızda uygulamanız, obfuscatedAccountId veya obfuscatedProfileId kullanarak satın alma işlemini gerçekleştiren kullanıcıyla ilgili sahip olduğunuz tüm kullanıcı tanımlayıcılarını ekleyebilir. Örnek bir tanımlayıcı, kullanıcının sisteminizdeki girişinin karartılmış 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ıya atanmasını 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şlemlerinin algılanması ve işlenmesi, promosyon kullanma işlemleri gibi uygulama dışı satın alma işlemleri dahil olmak üzere tüm satın alma türleri için geçerlidir.

Uygulamanız, yeni satın alma işlemlerini ve tamamlanmış beklemedeki satın alma işlemlerini aşağıdaki yöntemlerden biriyle algılar:

  1. Uygulamanızın launchBillingFlow'u çağırması sonucunda onPurchasesUpdated çağrıldığında (önceki bölümde açıklandığı gibi) veya uygulamanız 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, aile üyelerinden biri başka bir cihazda bekleyen bir satın alma işlemini onaylar.
  2. Uygulamanız, kullanıcının satın alma işlemlerini sorgulamak için queryPurchasesAsync'i çağrdığında.

1. seçenek için onPurchasesUpdated, uygulamanız çalışırken 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 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 zamanında satın alma güncellemeleri alabilmesi için ön planda olduğu sürece etkin bir bağlantı tutmaya çalışmasının önerilir.

2. madde için uygulamanızın tüm satın alma işlemlerini işlediğinden emin olmak üzere BillingClient.queryPurchasesAsync() işlevini çağırmanız gerekir. Bunu, 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ılırken veya öne geldiğinde yapılması önerilir). Bu, onServiceConnected için başarılı bir sonuç alındığında queryPurchasesAsync çağrılarak yapılabilir. Aşağıdakiler gibi etkinlikleri ve durumları ele almak için bu öneriyi uygulamak ö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ı, uygulamanız PurchasesUpdatedListener üzerinden satın alma işlemiyle ilgili bildirim almadan önce ağ bağlantısını kaybeder.
  • Birden fazla cihaz: Kullanıcılar bir cihazda satın aldıkları öğeleri cihaz değiştirdiklerinde görmeyi bekleyebilir.
  • Uygulamanızın dışında yapılan satın alma işlemlerini işleme: Promosyon kullanma işlemleri 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ılar, uygulamanız çalışmazken BEKLEMEDE olan bir satın alma işleminin ödemesini tamamlayabilir ve uygulamanızı açtıklarında satın alma işlemini tamamladıklarına dair onay almayı bekleyebilir.

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 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ın özetlendiği bir bölüm bulunmaktadır.

Satın alma işlemini doğrulama

Uygulamanız, kullanıcılara avantaj sunmadan önce satın alma işlemlerinin meşru olduğundan emin olmak için her zaman satın alma işlemlerini doğrulamalıdır. Bu işlem, Haklardan yararlanma hakkı vermeden önce satın alma işlemlerini doğrulama bölümünde açıklanan yönergeleri uygulayarak yapılabilir. Uygulamanız, satın alma işlemini yalnızca doğruladıktan sonra işlemeye devam etmeli ve kullanıcıya hak vermelidir. Bu konu, sonraki bölümde ele alınmaktadır.

Kullanıcıya Yetkilendirme Verme

Uygulamanız bir satın alma işlemini doğruladıktan sonra kullanıcıya hak vermeye ve kullanıcıyı bilgilendirmeye devam edebilir. Uygulamanızın, hak vermeden önce satın alma durumunun PURCHASED olduğunu kontrol ettiğinden emin olun. Satın alma işlemi BEKLEMEDE durumundaysa uygulamanız, kullanıcıya hak verilmeden önce satın alma işlemini tamamlamak için bazı işlemleri tamamlaması gerektiğini bildirmelidir. Yalnızca satın alma işlemi BEKLEMEDE durumundan BAŞARILI durumuna geçtiğinde hak verin. Onay bekleyen işlemleri ele alma başlıklı makalede daha fazla bilgi bulabilirsiniz.

Kullanıcı tanımlayıcılarını ekleme bölümünde açıklandığı gibi satın alma işlemine kullanıcı tanımlayıcıları eklediyseniz bunları alıntılayabilir ve sisteminizde 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ğu bağlamını kaybedebileceği satın alma işlemlerini uyumlulaştırmak için kullanışlıdır. 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, oturum açmış kullanıcıya hak verebilir veya kullanıcıdan tercih edilen hesabı seçmesini isteyebilir.

Kullanıcıyı bilgilendirme

Kullanıcıya hak verdikten sonra uygulamanız, başarılı satın alma işlemini onaylayan bir bildirim göstermelidir. Bu sayede, kullanıcının satın alma işleminin başarıyla tamamlanıp tamamlanmadığı konusunda kafası karışmaz. Bu da kullanıcının uygulamanızı kullanmayı bırakmasına, kullanıcı desteğiyle iletişime geçmesine veya sosyal medyada şikayet etmesine neden olabilir. Uygulamanızın, uygulama yaşam döngünüz sırasında herhangi bir zamanda satın alma güncellemeleri algılayabileceğini unutmayın. Örneğin, bir ebeveyn başka bir cihazda bekleyen bir satın alma işlemini onaylar. Bu durumda uygulamanız, kullanıcıyı uygun bir zamanda bilgilendirmeyi geciktirebilir. Gecikmenin uygun olacağı bazı örnekler:

  • Bir 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ü sona erdikten sonra kullanıcıyı bilgilendirmeniz gerekir.
  • Oyunun ilk eğitimi ve kullanıcı ayarlarının yapıldığı bölümlerde. Ö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 kullanıcının hesap oluşturmasını veya giriş yapmasını gerektiriyorsa kullanıcınıza, satın alma işlemi için hangi adımları tamamlaması gerektiğini bildirmeniz önerilir. Uygulamanız satın alma işlemini işleme almamışsa satın alma işlemleri 3 gün sonra geri ödenir. Bu nedenle bu işlem çok önemlidir.

Google Play, kullanıcıyı satın alma işlemi hakkında bilgilendirirken aşağıdaki mekanizmaları önerir:

  • Uygulama içi bir iletişim kutusu gösterin.
  • İleti, uygulama içi mesaj kutusuna gönderilir ve uygulama içi mesaj kutusunda yeni bir ileti olduğunu açıkça belirtir.
  • OS bildirim mesajı kullanın.

Bildirimde, kullanıcıya sunulan avantaj hakkında bilgi verilmelidir. Ö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ı nedeniyle gerçekleştiyse uygulamanız bunu kullanıcıya bildirir. Örneğin, "Öğeler alındı. Play Pass ile 100 mücevher kazandınız. Devam et"i tıklayın. Her programda, avantajları kullanıcılara iletmek için gösterilmesi önerilen metinle ilgili yönergeler bulunabilir.

Google'a satın alma işleminin yapıldığını bildirme

Uygulamanız kullanıcıya hak verdikten ve başarılı işlem hakkında kullanıcıyı bilgilendirdikten sonra, satın alma işleminin başarıyla işlendiğini Google'a bildirmesi gerekir. Bu işlem, satın alma işlemini onaylayarak yapılır ve satın alma işleminin otomatik olarak geri ödenmemesi ve uygunluk durumunun iptal edilmemesi için üç gün içinde yapılmalıdır. Farklı satın alma türlerini onaylama süreci aşağıdaki bölümlerde açıklanmıştır.

Tüketilebilir ürünler

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 kullanıcının kabul şartını karşılar ve uygulamanızın kullanıcıya hak verdiğini belirtir. 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

    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 = 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);

Tüketilebilir 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 sonucunda acknowledgementState değerini kontrol ederek satın alma işleminin daha önce kabul edilmediğinden 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 = ...

val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
    .setPurchaseToken(purchase.purchaseToken)
val ackPurchaseResult = withContext(Dispatchers.IO) {
     client.acknowledgePurchase(acknowledgePurchaseParams.build())
}

Java

BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...

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()'i 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.

Özet

Aşağıdaki kod snippet'inde bu adımların özeti gösterilmektedir.

Kotlin

fun handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify
.
    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

Java

void handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify

    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

Uygulamanızın bu adımları doğru şekilde uyguladığını doğrulamak için test kılavuzunu takip edebilirsiniz.

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ılı bir şekilde ödeme alındığını size bildirene kadar uygulamanız bu tür satın alma işlemlerine hak 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. Ardından 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.

Uygulamanız çalışıyorsa ve kullanıcı satın alma işlemini tamamladığında etkin bir Play Billing Library bağlantınız varsa PurchasesUpdatedListener işlevi tekrar çağrılır ve PurchaseState artık PURCHASED olur. Bu noktada uygulamanız, Satın Alma İşlemlerini Tespit Etme ve İşleme için standart yöntemi kullanarak satın alma işlemini işleyebilir. 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'ten PURCHASED'e geçtiğinde real_time_developer_notifications müşteriniz bir 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 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 satın alma işlemlerini işlemesi ve belirtilen satın alma miktarına göre uygunluk vermesi beklenir.

Çok miktarda satın alma işlemlerini gerçekleştirmek 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:

Birden fazla miktarda satın alma işlemini 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ı sorgulayın

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'yi uygulayarak yanıtı yönetin. Bu dinleyici, uygulamanızdan başlatılan tüm faturalandırma yapılandırma sorgularıyla ilgili güncellemeleri alır.

Döndürülen BillingResult'te hata yoksa kullanıcının Play ülkesini almak için BillingConfig nesnesinde 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
        }
      }
    });

Google Play Games ana sayfasındaki 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'a göz atarken 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österilen Alışveriş Sepeti Terk Etme Hatırlatıcısı gösterilmektedir:

Google Play Store ekranında, daha önce terk edilmiş bir satın alma işlemi için satın alma istemi gösteriliyor
Şekil 2. Google Play Store ekranında, daha önce bırakılan bir satın alma işlemi için satın alma istemi gösteriliyor.

Google Play Store ekranında, daha önce terk edilmiş bir satın alma işlemi için satın alma istemi gösteriliyor
Şekil 3. Google Play Store ekranında, daha önce bırakılan bir satın alma işlemi için satın alma istemi gösteriliyor.