谷歌计费接入文档地址:https://developer.android.com/google/play/billing/billing_overview。

因为公司的海外游戏策略变更,需要接入google支付,让土豪用户直接付钱,没钱的就看广告嘛。我们没有采用google钱包,只是用Google的结算库版本,因为我们公司没有申请为google的商户。

1.添加google billing库的依赖

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

2.初始化BillingClient

private String TAG =  "MainActivity";
private BillingClient billingClient;
private Handler handler = new Handler();
private final int consumeImmediately = 0;
private final int consumeDelay = 1;billingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener(new PurchasesUpdatedListener() {@Overridepublic void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) {for (final Purchase purchase : purchases) {if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {// Acknowledge purchase and grant the item to the userLog.i(TAG, "Purchase success");//确认购买交易,不然三天后会退款给用户if (!purchase.isAcknowledged()) {acknowledgePurchase(purchase);}//消耗品 开始消耗handler.postDelayed(new Runnable() {@Overridepublic void run() {consumePuchase(purchase, consumeDelay);}}, 2000);//TODO:发放商品} else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING) {//需要用户确认Log.i(TAG, "Purchase pending,need to check");}}} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {//用户取消Log.i(TAG, "Purchase cancel");} else {//支付错误Log.i(TAG, "Pay result error,code=" + billingResult.getResponseCode() + "\nerrorMsg=" + billingResult.getDebugMessage());}}}).build();

3.连接google服务器,判断google支付是否可用(需要开启VPN)

//连接google服务器billingClient.startConnection(new BillingClientStateListener() {@Overridepublic void onBillingSetupFinished(BillingResult billingResult) {Log.i(TAG, "billingResult Code=" + billingResult.getResponseCode());if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {// The BillingClient is ready. You can query purchases here.Log.i(TAG, "Init success,The BillingClient is ready");//每次进行重连的时候都应该消耗之前缓存的商品,不然可能会导致用户支付不了queryAndConsumePurchase();} else {Log.i(TAG, "Init failed,The BillingClient is not ready,code=" + billingResult.getResponseCode() + "\nMsg=" + billingResult.getDebugMessage());}}@Overridepublic void onBillingServiceDisconnected() {// Try to restart the connection on the next request to// Google Play by calling the startConnection() method.Log.i(TAG, "Init failed,Billing Service Disconnected,The BillingClient is not ready");}});

4.进行支付,需要传入你在google平台申请的对应商品的支付码

//进行支付
private void pay(String payCode){List<String> skuList = new ArrayList<>();skuList.add(payCode);SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);billingClient.querySkuDetailsAsync(params.build(),new SkuDetailsResponseListener() {@Overridepublic void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {Log.i(TAG, "querySkuDetailsAsync=getResponseCode==" + billingResult.getResponseCode() + ",skuDetailsList.size=" + skuDetailsList.size());// Process the result.if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {if (skuDetailsList.size() > 0) {for (SkuDetails skuDetails : skuDetailsList) {String sku = skuDetails.getSku();String price = skuDetails.getPrice();Log.i(TAG, "Sku=" + sku + ",price=" + price);BillingFlowParams flowParams = BillingFlowParams.newBuilder().setSkuDetails(skuDetails).build();int responseCode = billingClient.launchBillingFlow(mActivity, flowParams).getResponseCode();if (responseCode == BillingClient.BillingResponseCode.OK) {Log.i(TAG, "成功启动google支付");} else {//BILLING_RESPONSE_RESULT_OK 0   成功//BILLING_RESPONSE_RESULT_USER_CANCELED   1   用户按上一步或取消对话框//BILLING_RESPONSE_RESULT_SERVICE_UNAVAILABLE   2   网络连接断开//BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE 3   所请求的类型不支持 Google Play 结算服务 AIDL 版本//BILLING_RESPONSE_RESULT_ITEM_UNAVAILABLE    4   请求的商品已不再出售//BILLING_RESPONSE_RESULT_DEVELOPER_ERROR 5   提供给 API 的参数无效。此错误也可能说明应用未针对 Google Play 结算服务正确签名或设置,或者在其清单中缺少必要的权限。//BILLING_RESPONSE_RESULT_ERROR   6   API 操作期间出现严重错误//BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED  7   未能购买,因为已经拥有此商品//BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED   8   未能消费,因为尚未拥有此商品Log.i(TAG, "LaunchBillingFlow Fail,code=" + responseCode);}}} else {Log.i(TAG, "skuDetailsList is empty.");}} else {Log.i(TAG, "Get SkuDetails Failed,Msg=" + billingResult.getDebugMessage());}}});}

5.确认支付,不然用户付的钱三天后又回到用户的账上了,那还玩毛线

//确认订单private void acknowledgePurchase(Purchase purchase) {AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build();AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = new AcknowledgePurchaseResponseListener() {@Overridepublic void onAcknowledgePurchaseResponse(BillingResult billingResult) {if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {Log.i(TAG, "Acknowledge purchase success");} else {Log.i(TAG, "Acknowledge purchase failed,code=" + billingResult.getResponseCode() + ",\nerrorMsg=" + billingResult.getDebugMessage());}}};billingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);}

6.消耗用户购买的一次性商品,不然用户无法进行二次购买

//消耗商品private void consumePuchase(final Purchase purchase, final int state) {ConsumeParams.Builder consumeParams = ConsumeParams.newBuilder();consumeParams.setPurchaseToken(purchase.getPurchaseToken());consumeParams.setDeveloperPayload(purchase.getDeveloperPayload());billingClient.consumeAsync(consumeParams.build(), new ConsumeResponseListener() {@Overridepublic void onConsumeResponse(BillingResult billingResult, String purchaseToken) {Log.i(TAG, "onConsumeResponse, code=" + billingResult.getResponseCode());if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {Log.i(TAG, "onConsumeResponse,code=BillingResponseCode.OK");if (state == consumeImmediately) {}} else {//如果消耗不成功,那就再消耗一次Log.i(TAG, "onConsumeResponse=getDebugMessage==" + billingResult.getDebugMessage());if (state == consumeDelay && billingResult.getDebugMessage().contains("Server error, please try again")) {handler.postDelayed(new Runnable() {@Overridepublic void run() {queryAndConsumePurchase();}}, 5 * 1000);}}}});}

7.为了保险起见,每次连接google服务器的时候,都查一下历史订单,并把购买成功的商品消耗一遍,避免之前消耗失败的同类商品无法购买,已经消耗过的商品会提示这个商品不属于你,这个不影响的

    //查询最近的购买交易,并消耗商品private void queryAndConsumePurchase() {//queryPurchases() 方法会使用 Google Play 商店应用的缓存,而不会发起网络请求billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP,new PurchaseHistoryResponseListener() {@Overridepublic void onPurchaseHistoryResponse(BillingResult billingResult,List<PurchaseHistoryRecord> purchaseHistoryRecordList) {{if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchaseHistoryRecordList != null) {for (PurchaseHistoryRecord purchaseHistoryRecord : purchaseHistoryRecordList) {// Process the result.//确认购买交易,不然三天后会退款给用户try {Purchase purchase = new Purchase(purchaseHistoryRecord.getOriginalJson(), purchaseHistoryRecord.getSignature());if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {//消耗品 开始消耗consumePuchase(purchase, consumeImmediately);//确认购买交易if (!purchase.isAcknowledged()) {acknowledgePurchase(purchase);}//TODO:这里可以添加订单找回功能,防止变态用户付完钱就杀死App的这种}} catch (JSONException e) {e.printStackTrace();}}}}}});}

至此,google支付已经完成了,下面是完整的Activity中的代码,涉及到UI的只有一个支付按钮,所以我就不另外搞完整的demo了:

package com.sxk.wanzheng.douyin;import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Toast;import com.android.billingclient.api.AcknowledgePurchaseParams;
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchaseHistoryRecord;
import com.android.billingclient.api.PurchaseHistoryResponseListener;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.android.billingclient.api.SkuDetailsResponseListener;import org.json.JSONException;import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private String TAG =  "MainActivity";private BillingClient billingClient;private Handler handler = new Handler();private final int consumeImmediately = 0;private final int consumeDelay = 1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);billingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener(new PurchasesUpdatedListener() {@Overridepublic void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) {for (final Purchase purchase : purchases) {if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {// Acknowledge purchase and grant the item to the userLog.i(TAG, "Purchase success");//确认购买交易,不然三天后会退款给用户if (!purchase.isAcknowledged()) {acknowledgePurchase(purchase);}//消耗品 开始消耗handler.postDelayed(new Runnable() {@Overridepublic void run() {consumePuchase(purchase, consumeDelay);}}, 2000);//TODO:发放商品} else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING) {//需要用户确认Log.i(TAG, "Purchase pending,need to check");}}} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {//用户取消Log.i(TAG, "Purchase cancel");} else {//支付错误Log.i(TAG, "Pay result error,code=" + billingResult.getResponseCode() + "\nerrorMsg=" + billingResult.getDebugMessage());}}}).build();//连接google服务器billingClient.startConnection(new BillingClientStateListener() {@Overridepublic void onBillingSetupFinished(BillingResult billingResult) {Log.i(TAG, "billingResult Code=" + billingResult.getResponseCode());if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {// The BillingClient is ready. You can query purchases here.Log.i(TAG, "Init success,The BillingClient is ready");//每次进行重连的时候都应该消耗之前缓存的商品,不然可能会导致用户支付不了queryAndConsumePurchase();} else {Log.i(TAG, "Init failed,The BillingClient is not ready,code=" + billingResult.getResponseCode() + "\nMsg=" + billingResult.getDebugMessage());}}@Overridepublic void onBillingServiceDisconnected() {// Try to restart the connection on the next request to// Google Play by calling the startConnection() method.Log.i(TAG, "Init failed,Billing Service Disconnected,The BillingClient is not ready");}});}@Overridepublic void onClick(View view) {switch (view.getId()){case R.id.googlePay://传入你在google上申请的对应商品的支付码pay("xxxxxxxxxxx");}}private void pay(String payCode){List<String> skuList = new ArrayList<>();skuList.add(payCode);SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);billingClient.querySkuDetailsAsync(params.build(),new SkuDetailsResponseListener() {@Overridepublic void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {Log.i(TAG, "querySkuDetailsAsync=getResponseCode==" + billingResult.getResponseCode() + ",skuDetailsList.size=" + skuDetailsList.size());// Process the result.if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {if (skuDetailsList.size() > 0) {for (SkuDetails skuDetails : skuDetailsList) {String sku = skuDetails.getSku();String price = skuDetails.getPrice();Log.i(TAG, "Sku=" + sku + ",price=" + price);BillingFlowParams flowParams = BillingFlowParams.newBuilder().setSkuDetails(skuDetails).build();int responseCode = billingClient.launchBillingFlow(mActivity, flowParams).getResponseCode();if (responseCode == BillingClient.BillingResponseCode.OK) {Log.i(TAG, "成功启动google支付");} else {//BILLING_RESPONSE_RESULT_OK    0   成功//BILLING_RESPONSE_RESULT_USER_CANCELED   1   用户按上一步或取消对话框//BILLING_RESPONSE_RESULT_SERVICE_UNAVAILABLE   2   网络连接断开//BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE 3   所请求的类型不支持 Google Play 结算服务 AIDL 版本//BILLING_RESPONSE_RESULT_ITEM_UNAVAILABLE    4   请求的商品已不再出售//BILLING_RESPONSE_RESULT_DEVELOPER_ERROR 5   提供给 API 的参数无效。此错误也可能说明应用未针对 Google Play 结算服务正确签名或设置,或者在其清单中缺少必要的权限。//BILLING_RESPONSE_RESULT_ERROR   6   API 操作期间出现严重错误//BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED  7   未能购买,因为已经拥有此商品//BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED   8   未能消费,因为尚未拥有此商品Log.i(TAG, "LaunchBillingFlow Fail,code=" + responseCode);}}} else {Log.i(TAG, "skuDetailsList is empty.");}} else {Log.i(TAG, "Get SkuDetails Failed,Msg=" + billingResult.getDebugMessage());}}});}//查询最近的购买交易,并消耗商品private void queryAndConsumePurchase() {//queryPurchases() 方法会使用 Google Play 商店应用的缓存,而不会发起网络请求billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP,new PurchaseHistoryResponseListener() {@Overridepublic void onPurchaseHistoryResponse(BillingResult billingResult,List<PurchaseHistoryRecord> purchaseHistoryRecordList) {{if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchaseHistoryRecordList != null) {for (PurchaseHistoryRecord purchaseHistoryRecord : purchaseHistoryRecordList) {// Process the result.//确认购买交易,不然三天后会退款给用户try {Purchase purchase = new Purchase(purchaseHistoryRecord.getOriginalJson(), purchaseHistoryRecord.getSignature());if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {//消耗品 开始消耗consumePuchase(purchase, consumeImmediately);//确认购买交易if (!purchase.isAcknowledged()) {acknowledgePurchase(purchase);}//TODO:这里可以添加订单找回功能,防止变态用户付完钱就杀死App的这种}} catch (JSONException e) {e.printStackTrace();}}}}}});}//消耗商品private void consumePuchase(final Purchase purchase, final int state) {ConsumeParams.Builder consumeParams = ConsumeParams.newBuilder();consumeParams.setPurchaseToken(purchase.getPurchaseToken());consumeParams.setDeveloperPayload(purchase.getDeveloperPayload());billingClient.consumeAsync(consumeParams.build(), new ConsumeResponseListener() {@Overridepublic void onConsumeResponse(BillingResult billingResult, String purchaseToken) {Log.i(TAG, "onConsumeResponse, code=" + billingResult.getResponseCode());if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {Log.i(TAG, "onConsumeResponse,code=BillingResponseCode.OK");if (state == consumeImmediately) {}} else {//如果消耗不成功,那就再消耗一次Log.i(TAG, "onConsumeResponse=getDebugMessage==" + billingResult.getDebugMessage());if (state == consumeDelay && billingResult.getDebugMessage().contains("Server error, please try again")) {handler.postDelayed(new Runnable() {@Overridepublic void run() {queryAndConsumePurchase();}}, 5 * 1000);}}}});}//确认订单private void acknowledgePurchase(Purchase purchase) {AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build();AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = new AcknowledgePurchaseResponseListener() {@Overridepublic void onAcknowledgePurchaseResponse(BillingResult billingResult) {if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {Log.i(TAG, "Acknowledge purchase success");} else {Log.i(TAG, "Acknowledge purchase failed,code=" + billingResult.getResponseCode() + ",\nerrorMsg=" + billingResult.getDebugMessage());}}};billingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);}}

注意事项:

1.记得开启VPN,VPN最好是连接美国的
2.手机上需要安装google play service,并且需要在权限设置里面允许弹窗权限

google计费接入,Billing结算库支付相关推荐

  1. Google in app billing 应用内支付

    一 简介 Google in app billing 是google play 商店的应用内支付,他是一种应用内的虚拟的道具支付服务,支持应用内支付(inapp)和订阅(subs)两种模式; 在中国, ...

  2. 最新 Google支付 Google Play 结算库 4.0 版:从创建定价、商品到测试、支付成功等步骤

    使用 Google Play 结算系统,分为线上gp后台配置和代码billing集成,以下都以应用内产品为例.我做的是小说,应用内购买的是书币. 后台配置:前提能科学上网 设定定价,就是商品的定价: ...

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

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

  4. Google Pay接入

    1.由于业务需求,准备接入Google Pay,一开始本人接到这个需求的时候,就开始到Google Pay官网以及Google.百度上搜索如何接入Google Pay,也是有发现一些文章.在我处理了一 ...

  5. Google Play In-app Billing 踩过的那些坑

    来源:http://leenjewel.github.io/blog/2014/11/21/google-play-in-app-billing-cai-guo-de-na-xie-keng/ 最近在 ...

  6. Google Play In-app Billing

    0, 概述 应用程序内部付费机制(Google Play In-app Billing, 以下简称应用内支付)是Google Play的一项服务,这种服务为应用内购买提供支付流程. 要使用这项服务,你 ...

  7. 中国农业银行h5支付(php接入中国农业银行h5支付)

    接入中国农业银行h5支付是银行找到了我们公司,说要我们开发,农行支付,给我们补贴.银行是为了推广农行的线上支付,在我看来农行支付不算太流行,我开发时,也是沟通了很多次,还到了网点柜台开通商户支付(具体 ...

  8. 【云周刊】第127期:数据可视化最强CP登场!DataV接入ECharts图表库

    原文链接 本期头条 DataV接入ECharts图表库 可视化利器强强联手 DataV 数据可视化是搭建每年天猫双十一作战大屏的幕后功臣,ECharts 是广受数据可视化从业者推崇的开源图表库.从今天 ...

  9. 【Android 应用开发】Google 官方 EasyPermissions 权限申请库 ( 最简单用法 | 一行代码搞定权限申请 | 推荐用法 )

    文章目录 一.添加依赖 二.在 AndroidManifest.xml 中配置权限 三.权限申请最简单用法 四.推荐使用的用法 五.GitHub 地址 上一篇博客 [Android 应用开发]Goog ...

最新文章

  1. 以后的知识点以PPT的形式展现
  2. sqlserver 中统计信息语句
  3. ajax 五种状态,ajax的五种状态
  4. python用什么处理文件_利用Python如何快速处理文件
  5. Unity3d中BlinnPhong光照模型注解
  6. java实体类设计_java实验1 实体类的设计-答案
  7. Python的if判断与while循环
  8. Puppet 实验十三 Foreman 基础使用
  9. 原生js写简单轮播图方式1-从左向右滑动
  10. 2.3Word2003段落设置1
  11. Jupyter Notebook代码字体更改
  12. 你的功夫真的夠了嗎?
  13. Swiper去除点击选项卡时出现的蓝色边框和蓝色背景
  14. 由于找不到vcruntime140_1.dll,无法继续执行代码
  15. ARM CPU Cortex-X3,Cortex-A715,Cortex-A510 | GPU Immortalis-G715
  16. 通过泰勒展开求自然常数e,R语言实现
  17. seosem是什么意思
  18. Synaptics FP Sensors(WBF)(PID=0011)无法录入Windows Hello问题记录
  19. 【分享】关闭科学上网后网络连接故障
  20. 什么是MTD分区和NAND flash?

热门文章

  1. 替代SSD?Crossbar进军中国存储市场
  2. 智慧城市的背后是大数据的深度挖掘和利用
  3. 香港部分超市因内地游客抢购奶粉发出限购令
  4. Q2净利润同比下降1%,甲骨文转型之路错搭“老爷车”?
  5. E. 手机服务(构造+拷贝构造+堆)
  6. b、B、kb、kB单位
  7. bootstrap class path not set in conjunction with -source 1.6
  8. [爬虫实战]利用python快速爬取NCBI中参考基因组assembly的相关信息
  9. ETC卡 PSAM卡消费流程(转载)
  10. swoole:mac下的测试工具