接入谷歌支付4.0(Kotlin)

2 篇文章 0 订阅
2 篇文章 0 订阅

前言

很多游戏研发同学可能都需要顺带接入谷歌支付,谷歌的文档大家都懂得,有时候感觉看下来好像抓住了什么却又什么都没有抓住,导致接入工作有时候会陷入瓶颈。我整理了下谷歌支付接口,并添加了一些解释性文本及扩展代码,希望能对你有所帮助。最后贴上谷歌支付的官网地址

准备工作

谷歌后台项目传入白包,需要麻烦运营同学后台配置好商品,白包可以什么功能都没有,但一定要谷歌支付SDK,因为谷歌需要你的包里有支付相关的权限。4.0开始不用单独在manifest申明,直接依赖谷歌支付包,依赖方法:

dependencies {
	//版本可能有更新,建议使用最新版本
    val billing_version = "4.0.0"
	implementation("com.android.billingclient:billing-ktx:$billing_version")
}

传入白包后,才能够在接下来的流程中查询商品,拉起支付。

开始集成

注意:下文所指商品只针对消耗型商品!!!非消耗型商品除最后消耗步骤有区别,其余基本一致。

初始化并连接Google Play

谷歌支付需要先与Google play建立连接后才能查询商品等操作,所以最好在项目初始化成功后调用谷歌支付初始化,初始化及连接代码示例:

private lateinit var billingClient: BillingClient
billingClient = BillingClient.newBuilder(activity)
//谷歌支付回调,后面拉起支付后会用到,后面再详解
            .setListener(purchasesUpdatedListener)
            .enablePendingPurchases()
            .build()
billingClient.startConnection(object : BillingClientStateListener {
   override fun onBillingSetupFinished(billingResult: BillingResult) {
       if (billingResult.responseCode ==  BillingClient.BillingResponseCode.OK) {
           //执行初始化成功相关操作
       }
   }
   override fun onBillingServiceDisconnected() {
       //做好断开连接重连操作
 
   }
})

查询商品信息

一般游戏都会配置一张内购商品表,定义好商品名称,价格,等参数,但如果发行多个国家,可以使用该接口查询玩家所在地的币种,对应价格,国家简码等信息。查询成功返回的结果也是支付所必需的参数。另外官方也建议在查询商品信息前有无需要消耗的商品,如果有就得先消耗商品再拉起支付,否则会导致支付失败。查询商品代码示例:

//协程请求商品信息
private var paySkuDetails: ArrayList<SkuDetails> = ArrayList()
private suspend fun queryProductInfo(productIds: List<String>) {
    val params = SkuDetailsParams.newBuilder()
    params.setSkusList(productIds).setType(BillingClient.SkuType.INAPP)

    // leverage querySkuDetails Kotlin extension function
    val skuDetailsResult = withContext(Dispatchers.IO) {
        billingClient.querySkuDetails(params.build())
    }
    if (skuDetailsResult.billingResult.responseCode == BillingClient.BillingResponseCode.OK && !skuDetailsResult.skuDetailsList.isNullOrEmpty()){
        //查询成功回调
        paySkuDetails = ArrayList()
        for (skuDetailList in skuDetailsResult.skuDetailsList){
        
        }
    } else{
        //查询失败回调
    }
}

启动购买流程

购买方法需要在主线程调用,支付所需参数是上个环节查询成功的商品详情,如果查询商品失败请不要调用支付接口。拉起支付代码示例:

val flowParams = BillingFlowParams.newBuilder()
            .setSkuDetails(paySkuDetails[0])
            .setObfuscatedAccountId("可选,谷歌支付检测机制,与游戏账号关联的唯一ID,例如账号的MD5值,注意不能为空")
            .setObfuscatedProfileId("可选,和上述功能类似,但国内很多开发用来透传自己平台的订单号,慎用")
            .build()
val responseCode = billingClient.launchBillingFlow(mActivity, flowParams).responseCode

一开始谷歌初始化的时候就提到了一个支付回调接口,用来监听支付状态,谷歌支付回调代码示例:

@DelicateCoroutinesApi
private val purchasesUpdatedListener = PurchasesUpdatedListener {
        billingResult, purchases ->
    if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null){
        //支付成功,处理消耗逻辑
        for (purchase in purchases){
            mPurchase = purchase
            GlobalScope.launch {
	            consume(mPurchase)
	        }
        }
    }else if(billingResult.responseCode == BillingClient.BillingResponseCode.USER_CANCELED){
        //用户取消支付回调
    }else{
        //其他支付错误
    }
}

消耗已购买商品

最关键的来了,每次支付成功后请一定要消耗掉商品,如果不消耗测试账号5分钟,正常玩家三天就会收到谷歌的退款,如果游戏内发货了,那真的是赔了夫人又折兵,所以请一定要消耗!!!至于实在发货前消耗还是发货后消耗就看自己需求。消耗代码示例:

private suspend fun consume(purchase: Purchase) {
    val consumeParams = ConsumeParams.newBuilder()
        .setPurchaseToken(purchase.purchaseToken)
        .build()
    val consumeResult = withContext(Dispatchers.IO) {
        billingClient.consumePurchase(consumeParams)
    }
    if (consumeResult.billingResult.responseCode == BillingClient.BillingResponseCode.OK){
       	//处理商品消耗成功的逻辑
    }else{
     	//处理商品购买时消耗失败的逻辑
        
    }
}

未消耗商品查询

在一些非正常购买流程下,可能会接收不到购买成功回调,例如:多台设备;内购过程中网络中断;用户在应用外进行交易等,所以谷歌推荐在onResume和onCreate中调用BillingClient.queryPurchasesAsync()来查询是否有需要消耗的商品,我感觉最好是每次拉起支付前都查询下,有就先消耗,没有就直接拉起支付。

GlobalScope.launch {
   val purchasesResult = billingClient.queryPurchasesAsync(BillingClient.SkuType.INAPP)
   if (purchasesResult.billingResult.responseCode == BillingClient.BillingResponseCode.OK){
       if(purchasesResult.purchasesList.isNotEmpty()){
           //处理商品消耗逻辑
           for (purchase in purchasesResult.purchasesList){
           		//消耗商品
           		consume(mPurchase)
           }
       } else{
           //没有需要补消的商品
       }
   }else{
       //查询谷歌订单失败
   }
}

测试支付

到此支付部分就差不多接入结束了,最后就差测试支付了,这部分也是搞脑子的大头,下面整理了几个我踩过的坑,希望能帮到你。

  1. 保证你测试APK的签名,包名,VersionCode需要与你上传的白包保持一致;
  2. 点击支付能够展现谷歌支付弹窗,但是出现了无法购买之类的错误一般都是配置问题,请仔细检查第一条,并且确认是否正确添加了测试账号;
  3. 一定要保证你Google Play登的账号是测试账号,比较省事的做法就是手机只保留一个测试账号;
  4. 如果加入了测试账号,并且谷歌登录的账号也是对的,但拉起支付还是提示无法购买,可以清除Google Play数据试试,谷歌缓存懂得都懂;
  5. 测试账号一定要加入测试计划,不点击加入计划就算后台添加了也无法生效。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值