一、Google Play Console中创建订阅商品
1.再自己的项目下,选择 "产品"->"订阅",点击“建立订阅”,如下图所示
2.输入产品id和名字,产品id创建后是唯一的,且不能修改(貌似也不能删除)
3.新建计划,比如公司要求vip有3个订阅计划(一个是按1个月收费,一个3个月收费,一个按1年收费),这时候就需要分别创建三个计划
4.创建优惠,很多app订阅商品都有优惠,例如:新用户订阅可免费使用7天,具体步骤如下图所示
二、Android端订阅google 官网结算地址
订阅支付和一次性商品支付流程差不多,具体看文档,这里说下具体区别
1.查询商品类型修改setProductType(BillingClient.ProductType.SUBS)
suspend fun processPurchases() {
val productList = ArrayList<String>()
productList.add(
QueryProductDetailsParams.Product.newBuilder()
.setProductId("product_id_example")
//一次性商品
// .setProductType(BillingClient.ProductType.INAPP)
//订阅商品
.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.
}
2.支付配置
// An activity reference from which the billing flow will be launched.
Activity activity = ...;
ImmutableList productDetailsParamsList =
ImmutableList.of(
ProductDetailsParams.newBuilder()
// retrieve a value for "productDetails" by calling queryProductDetailsAsync()
.setProductDetails(productDetails)
// to get an offer token, 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);
主要设置setOfferToken,具体代码可以下载demo去看代码下载地址
下面是我自己写的一段代码,获取selectedOfferToken
billingClient.queryProductDetailsAsync(queryProductDetailsParams) { billingResult, productDetailsList ->
if (productDetailsList.isNotEmpty()) {
val productDetails = productDetailsList[0]
LogUtils.d("print","hashCode-->${productDetails.hashCode()}")
//获取计划相关(获取指定计划)
val basicOffers = productDetails.subscriptionOfferDetails?.let { retrieveEligibleOffers(it) }
val productDetailsParamsList: ArrayList<BillingFlowParams.ProductDetailsParams> = ArrayList()
val offerToken = basicOffers?.let { leastPricedOfferToken(it) }.toString()
LogUtils.d("print","offerToken-->${offerToken}")
productDetailsParamsList.add(
BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails!!)
.setOfferToken(offerToken)
.build()
)
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.build()
billingClient.launchBillingFlow(this, billingFlowParams)
} else {
Toast.makeText(this, "商品ID无效", Toast.LENGTH_SHORT).show()
}
}
/**
* 使用ProductDetails中的标记检索所有符合条件的基本计划和优惠。
*/
private fun retrieveEligibleOffers(offerDetails: MutableList<ProductDetails.SubscriptionOfferDetails>):
List<ProductDetails.SubscriptionOfferDetails> {
val eligibleOffers = emptyList<ProductDetails.SubscriptionOfferDetails>().toMutableList()
offerDetails.forEach { offerDetail ->
//data[vipAdapter.selectPosition].app_product_id是后台接口配置返回的指定计划id
if (offerDetail.basePlanId == data[vipAdapter.selectPosition].app_product_id) {
eligibleOffers.add(offerDetail)
}
}
return eligibleOffers
}
3.到这里客户端就能调起订阅,订阅后需要确认订单(没有确认,会自动退款),正常是订阅成功返回的数据,传给后台,让后台去确认订单。一下是Android端确认订单方法
/**
* 订阅确认
*/
fun handleSubscribePurchase(purchase: Purchase) {
if (purchase.purchaseState == PurchaseState.PURCHASED) {
if (!purchase.isAcknowledged) {
val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
billingClient.acknowledgePurchase(acknowledgePurchaseParams){
val responseCode = it.responseCode
val debugMessage = it.debugMessage
LogUtils.d("print", "acknowledgePurchase: $responseCode $debugMessage")
}
}
}
}