簡單 3 步配置 Google Play Billing | 系列分享

來源: 谷歌開發(fā)者
作者:Google Play
時間:2020-10-29
17215
Google Play Billing 系列內(nèi)容是專門為中文開發(fā)者開辟的系列分享,著重講解中國開發(fā)者對 Play Billing 最容易感到疑惑的地方。如果您有任何問題,也歡迎在留言區(qū)提出,我們會收集大家的反饋并在后續(xù)文章中做出解答。

640.webp.jpg

銷售數(shù)字內(nèi)容是許多Android應(yīng)用的主要營收渠道。具體形式包括銷售應(yīng)用內(nèi)的特定商品(如游戲金幣)以及訂閱計劃(比如允許用戶在限定時間內(nèi)訪問高級功能)。Google Play Billing作為一個數(shù)字內(nèi)容銷售的工具和服務(wù)的集合,可以幫助開發(fā)者在Android應(yīng)用中銷售線上商品。

本文將從基礎(chǔ)知識開始,帶大家逐步深入,詳細(xì)了解Google Play Billing 3,及其用例和最佳實踐。

首先,我們來熟悉一下Google Play Billing的一些關(guān)鍵組件。

Google Play管理中心(Google Play Console)-Google Play管理中心既是Android應(yīng)用發(fā)布平臺,也可以用于設(shè)置應(yīng)用中銷售的各種內(nèi)容。在Play管理中心可以配置待出售的商品,包括價格點(diǎn),以及針對每個產(chǎn)品進(jìn)行高級配置,如提供訂閱的免費(fèi)試用期;

Google Play Billing Library-這是您集成到Android應(yīng)用中的開發(fā)庫。使用此庫連接Google Play就可以執(zhí)行各種與銷售相關(guān)的任務(wù),例如在用戶購買商品時處理購買流程;

Google Play Developer API-一組REST API,可用于與Google Play通信。使用這些API可以查詢和管理應(yīng)用銷售的商品。這些API還可以驗證用戶的購買中是否存在欺詐行為,或者檢查訂閱是否仍處于有效狀態(tài)。

Google Play管理中心

https://developer.android.google.cn/distribute/console

Google Play Billing Library

https://developer.android.google.cn/google/play/billing/billing_library_overview

Google Play Developer API

https://developers.google.cn/android-publisher

了解了Google Play Billing的關(guān)鍵組件之后,我們將從頭介紹如何設(shè)置環(huán)境并開始在Android應(yīng)用中銷售商品。

1.設(shè)置Android應(yīng)用以使用Google Play Billing開發(fā)庫

第一步,也是最重要的一步,是設(shè)置Android應(yīng)用以使用Google Play Billing開發(fā)庫。

向app/build.gradle文件中添加以下依賴關(guān)系,在應(yīng)用中實現(xiàn)Google Play Billing:

implementation‘com.android.billingclient:billing:3.0.0’

添加庫依賴關(guān)系后,為應(yīng)用構(gòu)建一個發(fā)布版APK,并將其上傳到Google Play管理中心。

2.添加應(yīng)用內(nèi)產(chǎn)品

上傳APK后,可以使用Google Play管理中心開始添加要在應(yīng)用中銷售的應(yīng)用內(nèi)產(chǎn)品。在"商店發(fā)布(Store Presence)"下,有一個設(shè)置應(yīng)用內(nèi)產(chǎn)品的部分。在這里可以設(shè)置兩種類型的商品:

托管產(chǎn)品(或一次性購買)

訂閱

創(chuàng)建新的托管產(chǎn)品和訂閱時,需要輸入商品的產(chǎn)品ID(Product ID)或SKU。這個產(chǎn)品ID后續(xù)將在應(yīng)用代碼中使用,我們稍后會講到。在創(chuàng)建托管產(chǎn)品之前,應(yīng)慎重規(guī)劃產(chǎn)品ID。產(chǎn)品ID在應(yīng)用中必須唯一,并且在創(chuàng)建后無法更改或重復(fù)使用。

640 (3).png

為了使測試更快、更簡單,您可以將您的Google帳號添加到Google Play開發(fā)者帳號的"許可測試(License Testing)"中。這樣,只要軟件包名稱與Play Store中的APK匹配,就可以使用調(diào)試版本和調(diào)試簽名進(jìn)行測試。

將Google帳號添加到Google Play開發(fā)者帳號的"許可測試(License Testing)"中

https://developer.android.google.cn/google/play/billing/billing_testing#testing-purchases

