android--GooglePay 谷歌支付内购接入(1)

由于谷歌应用市场的限制令,需要把目前的APP接入googlepay 谷歌支付,以免在3月31日底,没接入的APP将会有被下架掉的风险,

整个接入流程,以及注意事项,以及踩坑记录,我都会写出来,希望对大家有所帮助,文章大概拆成2篇,来全方位记录跟概况

在这我先提前说这么几个名词

1.消耗

消耗是什么意思:消耗就相当于是订单确认,如果没有确认google会在3天后自动退款,同时这一笔物品就重新买不了

2.重试

重试是什么意思:就是重新去做处理,去查询谷歌这边,如果谷歌这边真的扣款成功,在去服务器这边查看是否成功)

3.依赖包版本选择

implementation 'com.android.billingclient:billing:3.0.0'

implementation 'com.android.billingclient:billing:4.0.0'

implementation 'com.google.android.gms:play-services-wallet:19.1.0'

这3个包都是谷歌支付有关的,3.0 跟4.0 最大区别是3.0不能重复购买,只能一个个的购买,4.0版本可以购买多件(根据产品的需求 不需要一次性购买多件,我这次选择3.0)

至于gms:play-services-wallet 没找到太多网上帖子,我就放弃了

一.接入前准备

##   1.申请一个google play开发者账号,这里我是有google play开发账号的,毕竟我们的APP是发谷歌市场的
##   2.提前准备好一个apk(不需要集成支付sdk,占位用),在google play控制台上传你的apk,这里你可以发封闭测试里面去,下面我会上图,不懂的看图
##   3.发布一个alpha或者beta的版本,发布之前需要点亮以下选项(提交商品详情内容)(确定内容分级)(选择发布范围)等,之后才能正常发布
##   4.添加测试人员,等应用审核通过之后,会得到一个地址,把地址发给对方,让对方点击同意加入测试即可
##   5.需要创建应用内商品(商品id,商品描述,定价),按提示填就可以了
##   6.在账户详细信息里面,添加许可测试的邮箱账号,许可测试响应改为 “RESPOND_NORMALLY/LICENSED”,点击保存,需要一两分钟生效,记得弄这一步,这个很坑,你不弄,你测试人员就一直不会出现测试卡测试的模式
##   7.检查你的包名和签名文件是否和Google Console 上面上传的apk包是否一致
##   8.检查版本号是否和Google console发布的apk版本是否一致
##   9.检查你是否可以购买,是否绑定了银行卡,手机支不支持Google支付,手机是否有Google服务
##   10.由于我是台湾上线APP,想测台币支付,我还得准备一个vpn,能选择线路台湾的

google play 后台配置:

1.设定定价,就是商品的定价:

按图所示建立价格, 我这里有4个价格。具体建立很简单

建立产品:一个产品对应一个定价,比如我这里580台币对应406点。创建完后,如果没问题,一定要启用,不然app那边取不到数据,另外产品ID就是唯一,后面用在代码里取数据用的。关于产品id的设置,谷歌API中有这么一说,建议是按他要求的来,比较好

2.在账户详细信息里面,添加许可测试的邮箱账号,许可测试响应改为 “RESPOND_NORMALLY/LICENSED”,点击保存,需要一两分钟生效,记得弄这一步,这个很坑,你不弄,你测试人员就一直不会出现测试卡测试的模式

三.关于发一个占位包,跟设置测试人员

成功发布后,应用市场会出现

二.整体流程

看完流程图后,我们可以简单的总结下步骤,这里业务部分我就不细说了,这东西你得根据自己业务来调整

