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

Bu bölümde, Google Play Faturalandırma Kitaplığı'nı uygulamanızı öneririz.

Bir satın alma süreci

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

  1. Kullanıcıya neler satın alabileceğini 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. Sunucunuzda satın alma işlemini doğrulayın.
  4. Kullanıcıya içerik verin.
  5. İçeriğin teslim edildiğini onaylama. Tüketim ürünleri için satın almayı önceliklendirebilir.

Abonelikler, iptal edilene kadar otomatik olarak yenilenir. Abonelik başlayabilir şu eyaletler üzerinden:

  • Etkin: Kullanıcı iyi durumda ve aboneliğe erişebiliyor.
  • İptal edildi: Kullanıcı iptal etmiştir ancak süresi dolana kadar erişimi vardır.
  • Ek süre süresinde: Kullanıcı, ödeme sorunuyla karşılaştı ancak hâlâ erişimi var. ve Google ödeme yöntemini yeniden dener.
  • Beklemede: Kullanıcı bir ödeme sorunuyla karşılaşmıştır ve artık şu süre içinde hesaba erişemez: Google, ödeme yöntemini yeniden deniyor.
  • Duraklatıldı: Kullanıcı, erişimini duraklatmıştır ve devam eder.
  • Süresi doldu: Kullanıcı, aboneliği iptal etmiştir ve erişimini kaybetti. İlgili içeriği oluşturmak için kullanılan süresi dolan kullanıcının uygulamayı kullanmayı bırakmış olduğu kabul edilir.

Google Play bağlantısını ilk kullanıma hazırlayın

Google Play'in faturalandırma sistemiyle entegrasyonun ilk adımı Uygulamanızı Google Play Faturalandırma Kitaplığı'na ekleyin ve bağlantıyı ilk kullanıma hazırlayın.

Google Play Faturalandırma Kitaplığı bağımlılığı ekleme

Google Play Faturalandırma Kitaplığı bağımlılığını uygulamanızın build.gradle cihazına ekleyin dosyası şu şekildedir:

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ü Deyimsel yazmanızı sağlayan Kotlin uzantıları ve eş yordam desteği Kotlin'i kullanın. Bunları eklemek için yoksa, uygulamanızın verilerine aşağıdaki bağımlılığı ekleyin: Gösterilen build.gradle dosyası:

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 şunları yapmanız gerekir: BillingClient örneğini ilk kullanıma hazırlayın. BillingClient ana Google Play Faturalandırma Kitaplığı ve geri kalan kısmını izleyin. BillingClient, ikisi de eşzamanlı olmak üzere kolaylık yöntemleri sunar ve eş zamansız şekilde entegre edilir. Kesinlikle önerilir için aynı anda açık olan etkin bir BillingClient bağlantınızın olduğunu Tek bir etkinlik için birden fazla PurchasesUpdatedListener geri çağırması yapılmasını önleyin.

BillingClient oluşturmak için newBuilder() işlevini kullanın. Herhangi bir içeriği iletebilirsiniz newBuilder() olarak ayarlanır ve BillingClient, uygulama bağlamını almak için bunu kullanır. Bu, bellek sızıntıları konusunda endişelenmenize gerek olmadığı anlamına gelir. Şu konularla ilgili güncellemeleri almak için: satın alma işlemi gerçekleştiriyorsanız setListener() numarasını da çağırmalı ve PurchasesUpdatedListener. Bu işleyici, tüm katılımcılar için elde edebilirsiniz.

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ğlanın

BillingClient oluşturduktan sonra Google Play

Google Play'e bağlanmak için startConnection() numaralı telefonu arayın. Bağlantı eş zamanlı olmayan bir süreçtir ve BillingClientStateListener ve başka isteklerde bulunmaya hazırdır.

Google Play ile kaybedilen bağlantıları yönetmek için yeniden deneme mantığını da uygulamanız gerekir. Yeniden deneme mantığını uygulamak için onBillingServiceDisconnected() geçersiz kılınır geri çağırma yöntemini kullanın ve BillingClient öğesinin Google Play'e bağlanmadan önce startConnection() yöntemini kullanarak istemem gerekir.

Aşağıdaki örnek, bir bağlantının nasıl başlatılacağını ve kullanıma hazır:

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öster

Google Play ile bağlantı kurduktan sonra sorgu göndermeye hazır olursunuz. hazırlayıp kullanıcılarınıza gösterebilirsiniz.