3.檢查設(shè)置是否成功

在Play管理中心中設(shè)置好產(chǎn)品后,您可以在應(yīng)用中查詢產(chǎn)品的詳細(xì)信息來檢查設(shè)置是否成功。

lateinit private var billingClient:BillingClient

override fun onCreate(savedInstanceState:Bundle?){

super.onCreate(savedInstanceState)

//Set up the billing client

billingClient=BillingClient

.newBuilder(this)

.enablePendingPurchases()

.setListener(this)

.build()

billingClient.startConnection(object:BillingClientStateListener{

override fun onBillingSetupFinished(billingResult:BillingResult){

if(billingResult.responseCode==BillingClient.BillingResponseCode.OK){

Log.i(TAG,"Billing client successfully set up")

queryOneTimeProducts()

}

}

override fun onBillingServiceDisconnected(){

Log.i(TAG,"Billing service disconnected")

}

})

}

private fun queryOneTimeProducts(){

val skuListToQuery=ArrayList<String>()

skuListToQuery.add("coins_5")

//‘coins_5’is the product ID that was set in the Play Console.

//Here is where we can add more product IDs to query for based on

//what was set up in the Play Console.

val params=SkuDetailsParams.newBuilder()

params

.setSkusList(skuListToQuery)

.setType(BillingClient.SkuType.INAPP)

//SkuType.INAPP refers to'managed products'or one time purchases.

//To query for subscription products,you would use SkuType.SUBS.

billingClient.querySkuDetailsAsync(

params.build(),

object:SkuDetailsResponseListener{

override fun onSkuDetailsResponse(

result:BillingResult?,

skuDetails:MutableList<SkuDetails>?

){

Log.i(TAG,"onSkuDetailsResponse${result?.responseCode}")

if(skuDetails!=null){

for(skuDetail in skuDetails){

Log.i(TAG,skuDetail.toString())

}

}else{

Log.i(TAG,"No skus found from query")

}

}

})

}

如果一切順利,您將會看到剛剛添加進(jìn)Play管理中心的產(chǎn)品的詳細(xì)信息!

4.接入Google Play Billing開發(fā)庫

下一步,便是如何在您的Android應(yīng)用中接入Google Play Billing開發(fā)庫。

本文將以一次性購買的生命周期為例,即在應(yīng)用中銷售數(shù)字商品及授予用戶的過程。如果您在應(yīng)用中提供了訂閱功能,您也可以閱讀往期文章《訂閱取消后的那些事兒——恢復(fù)訂閱和重新訂閱》了解更復(fù)雜生命周期的訂閱流程。

一次性產(chǎn)品可以是消耗品,也可以是非消耗品。消耗品意味著用戶可以再次購買。例如,如果您的游戲允許用戶購買金幣,您可以將金幣做成消耗品,讓用戶可以多次購買。非消耗品意味著用戶只能購買一次,典型示例是包含額外應(yīng)用內(nèi)功能的升級包。

在Google Play管理中心配置應(yīng)用內(nèi)產(chǎn)品后,其銷售過程如下:

640 (4).png

讓我們逐步分析這一過程。

1.設(shè)置BillingClient-BillingClient類讓您的應(yīng)用可以與Play Billing Library進(jìn)行通信。您的應(yīng)用需要做的第一件事是調(diào)用startConnection()與Google Play建立連接。

startConnection()

https://developer.android.google.cn/reference/com/android/billingclient/api/BillingClient#startconnection

在實際環(huán)境中連接是有可能中斷的,所以您的應(yīng)用還必須重寫onBillingServiceDisconnected()回調(diào)來處理重新連接,確保應(yīng)用在發(fā)出任何進(jìn)一步請求之前已與Google Play連接。

//Set up the billing client

val billingClient=BillingClient

.newBuilder(this)

.enablePendingPurchases()

.setListener(this)

.build()

billingClient.startConnection(object:BillingClientStateListener{

override fun onBillingSetupFinished(billingResult:BillingResult){

if(billingResult.responseCode==OK){

Log.i(TAG,"Billing client successfully set up!")

//Query for existing user purchases

//Query for products for sale

}

}

override fun onBillingServiceDisconnected(){

Log.i(TAG,"Billing service disconnected")

//Restart the connection with startConnection()so future requests don't fail.

}

})

onBillingServiceDisconnected()

https://developer.android.google.cn/reference/com/android/billingclient/api

/BillingClientStateListener#onBillingServiceDisconnected()