1.进入商品选择列表界面,选择需要购买的物品
2.根据选择的物品id,创建订单
3.初始化google支付,如果google已经连接,查询这个商品ID得到商品详情;如果没连接googlepay,调用连接
4.购买操作
5.onPurchasesUpdated通过购买回调,判断是否购买成功
6。如果购买成功,拿到Google支付返回的相关信息,在服务器进行验证操作。
7.如果服务器拿到你上传的相关信息和Google支付进行交互验证,验证谷歌扣款成功,服务器收款成功,说明支付成功,成功后,要做一次消耗操作,(消耗是什么意思:消耗就相当于是订单确认,如果没有确认google会在3天后自动退款,同时这一笔物品就重新买不了

8.如果服务器拿到你上传的相关信息和Google支付进行交互验证,验证谷歌扣款成功,服务器未收款到账,说明有问题,需要做重试操作,(重试是什么意思:就是重新去做处理,去查询谷歌这边,如果谷歌这边真的扣款成功,在去服务器这边查看是否成功)

注:这里第8步,我在这2个环境下,都做了对应的操作,增加了程序的友好体验,
第1:如果用户支付完成,就没管了,每次打开APP首页,我都会去帮他们做重试操作。这种用户是无感的,体验比较友好
第2: 如果用户支付完成,退出当前页面,然后再进来商品选择页面,点击同样的商品,这个时候由于还没成功,也没做消耗处理,是会有提示框弹窗,已拥有该商品,这个时候,我是会做重试的,如果成功,他下次在点击,就可以重新购买了

三.代码接入

## 目前已经升级到V3、V4版本,AIDL的方法已经过时了,并且未来的版本会将之移除,推荐使用使用 Google Play 结算库

1.添加依赖 跟 权限

implementation 'com.android.billingclient:billing:3.0.0'

<!--谷歌商店应用内购买结算需要的权限-->
    <uses-permission android:name="com.android.vending.BILLING" />
    <uses-permission android:name="com.farsitel.bazaar.permission.PAY_THROUGH_BAZAAR" />

2.部分代码

2.1创建连接

//连接到GooglePayprivate void connectGooglePay(String skuId) {//请求连接到GooglePaybillingClient.startConnection(new BillingClientStateListener() {@Overridepublic void onBillingSetupFinished(@NonNull BillingResult billingResult) {int code = billingResult.getResponseCode();if (code != BillingClient.BillingResponseCode.OK) {String msg = billingResult.getDebugMessage();Log.e(TAG, "连接到GooglePay失败    code = " + code + "    msg = " + msg);onFail();return;}Log.e(TAG, "连接到GooglePay成功");checkSku(skuId);}//连接失败@Overridepublic void onBillingServiceDisconnected() {Log.e(TAG, "连接到GooglePay失败,请重试");}});}

2.2查询

//查询商品private void checkSku(String id) {List<String> skuList = new ArrayList<>();skuList.add(id);SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder().setSkusList(skuList).setType(BillingClient.SkuType.INAPP);billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {@Overridepublic void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable List<SkuDetails> list) {int code = billingResult.getResponseCode();if (code != BillingClient.BillingResponseCode.OK || list == null || list.isEmpty()) {String msg = billingResult.getDebugMessage();Log.e(TAG, "查询商品失败    code = " + code + "    msg = " + msg);onFail();return;}Log.e(TAG, "查询商品成功");buyIt(list.get(0));}});}

2.3购买

 //购买private void buyIt(SkuDetails skuDetails) {BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder().setSkuDetails(skuDetails).build();BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);int code = billingResult.getResponseCode();if (code != BillingClient.BillingResponseCode.OK) {String msg = billingResult.getDebugMessage();Log.e(TAG, "购买商品失败    code = " + code + "    msg = " + msg);onFail();return;}Log.e(TAG, "购买商品" + skuDetails.toString());}

2.4购买后的回调

@Overridepublic void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {int code = billingResult.getResponseCode();String msg = billingResult.getDebugMessage();Log.e(TAG, "onPurchasesUpdated:code = " + code + "    msg = " + msg);if (list != null) {for (Purchase purchase : list) {Log.e(TAG, "onPurchasesUpdated:" + purchase.toString());}}if (code == BillingClient.BillingResponseCode.OK && list != null) {Log.e(TAG, "支付成功");onSuccess(list);} else if (code == BillingClient.BillingResponseCode.USER_CANCELED) {Log.e(TAG, "支付取消");onFail();} else {Log.e(TAG, "支付失败:code = " + code + "    msg = " + msg);onFail();}}

2.5消耗

 //消耗商品    private void consume(List<Purchase> list) {if (list == null || list.isEmpty() || billingClient == null) {return;}for (Purchase purchase : list) {billingClient.consumeAsync(ConsumeParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build(), new ConsumeResponseListener() {@Overridepublic void onConsumeResponse(BillingResult billingResult, String purchaseToken) {Log.e(TAG, "onConsumeResponse    code = " + billingResult.getResponseCode() + " ,  msg = " + billingResult.getDebugMessage() + " , purchaseToken = " + purchaseToken);}});}}

2.6 成功跟失败的

 private void onFail() {//自己写关于支付失败后的操作}private void onSuccess(List<Purchase> list) {//自己写关于支付成功后的操作}

重试操作这块

这里有2种场景,要注意

1.谷歌支付成功了,但是后端没成功

2.谷歌支付成功,后端成功,但是没来得及消耗,可能是断网了,重新消耗

/*** 查询最近的购买交易*  */private void queryHistory() {Purchase.PurchasesResult mResult = billingClient.queryPurchases(BillingClient.SkuType.INAPP);if (mResult != null) {List<Purchase> list = new ArrayList();if(mResult.getPurchasesList()!=null ) {if (mResult.getPurchasesList().size() > 0) {for (int i = 0; i < mResult.getPurchasesList().size(); i++) {if (mResult.getPurchasesList().size() > 0)if (mResult.getPurchasesList().get(i).isAcknowledged()) {list.add(mResult.getPurchasesList().get(i));consume(list);} else {if (null != json) {}}}}}}}

四.坑

1.GooglePay默认只能购买一次,如果你需要重复购买一个商品 请调用consume方法

android--GooglePay 谷歌支付内购接入(1)相关推荐

  1. android--GooglePay 谷歌支付内购接入(2)

    android--GooglePay 谷歌支付内购接入(1) 一.支付返回CODE(BillingResponseCode) // * int SERVICE_TIMEOUT = -3;//服务超时 ...

  2. 谷歌应用 内购算付费应用吗_8种付费游戏,无需购买讨厌的应用内购买

    谷歌应用 内购算付费应用吗 It's rare when a mobile game doesn't come with any in-app purchases, but they still ex ...

  3. Amazon App Tester工具的安装和配置Amazon内购接入流程以及测试

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/u013007305/article/d ...

  4. ios-iap应用内购接入

    title: ios-iap应用内购接入 categories: Ios tags: [ios, iap, 内购, 苹果支付] date: 2021-03-26 16:51:37 comments: ...

  5. GooglePlay内购接入错误Google Play In-app Billing API version is less than 3

    接入谷歌内购时,代码部分接入好了,于是打算开始测试,但是打开应用后初始化时一直提示错误:Google Play In-app Billing API version is less than 3.看名 ...

  6. [iOS]应用内支付(内购)的个人开发过程及坑!

    本文基于XcodeVersion 7.3 (7D175)版本,手机是iPhone 6,9.3系统. 一. 创建测试App 首先你需要登录 App的ItunesConnection,你会看到如下界面 简 ...

  7. Android逆向笔记-大部分内购游戏破解思路

    最近出了几个Android逆向的笔记,CSDN审核不通过,在此不再做详细的笔记,仅是记录下思路,免得CSDN审核不通过. 这里以单机游戏为例,大部分是单机内购游戏. 2020-07-05 10:35: ...

  8. iOS开发支付 — 内购(IAP)

    为什么要使用内购? 如果你购买的商品,是在本App中使用和消耗的,就一定要用内购,否则会被拒绝上线,例如:游戏币.在线书籍.直播中用来打赏用的金币.app中使用的道具等.如果是直接购买商城之类的快递包 ...

  9. 瘟疫公司中国版(Android)手动破解内购

    前言 洒家近日下载了个瘟疫公司中国版(安卓版)(com.easymobi.plagueinc.mi ,版本 1.1.2(5)(.mi 小米版)),发现游戏需要内购而且价格不菲. 需求 root权限 文 ...

  10. Windows商店应用内购接入

    windows APP 和winPhone APP 接入,所用API是一样的,只是手动设置有所不同, 1.配置应用信息 可以将项目和应用商店关联,这样VS会自动下载所需信息:也可以手动设置(用别人账号 ...

最新文章

  1. MySQL基础之 恢复数据和数据库迁移
  2. 2021年春季学期-信号与系统-第十一次作业参考答案-第六小题
  3. php纯面向过程--论坛
  4. HDU 1711 Number Sequence(算法验证)
  5. Source Insight学习教程
  6. 《Java技术》第九次作业计科1501赵健宇-IO
  7. OSI、TCP/IP or Five-layer(Protocols Use) Model
  8. UVA 12716 GCD XOR(数论+枚举+打表)
  9. php 快速找到php.ini位置
  10. The Nighth Assignment
  11. handler 和 intent用法
  12. js 微信小程序根据身份证号计算年龄
  13. 利用canvas制作水印(兼容移动端哦)
  14. 记一次机房断电办公室网络瘫痪的恢复经过
  15. showdown ( markdown解析)
  16. Linux 批量删除指定后缀文件
  17. 安德斯.埃里克森 的研究
  18. excel 查找/替换 回车键
  19. MVC三层架构(超详细解析)
  20. 中艺人脸识别考勤机使用方法_人脸识别考勤机的使用方法

热门文章

  1. 关于阿里云windows服务器上ping不通公网 ip 的解决思路
  2. 数学建模基础理论【二】(定积分)
  3. 【论文精读】Learning Bounds for Importance Weighting
  4. 英特尔芯片的后缀_英特尔处理器后缀的含义是什么?
  5. ESP8266开启热点和TCP Server
  6. 利用多线程爬点dianying回家慢慢看【python爬虫入门进阶】(05)
  7. python通达信自动交易_【其他】通达信程序化交易新发现,通达信dll下单
  8. Attempt to read from field ‘android.os.VibrationEffect com.android.server.VibratorService$Vibration.
  9. XMAN misc writeup
  10. mysql ibd恢复数据_mysql通过ibd恢复数据