Ürün ayrıntılarını sorgulamak, ürünlerinizi sergilemeden önce önemli bir adımdır. yerelleştirilmiş ürün bilgileri döndürdüğünden emin olun. Örneğin, ürün görüntülemenizin tüm Play politikalarına uyduğundan emin olun.

Uygulama içi ürün ayrıntılarını sorgulamak için queryProductDetailsAsync() numaralı telefonu arayın.

Eşzamansız işlemin sonucunu işlemek için bir işleyicisi tarafından yürütülür.ProductDetailsResponseListener Ardından, onProductDetailsResponse() işleyiciyi, aşağıdaki örnekte gösterildiği gibi, sorgu tamamlandığında dinleyici olarak ayarlayın:

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 Ürün kimliği dizelerinin listesini belirten QueryProductDetailsParams Google Play Console'da ProductType ile birlikte oluşturulur. İlgili içeriği oluşturmak için kullanılan ProductType, tek seferlik ürünler için ProductType.INAPP veya Abonelikler için ProductType.SUBS.

Kotlin uzantılarıyla sorgulama

Kotlin uzantıları kullanıyorsanız uygulama içi ürün için sorgu oluşturabilirsiniz. ayrıntılarını görmek için queryProductDetails() uzantı işlevini çağırın.

queryProductDetails(), Kotlin eş yordamlarından yararlanır. Böylece ayrı bir dinleyici tanımlamalısınız. Bunun yerine, işlev sorgulayana kadar tamamlandıktan sonra 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.
}