2.獲取用戶的既有購買記錄-成功設(shè)置BillingClient后,您的應(yīng)用現(xiàn)在可以調(diào)用queryPurchases()來查詢用戶先前的購買記錄。

/**

*Query Google Play Billing for existing purchases.

*

*New purchases will be provided to PurchasesUpdatedListener.

*/

fun queryPurchases(){

if(!billingClient.isReady){

Log.e(TAG,"queryPurchases:BillingClient is not ready")

}

//Query for existing in app products that have been purchased.This does NOT include subscriptions.

val result=billingClient.queryPurchases(BillingClient.SkuType.INAPP)

if(result.purchasesList==null){

Log.i(TAG,"No existing in app purchases found.")

}else{

Log.i(TAG,"Existing purchases:${result.purchasesList}")

}

}

queryPurchases()

https://developer.android.google.cn/reference/com/android/billingclient/api/BillingClient#querypurchases

3.呈現(xiàn)待售產(chǎn)品-在本文的前半部分我們談到了如何在Google Play管理中心中設(shè)置產(chǎn)品以及如何在應(yīng)用中查詢這些產(chǎn)品。在調(diào)用querySkuDetailsAsync()獲取每個產(chǎn)品的SkuDetails后,即可使用這些信息設(shè)置對應(yīng)的界面。

private fun queryOneTimeProducts(){

val skuListToQuery=ArrayList<String>()

//sku refers to the product ID that was set in the Play Console

skuListToQuery.add("small_pineapple_seed")

val params=SkuDetailsParams.newBuilder()

params

.setSkusList(skuListToQuery)

.setType(BillingClient.SkuType.INAPP)

//SkuType.INAPP refers to'managed products'or one time purchases

//To query for subscription products,you would use SkuType.SUBS

billingClient.querySkuDetailsAsync(

params.build(),

object:SkuDetailsResponseListener{

override fun onSkuDetailsResponse(

result:BillingResult,

skuDetails:MutableList<SkuDetails>?

){

if(skuDetails!=null){

//Store sku and skuDetail to be used later

}else{

Log.i(TAG,"No sku found from query")

}

}

})

}

querySkuDetailsAsync()

https://developer.android.google.cn/reference/com/android/billingclient/api/BillingClient#queryskudetailsasync

SkuDetails

https://developer.android.google.cn/reference/com/android/billingclient/api/SkuDetails

4.啟動購買流程-當(dāng)用戶點(diǎn)擊產(chǎn)品進(jìn)行購買時,您的應(yīng)用需要帶上產(chǎn)品SkuDetails來調(diào)用launchBillingFlow(),從而向用戶展示Google Play購買界面(如下圖所示)。

640 (5).png

fun launchPurchaseFlow(skuDetails:SkuDetails){

val flowParams=BillingFlowParams.newBuilder()

.setSkuDetails(skuDetails)

.build()

val responseCode=billingClient.launchBillingFlow(this,flowParams)

Log.i(TAG,"launchPurchaseFlow result${responseCode}")

}

launchBillingFlow()

https://developer.android.google.cn/reference/com/android/billingclient/api/BillingClient#launchbillingflow

5.處理購買結(jié)果-在用戶退出Google Play購買界面時(點(diǎn)擊"購買"按鈕完成購買,或者點(diǎn)擊"返回"按鈕取消購買),onPurchaseUpdated()回調(diào)會將購買流程的結(jié)果發(fā)送回您的應(yīng)用。然后,根據(jù)BillingResult.responseCode即可確定用戶是否成功購買產(chǎn)品。如果responseCode==OK,則表示購買已成功完成。

onPurchaseUpdated()

https://developer.android.google.cn/reference/com/android/billingclient/api/PurchasesUpdatedListener

#onPurchasesUpdated(com.android.billingclient.api.BillingResult,%20java.util.List%3Ccom.android.billingclient.api.Purchase%3E)

BillingResult.responseCode

https://developer.android.google.cn/reference/com/android/billingclient/api/BillingClient.BillingResponseCode

onPurchaseUpdated()會傳回一個Purchase對象列表,其中包括用戶通過應(yīng)用進(jìn)行的所有購買。每個Purchase對象都包含sku、purchaseToken和isAcknowledged以及其他很多字段。使用這些字段,您可以確定每個Purchase對象是需要處理的新購買還是不需要進(jìn)一步處理的既有購買。

//Google Play calls this method to propogate the result of the purchase flow

