Google Pay调研 In-app Billing
来源:互联网 发布:哈工大大数据集团官网 编辑:程序博客网 时间:2024/05/21 10:32
Google Pay 概念
- 只能用来销售数字内容,不能销售实体商品
- 应用一旦被购买,无法进行退款服务
- Google Play不提供内容交付,开发者需要自行交付在应用内购买的数字内容
- 一个应用不能购买另一个应用发布的商品
开发备忘
混淆时添加
-keep class com.android.vending.billing.**
清单文件添加com.android.vending.BILLING 权限
配置应用的key,初始化Googlepay的时候使用,key的位置
代码编写
- 谷歌提供的sample中有一个aidl文件和util包下的工具类可以使用,功能已经封装好
- AIDL文件创建com.android.vending.billing的包将IInAppBillingService.aidl放进去(之后进行编译会在gen对应包名下面生成IInAppBillingService.java)
- com.android.vending.BILLING 权限添加
此后就可以访问google服务了
- 初始化尝试连接google服务,如果连接成功就进行消耗性商品的账单查询是否有没有消耗的商品(防止漏单)
mHelper = new IabHelper(this, GOOGLE_PAY_key); // 打开log日志 mHelper.enableDebugLogging(AppConfigs.isDebug(this)); Mlog.e("google pay 开始初始化.", mContext); // // ### Google play连接初始化开始 ### 异步回调 mHelper.startSetup(new OnIabSetupFinishedListener() { @Override public void onIabSetupFinished(IabResult result) { Mlog.e("google pay 初始化完成.", mContext); // 连接过程中出现问题 if (!result.isSuccess()) { // Mlog.e("谷歌服务未连接上Problem setting up in-app billing: " + result, mContext); // add 当未连接上谷歌服务的时候就结束,不然在没有google服务的手机上ondestory()中断服务时会出非法状态异常 mHelper = null; return; } // 异步过程,连接过程中就结束 if (mHelper == null) return; // ### Google play连接初始化结束 ### // 查询消耗商品的拥有 状态 Mlog.e("谷歌服务连接成功!开始查询消耗商品的购买状态", mContext); try { mHelper.queryInventoryAsync(mGotInventoryListener); } catch (IabAsyncInProgressException e) { Mlog.e("查询用户物品清单失败. Another async operation in progress.", mContext); } } });
- 由于此连接耗费性能,所以需要在合适地方中断链接
@Override protected void onDestroy() { super.onDestroy(); // 清除与Google Play的链接服务,释放资源 if (mHelper != null) { mHelper.disposeWhenFinished(); mHelper = null; } }
- 进行商品购买 launchPurchaseFlow方法的sku是google console中发布商品的id,extreCode是订单号,如果支付成功此订单号会通过purchase.getDeveloperPayload()返回,和本地服务器的后台确定从而完成商品的交付
。第三个参数是一个商品完成支付的监听
if (mHelper == null) { // 表示google服务未连接上 PublicFunc.showMsg(mContext, getResources().getString(R.string.google_pay_error)); return; } String sku_name = null; if ("50".equals(sku)) { sku_name = Constant.SKU_kb_50; } else if ("5".equals(sku)) { sku_name = Constant.SKU_kb_5; } else if ("100".equals(sku)) { sku_name = Constant.SKU_kb_100; } else if ("200".equals(sku)) { sku_name = Constant.SKU_kb_200; } else if ("500".equals(sku)) { sku_name = Constant.SKU_kb_500; } else if ("1000".equals(sku)) { sku_name = Constant.SKU_kb_1000; } else if ("2000".equals(sku)) { sku_name = Constant.SKU_kb_2000; } if (sku_name != null) { try { // 这句触发付款界面,界面跳转完成时回到本应用触发回调的方法 mHelper.launchPurchaseFlow(VoucherCenterActivity.this, sku_name, request_google_code, mPurchaseFinishedListener, extreCode); } catch (IabAsyncInProgressException e) { Mlog.e("唤起谷歌支付页面失败. Another async operation in progress.", mContext); } }
- 3的购买方法会触发startactivityforresult启动Google Play支付页面,所以需要重写onactivityresult来获取付款结果,Google Play的回调结果在3中第三个参数设置的监听中触发,可消耗的商品需要在支付完成时进行“消费”
protected void onActivityResult(int requestCode, int resultCode, Intent data) { Mlog.e("onActivityResult(" + requestCode + "," + resultCode + "," + data, mContext); if (mHelper == null) return; if (!mHelper.handleActivityResult(requestCode, resultCode, data)) { super.onActivityResult(requestCode, resultCode, data); } else { Mlog.e("onActivityResult handled by IABUtil.", mContext); } };
// 付款完成 从谷歌页面返回的回调 IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() { public void onIabPurchaseFinished(IabResult result, Purchase purchase) { if (mHelper == null) return; if (result.isFailure()) { Mlog.e("Error purchasing 付款失败或者取消付款: " + result, mContext); return; } Mlog.e("Purchase successful.", mContext); try { // 触发消费过程 mHelper.consumeAsync(purchase, mConsumeFinishedListener); } catch (IabAsyncInProgressException e) { Mlog.e("Error consuming " + cur_sku + ". Another async operation in progress.", mContext); return; } } };
- 4中触发消费流程,消费是一个异步过程也需要一个监听
消耗过程的原因
如果是设置的是可重复商品,当你在成功购买这个商品后是需要主动消耗的,只有消耗成功后才可以再次购买。这样设定,第一,可以避免用户重复下单购买,第二,可以保证每笔消费订单的唯一。有了以上两点就可以很好地处理漏单。 so,上面代码在成功设置billing后,第一个操作就是查询拥有的商品,就是做的漏单处理。因为支付过程其实就是你的应用程序—–>Google Play程序(通过Google Play Service)——>Google服务器——->Google Play程序(通过Google Play Service)——>你的应用程序。这样一个交互过程,还需要网络支持,所以每次支付操作不会保证百分百成功,这样就会产生漏单现象,就是用户付费成功了,但是Google Play在通知你的应用程序支付结果时,因为某些原因断掉了,这样你的程序就不知道支付是否操作成功了,so,只好在下次进游戏时查查有没有已经购买的,但是还没有消耗的商品,有的话就消耗掉,然后再把商品发送给用户。因为这个商品在消耗之前,用户是无法再次购买的,所以单个用户就只会对应单一的漏单,不会有重复的漏单。这些信息都是存到Google服务器上的,直接调代码里的查询代码就可以了。
// 消费完成调用 IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() { public void onConsumeFinished(Purchase purchase, IabResult result) { Mlog.e("物品消费过程完毕. Purchase: " + purchase + ", result: " + result, mContext); if (mHelper == null) return; if (result.isSuccess()) { Mlog.e("物品消费 successful. Provisioning.", mContext); // new AlertDialog.Builder(mContext).setMessage("sku:" + // purchase.getSku() + "dingdanhao" // +purchase.getDeveloperPayload()); // 上传这两个信息 // TODO 这里应该做充值成功的操作 } else { Mlog.e("物品消费 Error: " + result, mContext); } } };
- 对于可消耗的商品,为了防止漏单,可在初始化链接完成时查询拥有商品的清单,对于未消耗的商品进行消耗(之后才可以再次购买此商品),对应1中查询清单的监听实现
// mHelper.queryInventoryAsync异步查询完成时调用 IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() { @Override public void onQueryInventoryFinished(IabResult result, Inventory inventory) { Mlog.e("查询 物品清单 结束.", mContext); // Have we been disposed of in the meantime? If so, quit. if (mHelper == null) return; // Is it a failure? if (result.isFailure()) { Mlog.e("Failed to query 物品清单: " + result, mContext); return; } Mlog.e("Query 物品清单 was successful.", mContext); // 查询消耗品的拥有状态 for (String sku : skuList) { Purchase sku_Purchase = inventory.getPurchase(sku); if (sku_Purchase != null) { Mlog.e("现在存在未消费物品-" + sku + ". Consuming it.", mContext); try { mHelper.consumeAsync(inventory.getPurchase(sku), mConsumeFinishedListener); } catch (IabAsyncInProgressException e) { Mlog.e("未消费物品消费失败. Another async operation in progress.", mContext); } } } } };
消耗性商品APi调用流程
在应用中管理消耗型商品购买
下面是购买消耗型应用内商品的基本流程:
1. 调用 getBuyIntent 启动购买流程。
2. 从 Google Play 接收表明购买是否成功完成的响应 Bundle。
3. 如果购买成功,则通过调用 consumePurchase 消耗购买。
4. 从 Google Play 接收表明消耗是否成功完成的响应代码。
5. 如果消耗成功,则在您的应用中配置商品。之后,当用户启动或登录到您的应用时,您应检查该用户是否拥有任何尚未消耗的消耗型应用内商品;如果有,请务必消耗并配置这些商品。 如果您在应用中实现消耗型应用内商品,则可以采用下面推荐的应用启动流程:
1. 发送 getPurchases 请求,查询此用户拥有的应用内商品。
2. 如果有任何消耗型应用内商品,请通过调用 consumePurchase 消耗这些商品。 必须执行这步操作,因为应用虽然可能已完成此消耗型商品的购买订单,但在其发送消耗请求之前仍有可能已停止运行或断开连接。
3. 从 Google Play 接收表明消耗是否成功完成的响应代码。
4. 如果消耗成功,则在您的应用中配置商品。
后台需要处理的事情
- 在 Google Play Developer Console 上设置和维护商品列表。
- 注册测试帐户。
只有商品列在应用的商品列表上,您才可以使用 Google Play 的应用内购买结算功能出售它们
接入过程中遇到的问题
针对alpha版本测试
1. 支付时弹出无法购买商品
- 确保google console上后台测试版本apk的版本号、包名和测试安装的apk一致,并且经过签名 清单中注册有com.android.vending.BILLING 权限
- 并且测试账号经过测试链接(alpha版本测试页面生成的一个地址)的注册
- APP的正式版本处于发布状态
- 在手机上进行支付测试登录google账号不能是本应用的开发者账号,否则会在弹出开发者无法购买本商品的提示
- 测试需要绑定银行卡才能进行购买,在封闭式alpha测试下不会对账户进行扣款,但是绑定银行卡的时候需要选择账单地址,但是目前google好像不支持中国地区的账单,这样会出现您的交易无法完的提示
正式发布
上传一个集成了in-app billing功能的app的正式版本并发布
配置添加完成应用内商品
完成以上两步 用户就可以下载发布的app并登陆谷歌账户进行支付(手机需要安装有google play 和 google service,如果没有连支付的弹框都不会出现)
参考文章
http://blog.csdn.net/change_from_now/article/details/36668017
google In-app Billing demo
https://developer.android.com/google/play/billing/index.html
https://github.com/googlesamples/android-play-billing
谷歌控制台
https://play.google.com/apps/publish/
- Google Pay调研 In-app Billing
- Google In App Billing
- Google Play In-app Billing
- Google Play In-app Billing
- Google Play In-app Billing
- Google Play In-app Billing
- google In-app Billing FAQ
- google play in app billing
- Google Play In-app Billing
- Google Play In-app Billing
- google in-app billing faq
- google In-app Billing FAQ
- Google Play In-app Billing
- Google IAB(In-App Billing)
- google内购In-App Billing
- Google IAB(In-App Billing)
- google in-app billing(转)
- google内购In-App Billing
- 【稀疏矩阵转置】线性时间复杂度实现稀疏矩阵转置
- 花花的森林forest
- 谷歌11亿美元买台企手机团队 对硬件有长远计划
- 汽车加油问题(贪心)
- okhttp get post 使用源代码
- Google Pay调研 In-app Billing
- 在MarkDown编辑器编辑时img标签会不识别而转为![](xx.jpg)
- 【算法】数字读法转汉字
- 获取客户端的外网ip地址
- iOS之界面开发屏幕适配Interface Builder、Storyboard、Xib、Nib、AutoSizing、AutoLayout、Masonry
- 学习 显式原型与隐式原型
- Hadoop搭建之Centos 7.0系统安装
- SSL与TLS
- E