Nadiren de olsa bazı cihazlar ProductDetails ve queryProductDetailsAsync() (genellikle Google Play'in eski sürümleri nedeniyle) Hizmetler. Bu senaryoda doğru desteğin sağlanması için Play Faturalandırma Kitaplığı 5 taşıma işlemindeki geriye dönük uyumluluk özellikleri rehberini inceleyin.

Sonucu işleme

Google Play Faturalandırma Kitaplığı, sorgu sonuçlarını List içinde depolar. ProductDetails nesne. Daha sonra her biri için farklı yöntemler çağırabilir Bir uygulama içi ürünle ilgili alakalı bilgileri görüntülemek için listede ProductDetails nesne (ör. fiyatı veya açıklaması) Mevcut ürün ayrıntılarını görüntülemek için bilgi için ProductDetails sınıfındaki yöntem listesine bakın.

Bir öğeyi satışa sunmadan önce, kullanıcının halihazırda öğede olup olmadığını kontrol edin öğe. Kullanıcının öğe kitaplığında hâlâ bir sarf malzemesi varsa önce ürünü tüketmesi gerekir.

Abonelik sunmadan önce kullanıcının zaten abone olmadığını doğrulayın. Ayrıca aşağıdakilere de dikkat edin:

  • queryProductDetailsAsync(), abonelik ürünü ayrıntılarını ve Abonelik başına en fazla 50 fırsat.
  • queryProductDetailsAsync(), yalnızca kullanıcının şu teklifte bulunduğu teklifleri döndürür: uygun. Kullanıcı, sunduğu bir fırsatı satın almaya çalışırsa uygun değildir (örneğin, uygulama uygun teklifler) sunduğunda Play, kullanıcıya uygun olmadığını bildirir ve kullanıcı temel planı satın alabilir.
ziyaret edin.

Satın alma akışını başlatma

Uygulamanızdan satın alma isteği başlatmak için launchBillingFlow() numaralı telefonu arayın yöntemini kullanın. Bu yöntem, Alakalı olan BillingFlowParams nesnesi Aramadan ProductDetails nesne alındı queryProductDetailsAsync(). Bir BillingFlowParams nesnesi oluşturmak için şunu kullanın: BillingFlowParams.Builder sınıfı.

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 Bu sonucu kontrol ettiğinizden emin olun: ve satın alma akışının herhangi bir hata olmadığından emin olun. BillingResponseCode OK metriğinin başarılı bir lansmanın gerçekleştirildiğini gösterir.

launchBillingFlow() başarılı bir çağrı olduğunda sistem, Play satın alma ekranı. Şekil 1'de bir abonelik için satın alma ekranı gösterilmektedir:

google play satın alma ekranında şu anda bir abonelik
            satın alınabilir
Şekil 1. Google Play satın alma ekranında görünen aboneliği satın alabilirsiniz.

Google Play, satın alma işleminin sonucunu bildirmek için onPurchasesUpdated() adlı kişiyi çağırır PurchasesUpdatedListener işlemini uygulayan bir işleyiciye kullanır. İşleyici, setListener() yöntemini kullanarak istemcinizi başlattık.

Olası yanıt kodlarını işlemek için onPurchasesUpdated() öğesini uygulamanız gerekir. İlgili içeriği oluşturmak için kullanılan 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, şuna benzer bir Google Play satın alma işlemi başarısı ekranı oluşturur: Şekil 2.

google play&#39;in başarılı satın alma işlemleri ekranı
Şekil 2. Google Play'in satın alma işlemi başarısı tıklayın.

Başarılı bir satın alma işlemi aynı zamanda bir satın alma jetonu oluşturur. Bu, benzersiz bir kullanıcıyı ve uygulama içi ürünün ürün kimliğini temsil eden tanımlayıcı gösterir. Uygulamalarınız satın alma jetonunu yerel olarak saklayabilir, ancak jetonu güvenli arka uç sunucunuza iletmenizi öneririz. Böylece satın alma işlemini doğrulama ve sahtekarlığa karşı koruma sağlama. Bu süreç daha ayrıntılı şekilde ele alacağız.

Kullanıcıya ayrıca, sipariş kimliğinin veya işlemin benzersiz bir kimliğidir. Kullanıcılar benzersiz bir Sipariş Kimliği içeren e-posta alır her bir tek seferlik ürün satın alma işlemi için ve ayrıca ilk abonelik için ve müteakip yinelenen otomatik yenilemeler için geçerlidir. Sipariş kimliğini kullanabilirsiniz Google Play Console'da geri ödemeleri yönetme

Kişiselleştirilmiş bir fiyat belirtin

Uygulamanız Avrupa Birliği'ndeki kullanıcılara dağıtılabiliyorsa setIsOfferPersonalized() yöntemini kullanarak kullanıcılara bir öğenin fiyatının otomatik karar alma tekniğiyle kişiselleştirilmiştir.

Fiyatın kullanıcı için özelleştirildiğini gösteren Google Play satın alma ekranı.
Şekil 3. Gösterilen Google Play satın alma ekranı fiyatın kullanıcıya göre özelleştirildiğini belirtmelidir.

6 (1) (ea) Tüketici Hakları Yönergesi CRD'si kullanıcılara sunduğunuz fiyatın geçerli olup olmadığını belirlemek için 2011/83/EU kişiselleştirilmiş olduğundan emin olun.

setIsOfferPersonalized() bir boole girişi alır. true olduğunda Play kullanıcı arayüzü bir açıklama ekleyin. false olduğunda kullanıcı arayüzü açıklama atlar. Varsayılan değer false.

Daha fazla bilgi için Tüketici Yardım Merkezi'ne göz atın.

Satın alma işlemleri işleniyor

Kullanıcı bir satın alma işlemini tamamladıktan sonra, uygulamanızın bu satın alma işlemini gerçekleştirmesi gerekir. Çoğu durumda, satın alma işlemlerinde uygulamanız PurchasesUpdatedListener. Ancak uygulamanız, bazı durumlarda BillingClient.queryPurchasesAsync() numaralı telefonu arayarak satın alma işlemlerinden haberdar olundu Satın alınanları getirme bölümünde açıklandığı gibi.

Ayrıca, Android'de Gerçek Zamanlı Geliştirici Bildirimleri istemciniz varsa yeni satın alma işlemlerini güvenli arka ucunuzda, subscriptionNotification veya oneTimeProductNotification tarafından uyarı gönderen satın alabilirsiniz. Bu bildirimleri aldıktan sonra Google Play'i arayın Developer API'yi kullanarak tam durumu alın ve kendi arka uç durumunuzu güncelleyin.

Uygulamanız, satın alma işlemlerini aşağıdaki şekilde işlemelidir:

  1. Satın alma işlemini doğrulayın.
  2. 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 satın alabilmesi için öğeyi tüketildi olarak işaretleyin tekrar.

Bir satın alma işlemini doğrulamak için önce satın alma durumunun şu olduğundan emin olun: PURCHASED. Satın alma işlemi PENDING ise (Bekleyen işlemleri yönetme bölümünde açıklandığı gibi) satın almanız gerekir. Satın alma işlemleri için onPurchasesUpdated() veya queryPurchasesAsync() adlı kişiden alındıysa, Uygulamanız size izin vermeden önce satın alma işleminin meşruluğundan emin olmak için daha fazla doğrulama yapmalıdır. hak. Satın alma işlemlerini doğru şekilde nasıl doğrulayacağınızı öğrenmek için Satın alma işlemlerini doğrulama bilgi edinin.

Satın alma işlemini doğrulamanızın ardından uygulamanız belirtir. Satın alma işlemiyle ilişkili kullanıcı hesabı, ProductPurchase.obfuscatedExternalAccountId tane şu kullanıcı tarafından geri verildi: Uygulama içi ürün satın alma işlemleri için Purchases.products:get ve SubscriptionPurchase.obfuscatedExternalAccountId tarafından iade edildi Purchases.subscriptions:get ya da sunucu tarafındaki abonelikler için obfuscatedAccountId Purchase.getAccountIdentifiers() tarihinde geçerli olduğunda setObfuscatedAccountId satın alındığını gösterir.

Yararlanma hakkı verildikten sonra uygulamanızın satın alma işlemini onaylaması gerekir. Bu onay, Google Play'e kullanım hakkı verdiğinizi bildirir işlem gerçekleştiriyor.

Yararlanma hakkı verme ve satın alma işlemini onaylama süreci, Satın alınan öğe; tüketilebilir, tüketilebilir olmayan bir öğe veya abonelik kapsamındadır.

Tüketim Ürünleri

Sarf malzemeleri 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. Şunlardan emin olun: kontrol edilerek consumptionState Purchases.products:get çağrısının sonucu. Uygulamanız yalnızca istemciye yönelikse arka uç olmadan consumeAsync() kullanın: Google Play Faturalandırma Kitaplığı. Her iki yöntem de onayı karşılar şartına sahip olmalı ve uygulamanızın kullanıcıya yararlanma hakkı verdiğini belirtmelisiniz. Bu yöntemler, uygulamanızın ilgili tek seferlik ürünü yeniden satın alınabilecek giriş satın alma jetonu. consumeAsync() ile siz ConsumeResponseListener işlemini uygulayan bir nesneyi de iletmelidir kullanır. Bu nesne, tüketim işleminin sonucunu işler. Şunları yapabilirsiniz: onConsumeResponse() yöntemini geçersiz kılarak bir sonraki İşlem tamamlandığında Google Play Faturalandırma Kitaplığı çağrı yapar.

Aşağıdaki örnekte, İlişkilendirilmiş satın alma jetonunu kullanan Google Play Faturalandırma Kitaplığı:

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

Tüketilebilir Olmayan Ürünler

Tüketilebilir olmayan satın alma işlemlerini onaylamak için uygulamanızın güvenli bir arka ucu varsa bunu güvenilir bir şekilde onaylamak için Purchases.products:acknowledge değeri için teklif verirsiniz. Satın alma işleminin daha önce çağrının sonucundaki acknowledgementState kontrol ediliyor Purchases.products:get.

Uygulamanız yalnızca istemciye yönelikse şunu kullanın: BillingClient.acknowledgePurchase() Google Play Faturalandırma Kitaplığı'nı kullanabilirsiniz. Bir satın alma işlemi için isAcknowledged() yöntemini kullanarak Google Play Faturalandırma Kitaplığı'nı kullanabilirsiniz.

Aşağıdaki örnekte, Google Play Faturalandırma Kitaplığı:

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üketim maddelerine benzer şekilde işlenir. Mümkünse Purchases.subscriptions.acknowledge - Google Play Developer API'nin Google Play Geliştirici API'sini kullanarak, güvenli arka uç sağlar. Satın alma işleminin daha önce Google tarafından kabul edilmediğini doğrulayın. satın alma kaynağındaki acknowledgementState öğesini kontrol ederek Purchases.subscriptions:get. Aksi takdirde, BillingClient.acknowledgePurchase() ile abone olmak için isAcknowledged() kontrol edildikten sonra Google Play Faturalandırma Kitaplığı. Tümü İlk abonelik satın alma işlemlerinin onaylanması gerekir. Abonelik yenilemeleri kabul edilmelerine gerek yoktur. Aboneliklerin ne zaman için Abonelik satma konusuna göz atın.

Satın alınanlar getiriliyor

Satın alma güncellemelerini PurchasesUpdatedListener kullanarak dinlemek mümkün değildir Uygulamanızın tüm satın alma işlemlerini işlemesini sağlamak için yeterlidir. Belki de kişisel bilgileriniz Uygulama, kullanıcının yaptığı tüm satın alma işlemlerinden haberdar olmayabilir. Aşağıda bazı örnekler verilmiştir: uygulamanızın takibi kaybedebileceği veya satın alma işlemlerinden habersiz olabileceği senaryolar:

  • Satın alma sırasında ortaya çıkan ağ sorunları: Kullanıcı, başarılı bir satın alma işlemi gerçekleştirir. ve Google'dan onay aldığında cihazın ağı kesiliyor bağlantısı, satın alma işlemiyle ilgili bildirim almadan önce PurchasesUpdatedListener üzerinden.
  • Birden çok cihaz: Kullanıcı bir cihazda bir öğe satın alır ve daha sonra bu öğeyi görebilir.
  • Uygulamanızın dışında yapılan satın alma işlemlerini yönetme: Bazı satın alma işlemleri, ör. promosyon kullanımları, uygulamanızın dışında gerçekleştirilebilir.

Bu durumları ele almak için uygulamanızın onResume() yönteminizde BillingClient.queryPurchasesAsync() tüm satın alma işlemlerinin işleme konusunda açıklandığı gibi başarıyla işlendiğinden emin olun. satın alma işlemleri.

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 döndürdüğünü ve tüketilmemiş tek seferlik satın alımlar.

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ı 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 gerçekleştirdiğinde uygulamanızın gösterilmesini beklerler uygulama içi bir mesaj gönderebilir ya da bir tür bildirim mekanizması kullanarak uygulamanın satın alma işlemini doğru bir şekilde aldığını ve işlediğini bilmelisiniz. Kabul edilebilir düzeyde mekanizmalar şunlardır:

  • Uygulama içi pop-up göster.
  • Mesajı uygulama içi bir mesaj kutusuna iletin ve orada açıkça uygulama içi mesaj kutusunda yeni bir mesajdır.
  • İşletim sistemi bildirim mesajı kullanın.

Uygulamanız başka herhangi bir durumda olabilir. teşekkür eder. Hatta belki uygulamanız henüz yüklendi. Kullanıcılar satın aldıkları ürünü almayı beklerler uygulamanın hangi durumda olduğu fark etmeksizin uygulamayı devam ettirdiklerinde

Uygulamanın, satın alındığını gösterir. Ancak, bunun kabul edilebileceği bazı istisnalar vardır. öğenin alındığı konusunda kullanıcıyı hemen bilgilendirmemelidir. Örnek:

  • Oyunun aksiyon bölümünde mesaj göstermek, kullanıcının dikkatini dağıtabilir belirtir. Bu durumda, kullanıcıyı işlem bölümü bittikten sonra bilgilendirmeniz gerekir.
  • Mesaj gösterilmesinin kullanıcının dikkatini dağıtabileceği ara sahnelerde. Burada Kesitten sonra kullanıcıya haber vermeniz gerekir.
  • Oyunun ilk eğitim ve kullanıcı kurulumu kısımları sırasında. Önerilerimiz: Oyunu açtıktan hemen sonra yeni kullanıcılara ödül hakkında bilgi verirsiniz veya 25-34 yaşındaki kullanıcı kurulumu sırasında gerçekleştirin. Ancak, ana toplantı gerçekleştirilene kadar kullanıcıya bilgi vermek için oyun sırası kullanılabilir.

Kullanıcılarınızı ne zaman ve nasıl bilgilendireceğinize karar verirken her zaman kullanıcıları göz önünde bulundurun en az 24 saat sürer. Kullanıcı ilk e-postada bildirimi alırsa kafaları karışabilir ve uygulamanızı kullanmayı bırakabilir, kullanıcı ile destekleyici veya şikayet edebilirler. Not: PurchasesUpdatedListener, başvurunuzda kayıtlı dışından başlatılan satın alma işlemleri de dahil olmak üzere satın alma güncellemelerini yönetmek için bağlam en iyi yoludur. Bu, başvuru sürecinizin mevcut olmadığı durumlarda PurchasesUpdatedListener bilgilendirilmeyecek. Bu nedenle uygulamanız onResume() yönteminde BillingClient.queryPurchasesAsync() yöntemini şu şekilde çağırın: Satın Alma İşlemlerini Getir bölümünde bahsedilenler.

Beklemedeki işlemleri gerçekleştirme

Google Play bekleyen işlemleri veya Kullanıcının satın alma işlemini başlatması ile ödeme yönteminin işleme alındığını unutmayın. Uygulamanız, size bu tür satın alma işlemlerinden yararlanma hakkı Kullanıcının ödeme yönteminden başarıyla ödeme alındı.

Örneğin, kullanıcı fiziksel mağaza seçerek bir işlem başlatabilir. ödeme yapacağı yer. Kullanıcı hem bildirim ve e-posta. Kullanıcı fiziksel mağazaya geldiğinde kodu kasiyerde kullanıp nakit ödeme yapabilir. Google daha sonra hem siz hem de ödemenin alındığı kullanıcı. Uygulamanız daha sonra kullanıcıya devredilebilir.

enablePendingPurchases() Uygulamanızda bekleyen işlemleri etkinleştirmek için BillingClient. Uygulamanız tek seferlik ürünler için bekleyen işlemleri etkinleştirme ve destekleme Şu tarihten önce: destek ekliyorsanız, beklemede olan müşterilerin satın alma yaşam döngüsünü anladığınızdan emin olun. işlemlerdir.

Uygulamanız, PurchasesUpdatedListener araması sonucunda veya queryPurchasesAsync(), getPurchaseState() yöntemini kullanarak satın alma durumunun PURCHASED veya PENDING olduğunu belirler. Şunları yapmalısınız: yararlanma hakkı yalnızca eyalet PURCHASED olduğunda vermelidir.

Kullanıcı satın alma işlemini tamamladığında uygulamanız çalışıyorsa PurchasesUpdatedListener tekrar arandı ve PurchaseState şimdi arandı PURCHASED. Bu noktada, uygulamanız standart satın alma işlemlerinin işlenmesi. Uygulamanız ayrıca şunları da yapmalıdır: Uygulamanızın onResume() yönteminde satın alma işlemlerini gerçekleştirmek için queryPurchasesAsync() bu reklamlar, uygulamanız çalışmıyorken PURCHASED durumuna geçirilmiştir.

Satın alma işleminin PENDING ürününden PURCHASED, Gerçek zamanlı geliştirici bildirimleri istemciniz ONE_TIME_PRODUCT_PURCHASED veya SUBSCRIPTION_PURCHASED bildirim. Satın alma işlemi iptal edilirse bir ONE_TIME_PRODUCT_CANCELED veya SUBSCRIPTION_PENDING_PURCHASE_CANCELED bildirim. Bu durum, Müşteri, ödemeyi gereken zaman aralığında tamamlamamıştır. Lütfen her zaman Google Play Developer API'sini kullanarak bir değeri için teklif verirsiniz.

Çoklu miktar satın alma işlemlerini yönetme

Google Play Faturalandırma Kitaplığı'nın 4.0 ve sonraki sürümlerinde desteklenir. Google Play, müşterilerin aynı uygulama içi birden fazla öğeyi satın almasına olanak tanır. ürünün tek bir işlemde nasıl kullanıldığını gösterir. Sizin uygulamasının çok miktarlı satın alma işlemlerini yürütmesi ve bu öğelere göre yararlanma hakkı belirtilen satın alma miktarına göre sabitlenir.

Çoklu miktar satın alma işlemlerini dikkate almak için uygulamanızın temel hazırlık mantığının, ödeme yaparsınız. Bir quantity alanına şuradan erişebilirsiniz: aşağıdaki API'lerden yararlanabilirsiniz:

Çoklu miktar satın alma işlemleri için mantık ekledikten sonra, Uygulama içinde ilgili ürün için çoklu miktar özelliğini etkinleştir Google Play Developer Console'daki ürün yönetimi sayfasından.

Kullanıcının faturalandırma yapılandırmasını sorgulama

getBillingConfigAsync(), kullanıcının kullandığı ülkeyi belirtir Google Play

Kullanıcının faturalandırma yapılandırmasını şu tarihten sonra sorgulayabilirsiniz: BillingClient oluşturarak. Aşağıdaki kod snippet'i getBillingConfigAsync() nasıl aranır? Yanıtı şu şekilde ele alın: BillingConfigResponseListener uyguluyorum. Bu dinleyiciye uygulamanızdan başlatılan tüm faturalandırma yapılandırması sorguları için güncellemeler.

Döndürülen BillingResult hatası yoksa Kullanıcının Play'ini almak için BillingConfig nesnesindeki countryCode alanı Ülke.

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