override fun onPurchasesUpdated(billingResult:BillingResult,purchases:List<Purchase?>?){

if(billingResult.responseCode==OK&&purchases!=null){

for(purchase in purchases){

handlePurchase(purchase)

}

}else if(billingResult.responseCode==USER_CANCELED){

Log.i(TAG,"User cancelled purchase flow.")

}else{

Log.i(TAG,"onPurchaseUpdated error:${billingResult?.responseCode}")

}

}

Purchase

https://developer.android.google.cn/reference/com/android/billingclient/api/Purchase

6.驗證和確認(rèn)購買-使用Play Billing Library 3.0時,您的應(yīng)用需要確認(rèn)購買成功才能完成購買流程。如果您的應(yīng)用未在72小時內(nèi)確認(rèn)購買,則用戶會自動收到退款,并且Google Play會撤消該購買交易。

如果您的應(yīng)用包含驗證服務(wù)器組件,您應(yīng)在驗證成功后再確認(rèn)購買。我們強(qiáng)烈推薦開發(fā)者對所有的應(yīng)用內(nèi)購買進(jìn)行驗證。請查看本指南了解有關(guān)打擊欺詐性購買的更多信息。

指南:打擊欺詐和濫用行為

https://developer.android.google.cn/google/play/billing/security#verify

在對購買進(jìn)行驗證之后,您還需要對其進(jìn)行確認(rèn)。

非消耗品必須通過調(diào)用acknowledgePurchase()進(jìn)行確認(rèn);

消耗品必須通過調(diào)用consumeAsync()來標(biāo)記為"已消耗(consumed)",使得用戶可以再次購買。調(diào)用consumeAsync()還會將購買設(shè)置為已確認(rèn),因此只要調(diào)用了consumeAsync(),就無需再對消耗品調(diào)用acknowledgePurchase()。

fun handlePurchase(purchase:Purchase){

//If your app has a server component,first verify the purchase by checking that the

//purchaseToken hasn't already been used.

//If purchase was a consumable product(a product you want the user to be able to buy again)

handleConsumableProduct(purchase)

//If purchase was non-consumable product

handleNonConsumableProduct(purchase)

}

fun handleConsumableProduct(purchase:Purchase){

val consumeParams=

ConsumeParams.newBuilder()

.setPurchaseToken(purchase.getPurchaseToken())

.build()

billingClient.consumeAsync(consumeParams,{billingResult,purchaseToken->

if(billingResult.responseCode==BillingResponse.OK){

//Handle the success of the consume operation.

}

})

}

fun handleNonConsumableProduct(purchase:Purchase){

if(purchase.purchaseState==PURCHASED){

if(!purchase.isAcknowledged){

val acknowledgePurchaseParams=AcknowledgePurchaseParams.newBuilder()

.setPurchaseToken(purchase.purchaseToken)

billingClient.acknowledgePurchase(acknowledgePurchaseParams.build())

}

}

}

acknowledgePurchase()

https://developer.android.google.cn/reference/com/android/billingclient/api

/BillingClient#acknowledgepurchase

consumeAsync()

https://developer.android.google.cn/reference/com/android/billingclient/api/BillingClient#consumeasync

7.授予用戶產(chǎn)品-完成上述步驟后,您的應(yīng)用就可以向用戶授予他們購買的應(yīng)用內(nèi)產(chǎn)品了!

如果您想查看Google Play Billing開發(fā)庫的資源,可以在此處訪問官方文檔。我們還提供了一些示例,演示了實現(xiàn)Billing庫的最佳實踐。本文中的代碼示例可以在GitHub上獲取。

官方文檔:Google Play Billing服務(wù)概覽

https://developer.android.google.cn/google/play/billing/billing_overview

Play Billing開發(fā)庫示例

https://github.com/android/play-billing-samples

本文中的代碼示例

http://github.com/calren

如果您的應(yīng)用目前尚未使用Play Billing Library 3,務(wù)必查看我們的遷移指南,將您的應(yīng)用遷移到最新的Play Billing Library。

從AIDL遷移到Google Play Billing開發(fā)庫的遷移指南

https://developer.android.google.cn/google/play/billing/migrat

立即登錄,閱讀全文
版權(quán)說明:
本文內(nèi)容來自于谷歌開發(fā)者,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個人觀點(diǎn),不代表快出海對觀點(diǎn)贊同或支持。如有侵權(quán),請聯(lián)系管理員(zzx@kchuhai.com)刪除!
優(yōu)質(zhì)服務(wù)商推薦
更多