美文网首页
google pay支付以及支付掉单问题

google pay支付以及支付掉单问题

作者: 因为我的心 | 来源:发表于2023-01-29 13:51 被阅读0次

    一、前言:

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

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

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

    3.依赖包版本选择
    implementation 'com.android.billingclient:billing:3.0.0'
    implementation 'com.android.billingclient:billing:4.0.0'
    这2个包都是谷歌支付有关的,3.0 跟4.0 最大区别是3.0不能重复购买,只能一个个的购买,4.0版本可以购买多件(根据产品的需求 不需要一次性购买多件,我这次选择3.0)

    二、google play 后台配置:

    1、接入准备

    • 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,能选择线路台湾的

    2、设定定价,就是商品的定价:

    图片.png

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

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

    图片.png 图片.png 图片.png 图片.png 图片.png

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

    图片.png

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

    图片.png 图片.png

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

    图片.png

    三、整体流程

    图片.png

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

    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](https://so.csdn.net/so/search?q=AIDL&spm=1001.2101.3001.7020)的方法已经过时了,并且未来的版本会将之移除,推荐使用使用 Google Play 结算库

    1、添加依赖 跟 权限

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

    2、创建连接

    //连接到GooglePay
        private void connectGooglePay(String skuId) {
            //请求连接到GooglePay
            billingClient.startConnection(new BillingClientStateListener() {
                @Override
                public 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);
                }
     
                //连接失败
                @Override
                public void onBillingServiceDisconnected() {
                    Log.e(TAG, "连接到GooglePay失败,请重试");
                }
            });
        }
    

    3、查询

    //查询商品
       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() {
               @Override
               public 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));
               }
           });
       }
    

    4、购买

    //购买
      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());
      }
    

    5、购买后的回调

    @Override
      public 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();
          }
      }
    

    6、消耗

    /**
      * 消耗商品:BillingClient.BillingResponseCode.OK
      *
      *  int SERVICE_TIMEOUT = -3; //服务超时
      *  int FEATURE_NOT_SUPPORTED = -2; //不支持功能
      *  int SERVICE_DISCONNECTED = -1; //服务单元已断开
      *  int OK = 0; //成功
      *  int USER_CANCELED = 1; //用户按上一步或取消对话框
      *  int SERVICE_UNAVAILABLE = 2; //网络连接断开
      *  int BILLING_UNAVAILABLE = 3; //所请求的类型不支持 Google Play 结算服务 AIDL 版本
      *  int ITEM_UNAVAILABLE = 4; //请求的商品已不再出售。
      *  int DEVELOPER_ERROR = 5; //提供给 API 的参数无效。此错误也可能说明应用未针对结算服务正确签名或设置,或者在其清单中缺少必要的权限。
      *  int ERROR = 6; //API 操作期间出现严重错误
      *  int ITEM_ALREADY_OWNED = 7; //未能购买,因为已经拥有此商品
      *  int ITEM_NOT_OWNED = 8; //未能消费,因为尚未拥有此商品
      */
     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() {
                 @Override
                 public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
                     Log.e(TAG, "onConsumeResponse    code = " + billingResult.getResponseCode() + " ,  msg = " + billingResult.getDebugMessage() + " , purchaseToken = " + purchaseToken);
       if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
     //消耗成功,执行下一步
    }
                 }
             });
         }
     }
    

    7、查询失败订单(支付成功未消耗)

    /**
      * 查询失败的订单
      * skuType :,BillingClient.SkuType.INAPP;  BillingClient.SkuType.SUBS
      * 0:PurchaseState.UNSPECIFIED_STATE:未知状态
      * 1:PurchaseState.PURCHASED:付款完成
      * 2:PurchaseState.PENDING:购买正在等待付款完成。
      */
     public void queryFailOrder(Activity activity, String skuType) {
         MyToash.Log("pay", "-----查询需要补货的商品:");
         if (mBillingClient != null) {
             Purchase.PurchasesResult result = mBillingClient.queryPurchases(skuType);
             if (BillingClient.BillingResponseCode.OK == result.getResponseCode()) {
                 for (Purchase purchase : result.getPurchasesList()) {
                     //PURCHASED --已购买
                     if (Purchase.PurchaseState.PURCHASED == purchase.getPurchaseState()) {
                         //MyToash.Log("pay", "----------需要补货的商品:");
                         //调用google去消费
                         getConsumeGoods(activity, purchase);
                     }
                 }
             }
         }
     }
    

    五、支付遇到的掉单问题处理:

    1、分析失败的原因:

    1、付款成功,消费失败,查询google未消费订单即可;
    2、付款成功,消费失败(服务单元已断开-1,但是消费成功了,实际遇到的问题);
    3、消费成功了,调用本地发放书币失败;

    2、我的处理掉单的流程图

    正常支付流程图

    正常支付流程图.png

    重试流程图

    重试流程图.png

    六、本人的逻辑处理:

    1、GooglePayCommonUtils

    /**
     * google pay 公共方法调用
     */
    public class GooglePayCommonUtils {
        static  Activity activity = null;
        //google play的对象
        public static GoogleBillingUtil googleBillingUtil = null;
        // 购买回调接口
        public static MyOnPurchaseFinishedListener mOnPurchaseFinishedListener = new MyOnPurchaseFinishedListener();
        // 查询回调接口 - 返回无处理
        public static MyOnQueryFinishedListener mOnQueryFinishedListener = new MyOnQueryFinishedListener();
        // 启动结果回调接口-返回无处理
        public static MyOnStartSetupFinishedListener mOnStartSetupFinishedListener = new  MyOnStartSetupFinishedListener();
        /**
         * 初始化google play
         */
        public static void initPlay(Activity mActivity) {
            activity = mActivity;
            googleBillingUtil = GoogleBillingUtil.getInstance()
                    // 注意,监听器设置是可选的,视个人需求设置。
                    .setOnPurchaseFinishedListener(mOnPurchaseFinishedListener)//购买回调接口
                    .setOnQueryFinishedListener(mOnQueryFinishedListener) //查询回调接口
                    .setOnStartSetupFinishedListener(mOnStartSetupFinishedListener) //启动结果回调接口
                    .build(activity);
        }
    
        /**
         * google支付
         * google_id:谷歌ID
         * goods_id:商品ID
         */
        public static void googlePay(Activity context,String google_id,String goods_id){
            if (context != null&&googleBillingUtil!=null){
                googleBillingUtil.purchaseInApp(activity, google_id, goods_id);
            }
        }
    
        /**
         * 查询未完成消耗的订单
         */
       public static void chenkOrder(Activity context){
           if (context != null&&googleBillingUtil!=null){
               //调用线程池
               ThreadPoolManager.Companion.getInstance().addTask("googlepay", new Runnable() {
                   @Override
                   public void run() {
                       //1、查询google未消费的商品
                       googleBillingUtil.queryFailOrder(activity, BillingClient.SkuType.INAPP);
                       //2、检查本地消耗成功的商品
                       googleBillingUtil.checkRecordLoaclConsumeGoods(activity);
                       //3、查询本地的失败订单;
                       googleBillingUtil.getLocalFailOrder(activity);
                   }
               });
           }
       }
    
        /**
         * 更新用户第一次支付失败的状态
         */
        public static void updateUserFailState(){
            int is_recharge = MmkvUtils.decodeInt(CommonConstantUtils.IS_RECHARGE);
            if (is_recharge<=0){
                //支付数小于0
                MmkvUtils.encode(CommonConstantUtils.FIRST_FAIL,true);
            }else {
                MmkvUtils.encode(CommonConstantUtils.FIRST_FAIL,false);
            }
        }
        /**
         * 购买商品回调接口
         */
        public static class MyOnPurchaseFinishedListener implements GoogleBillingUtil.OnPurchaseFinishedListener {
            @Override
            public void onPurchaseSuccess(Purchase purchase) {
                MyToash.Log("pay","--MyOnPurchaseFinishedListener--purchase="+purchase.toString());
                //调用本地接口
                googleBillingUtil.getConsumeGoods(activity,purchase);
            }
    
            @Override
            public void onPurchaseFail(int responseCode) {
                updateUserFailState();
                MyToash.Log("pay","--MyOnPurchaseFinishedListener--responseCode="+responseCode);
            }
    
            @Override
            public void onPurchaseError() {
                updateUserFailState();
                MyToash.Log("pay","--MyOnPurchaseFinishedListener--onPurchaseError=");
            }
        }
    
    
        /**
         * 服务初始化结果回调接口
         */
        public static class MyOnStartSetupFinishedListener implements GoogleBillingUtil.OnStartSetupFinishedListener {
            @Override
            public void onSetupSuccess() {
    
            }
    
            @Override
            public void onSetupFail(int responseCode) {
    
            }
    
            @Override
            public void onSetupError() {
    
            }
        }
    
        /**
         * 查询商品信息回调接口
         */
        public static class MyOnQueryFinishedListener implements GoogleBillingUtil.OnQueryFinishedListener {
            @Override
            public void onQuerySuccess(String skuType, List<SkuDetails> list) {
            }
    
            @Override
            public void onQueryFail(int responseCode) {
                //查询失败
            }
    
            @Override
            public void onQueryError() {
                //查询错误
            }
        }
    
    
        /**
         * 支付
         *
         * @param palChannelBean
         * @param palChannelBean
         */
        public static void payGood(Activity activity,PayBeen.ItemsBean itemsBean, PayBeen.ItemsBean.PalChannelBean palChannelBean) {
            if (palChannelBean != null && itemsBean != null) {
               // MyToash.Log("van---", itemsBean.google_id + "    " + itemsBean.getFat_price());
                switch (palChannelBean.getPay_type()) {
                    case 1:
                        MyToash.Log("pay", "--发起内购");
                        /**
                         * google_id: 谷歌ID
                         * goods_id:商品ID
                         */
                        googleBillingUtil.purchaseInApp(activity, itemsBean.google_id, itemsBean.goods_id);
                        break;
                    case 2:
                    case 4:
                        // 应用内使用web
                        if (palChannelBean.getGateway() != null && !TextUtils.isEmpty(palChannelBean.getGateway())) {
                            Intent intent = new Intent();
                            intent.setClass(activity, WebViewActivity.class);
                            intent.putExtra("title", palChannelBean.getTitle());
                            if (palChannelBean.getGateway().contains("?")) {
                                intent.putExtra("url", palChannelBean.getGateway() +
                                        "&token=" + UserUtils.getToken(activity) +
                                        "&goods_id=" + itemsBean.goods_id);
                            } else {
                                intent.putExtra("url", palChannelBean.getGateway() +
                                        "?token=" + UserUtils.getToken(activity) +
                                        "&goods_id=" + itemsBean.goods_id);
                            }
                            if (palChannelBean.getPay_type() == 2) {
                                intent.putExtra("is_otherBrowser", true);
                            }
                            activity.startActivity(intent);
                        }
                        break;
                }
            } else {
                MyToash.ToashError(activity, LanguageUtil.getString(activity, R.string.PayActivity_zhifucuowu));
            }
        }
    }
    

    2、GoogleBillingUtil

    
    public class GoogleBillingUtil {
    
        private static final String TAG = "GoogleBillingUtil";
        private static final boolean IS_DEBUG = true;
        public static final String BILLING_TYPE_INAPP = BillingClient.SkuType.INAPP;//内购
        public static final String BILLING_TYPE_SUBS = BillingClient.SkuType.SUBS;//订阅
    
        private static BillingClient mBillingClient;
        private static BillingClient.Builder builder;
        private static OnPurchaseFinishedListener mOnPurchaseFinishedListener;//购买回调接口
        private static OnStartSetupFinishedListener mOnStartSetupFinishedListener;//启动结果回调接口
        private static OnQueryFinishedListener mOnQueryFinishedListener; //查询回调接口
        private static OnConsumeResponseListener mOnConsumeResponseListener; //消耗商品接口
    
        private boolean isAutoConsumeAsync = true;//是否在购买成功后自动消耗商品
    
        private static final GoogleBillingUtil mGoogleBillingUtil = new GoogleBillingUtil();
    
        private GoogleBillingUtil() {
    
        }
    
        /**
         * 设置skus
         *
         * @param inAppSKUS 内购id
         * @param subsSKUS  订阅id
         */
        public static void setSkus(@Nullable String[] inAppSKUS, @Nullable String[] subsSKUS) {
          /*  if (inAppSKUS != null) {
                GoogleBillingUtil.inAppSKUS = inAppSKUS;
            }
            if (subsSKUS != null) {
                GoogleBillingUtil.subsSKUS = subsSKUS;
            }*/
        }
    
        public static GoogleBillingUtil getInstance() {
            cleanListener();
            return mGoogleBillingUtil;
        }
    
        /**
         * google play初始化
         *
         * @param context
         * @return
         */
        public GoogleBillingUtil build(Context context) {
            if (mBillingClient == null) {
                synchronized (mGoogleBillingUtil) {
                    if (mBillingClient == null) {
                        //检测GooglePlay服务是否可用
                        if (isGooglePlayServicesAvailable(context)) {
                            builder = BillingClient.newBuilder(context);
                            mBillingClient = builder.enablePendingPurchases().setListener(mGoogleBillingUtil.new MyPurchasesUpdatedListener()).build();
                        } else {
                            if (IS_DEBUG) {
                                log("警告:GooglePlay服务处于不可用状态,请检查");
                            }
                            if (mOnStartSetupFinishedListener != null) {
                                mOnStartSetupFinishedListener.onSetupError();
                            }
                        }
                    } else {
                        //Google购买商品回调接口(订阅和内购都走这个接口)
                        builder.setListener(mGoogleBillingUtil.new MyPurchasesUpdatedListener());
                    }
                }
            } else {
                //Google购买商品回调接口(订阅和内购都走这个接口)
                builder.setListener(mGoogleBillingUtil.new MyPurchasesUpdatedListener());
            }
            //请求连接到GooglePay
            synchronized (mGoogleBillingUtil) {
                if (mGoogleBillingUtil.startConnection()) {
                  /*  mGoogleBillingUtil.queryInventoryInApp();
                    mGoogleBillingUtil.queryInventorySubs();
                    mGoogleBillingUtil.queryPurchasesInApp();*/
                }
            }
            return mGoogleBillingUtil;
        }
    
        /**
         * 请求连接到GooglePay
         *
         * @return
         */
        public boolean startConnection() {
            if (mBillingClient == null) {
                MyToash.Log("pay", "初始化失败:mBillingClient==null");
                return false;
            }
            MyToash.Log("pay", "--mBillingClient.isReady()-=" + mBillingClient.isReady());
            if (!mBillingClient.isReady()) {
                mBillingClient.startConnection(new BillingClientStateListener() {
                    @Override
                    public void onBillingSetupFinished(BillingResult billingResult) {
                        //  MyToash.Log("van--", "--mBillingClient.startConnection-=" + billingResult.getResponseCode() + "===" + billingResult.getDebugMessage());
                        //连接到GooglePay成功
                        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                            if (mOnStartSetupFinishedListener != null) {
                                mOnStartSetupFinishedListener.onSetupSuccess();
                            }
                        } else {
                            MyToash.Log("pay", "初始化失败:onSetupFail:code=" + billingResult.getResponseCode());
                            if (mOnStartSetupFinishedListener != null) {
                                mOnStartSetupFinishedListener.onSetupFail(billingResult.getResponseCode());
                            }
                        }
                    }
    
                    @Override
                    public void onBillingServiceDisconnected() {
                        if (mOnStartSetupFinishedListener != null) {
                            mOnStartSetupFinishedListener.onSetupError();
                        }
                        //log("初始化失败:onBillingServiceDisconnected");
                        MyToash.Log("pay", "初始化失败:onBillingServiceDisconnected");
                    }
                });
                return false;
            } else {
                return true;
            }
        }
    
    
        /**
         * getResponseCode值:
         * <p>
         * Google购买商品回调接口(订阅和内购都走这个接口)
         * int SERVICE_TIMEOUT = -3;//服务超时
         * int FEATURE_NOT_SUPPORTED = -2;//不支持功能
         * int SERVICE_DISCONNECTED = -1;//服务单元已断开
         * int OK = 0;//成功
         * int USER_CANCELED = 1;//用户按上一步或取消对话框
         * int SERVICE_UNAVAILABLE = 2;//网络连接断开
         * int BILLING_UNAVAILABLE = 3;//所请求的类型不支持 Google Play 结算服务 AIDL 版本
         * int ITEM_UNAVAILABLE = 4;//请求的商品已不再出售。
         * int DEVELOPER_ERROR = 5;//提供给 API 的参数无效。此错误也可能说明应用未针对结算服务正确签名或设置,或者在其清单中缺少必要的权限。
         * int ERROR = 6;//API 操作期间出现严重错误
         * int ITEM_ALREADY_OWNED = 7;//未能购买,因为已经拥有此商品
         * int ITEM_NOT_OWNED = 8;//未能消费,因为尚未拥有此商品
         */
        private class MyPurchasesUpdatedListener implements PurchasesUpdatedListener {
            @Override
            public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> list) {
                MyToash.Log("pay", "--MyPurchasesUpdatedListener--调用本地接口");
                //支付成功
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null && !list.isEmpty()) {
                    MyToash.Log("pay", "--onPurchasesUpdated--=" + list.size());
                    //回调支付成功
                    if (mOnPurchaseFinishedListener != null) {
                        //消耗商品
                        Purchase purchase = list.get(0);
                        mOnPurchaseFinishedListener.onPurchaseSuccess(purchase);
                    }
                } else {
                    MyToash.Log("pay", "--onPurchasesUpdatedFail--=" + billingResult.getResponseCode());
                    mOnPurchaseFinishedListener.onPurchaseFail(billingResult.getResponseCode());
                }
            }
    
        }
    
        /**
         * 查询内购商品信息
         */
        public void queryInventoryInApp() {
            queryInventory(BillingClient.SkuType.INAPP);
        }
    
        /**
         * 查询订阅商品信息
         */
        public void queryInventorySubs() {
            queryInventory(BillingClient.SkuType.SUBS);
        }
    
        private void queryInventory(final String skuType) {
    
           /* Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    if (mBillingClient == null) {
                        if (mOnQueryFinishedListener != null) {
                            mOnQueryFinishedListener.onQueryError();
                        }
                        return;
                    }
                    ArrayList<String> skuList = new ArrayList<>();
                    if (skuType.equals(BillingClient.SkuType.INAPP)) {
                        Collections.addAll(skuList, inAppSKUS);
                    } else if (skuType.equals(BillingClient.SkuType.SUBS)) {
                        Collections.addAll(skuList, subsSKUS);
                    }
                    SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
                    params.setSkusList(skuList).setType(skuType);
                    mBillingClient.querySkuDetailsAsync(params.build(), new MySkuDetailsResponseListener(skuType));
                }
            };
            executeServiceRequest(runnable);*/
        }
    
    
        /**
         * Google查询商品信息回调接口
         */
        private class MySkuDetailsResponseListener implements SkuDetailsResponseListener {
            private String skuType;
    
            public MySkuDetailsResponseListener(String skuType) {
                this.skuType = skuType;
            }
    
            @Override
            public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> list) {
                if (mOnQueryFinishedListener == null) {
                    if (IS_DEBUG) {
                        log("警告:接收到查询商品回调,但查询商品接口为Null,请设置购买接口。eg:setOnQueryFinishedListener()");
                    }
                    return;
                }
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null) {
                    mOnQueryFinishedListener.onQuerySuccess(skuType, list);
                } else {
                    mOnQueryFinishedListener.onQueryFail(billingResult.getResponseCode());
                }
            }
    
        }
    
        /**
         * 发起内购
         *
         * @param activity
         * @param skuId:googleID
         * @param goods_id:商品ID
         */
        public void purchaseInApp(Activity activity, String skuId, String goods_id) {
            //创建本地订单
            WaitDialogUtils.showDialog(activity);
            getCreateOrder(activity, goods_id, "1", new CallCheckOrder() {
                @Override
                public void call(String result) {
                    purchase(activity, skuId, BillingClient.SkuType.INAPP);
                }
            });
    
        }
    
        /**
         * 发起订阅
         *
         * @param skuId
         * @return
         */
        public void purchaseSubs(Activity activity, String skuId, String goods_id) {
            //创建本地订单
            WaitDialogUtils.showDialog(activity);
            getCreateOrder(activity, skuId, "1", new CallCheckOrder() {
                @Override
                public void call(String result) {
                    purchase(activity, skuId, BillingClient.SkuType.SUBS);
                }
            });
    
        }
    
        /**
         * 发起google play支付
         *
         * @param activity
         * @param skuId
         * @param skuType
         */
        private void purchase(Activity activity, final String skuId, final String skuType) {
            if (mBillingClient == null) {
                if (mOnPurchaseFinishedListener != null) {
                    mOnPurchaseFinishedListener.onPurchaseError();
                    MyToash.Log("pay", "-purchase-onPurchaseError");
                }
                return;
            }
            if (startConnection()) {
                List<String> skuList = new ArrayList<>();
                skuList.add(skuId);//商品的id
                skuList.add("gas");// 这个参数不能为空,值随便传
                SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
                params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
                MyToash.Log("pay", "-开始调用google查询商品接口");
                //querySkuDetailsAsync 查询方法,list集合中传入商品id,谷歌后台-》应用内商品-》具体商品
                mBillingClient.querySkuDetailsAsync(params.build(),
                        new SkuDetailsResponseListener() {
                            @Override
                            public void onSkuDetailsResponse(BillingResult billingResult,
                                                             List<SkuDetails> skuDetailsList) {
                                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && skuDetailsList != null) {
                                    //  MyToash.Log("pay", "skuDetailsList---=" + skuDetailsList.toString());
                                    for (SkuDetails skuDetailsBean : skuDetailsList) {
                                        String sku = skuDetailsBean.getSku();//商品id
                                        if (skuId.equals(sku)) {
                                            MyToash.Log("pay", "-开始调用google支付弹窗");
                                            /**
                                             * 真正的购买方法
                                             */
                                            BillingFlowParams purchaseParams =
                                                    BillingFlowParams.newBuilder()
                                                            .setSkuDetails(skuDetailsBean)
                                                            .build();
                                            //发起google支付弹窗
                                            mBillingClient.launchBillingFlow(activity, purchaseParams);
                                        }
                                    }
                                } else {
                                    MyToash.Log("pay", "goods search fail");
                                }
                            }
                        });
            } else {
                if (mOnPurchaseFinishedListener != null) {
                    MyToash.Log("pay", "---google连接失败");
                    mOnPurchaseFinishedListener.onPurchaseError();
                }
            }
        }
    
        /**
         * 消耗商品
         *
         * @param purchaseToken
         *  int SERVICE_TIMEOUT = -3; //服务超时
         *  int FEATURE_NOT_SUPPORTED = -2; //不支持功能
         *  int SERVICE_DISCONNECTED = -1; //服务单元已断开
         *  int OK = 0; //成功
         *  int USER_CANCELED = 1; //用户按上一步或取消对话框
         *  int SERVICE_UNAVAILABLE = 2; //网络连接断开
         *  int BILLING_UNAVAILABLE = 3; //所请求的类型不支持 Google Play 结算服务 AIDL 版本
         *  int ITEM_UNAVAILABLE = 4; //请求的商品已不再出售。
         *  int DEVELOPER_ERROR = 5; //提供给 API 的参数无效。此错误也可能说明应用未针对结算服务正确签名或设置,或者在其清单中缺少必要的权限。
         *  int ERROR = 6; //API 操作期间出现严重错误
         *  int ITEM_ALREADY_OWNED = 7; //未能购买,因为已经拥有此商品
         *  int ITEM_NOT_OWNED = 8; //未能消费,因为尚未拥有此商品
         */
        public void consumeAsync(Activity activity, ConsumeParams consumeParams, Purchase purchase) {
            if (mBillingClient == null) {
                return;
            }
            //本地记录消费的商品
            saveRecordLoaclConsumeGoods(activity, purchase, 1);
            mBillingClient.consumeAsync(consumeParams, new ConsumeResponseListener() {
                @Override
                public void onConsumeResponse(@NonNull BillingResult billingResult, @NonNull String s) {
    //                MyToash.Log("van---", "--consumeAsync--=" + billingResult.toString() + "---" + s);
                    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        MyToash.Log("pay", "-----消耗商品成功");
                        // ----------- 沙盒代码 - 正式环境要上报-------- -
                        if (BaseConfig.INSTANCE.getCurrentEnvironment()){
                            String pId = purchase.getSkus().get(0);
                            String price = CommonOkHttpUtils.INSTANCE.getPayPrice(pId);
                            MyToash.Log("pay", "-----消耗商品成功 "+"价格:"+price);
                            String productToken = purchase.getPurchaseToken();
                            String token = UserUtils.getToken(activity);
                            AdjustEvent event = new AdjustEvent(Constant.MD_ADJUST_czcg);
                            event.setRevenue(Double.parseDouble(price),"USD");
                            event.addCallbackParameter("productId", pId);
                            event.addCallbackParameter("productToken", productToken);
                            // event.addCallbackParameter("goods_id",goods_id);
                            event.addCallbackParameter("token", token);
    
                            event.addCallbackParameter("content_type", "1");
                            event.addCallbackParameter("book_id", ShareUitls.getString(activity, BaseKey.SP_BOOKID, ""));
                            event.addCallbackParameter("packageName", purchase.getPackageName());
                            Adjust.trackEvent(event);
                        }
                        //请求本地接口
                        getHttpPay(activity, purchase);
                        //移除
                        saveRecordLoaclConsumeGoods(activity, purchase, 2);
                    } else {
                        MyToash.Log("pay", "-----消耗商品失败" + billingResult.toString() + "---" + s + "--code:" + billingResult.getResponseCode());
                    }
                }
            });
        }
    
        /**
         * 记录本地消费的商品
         *
         * @param activity
         * @param purchase
         * @param type:    1:是保存;2:移除
         */
        private void saveRecordLoaclConsumeGoods(Activity activity, Purchase purchase, int type) {
            try {
                if (purchase != null) {
                    String uid_key = UserUtils.getUID(activity) + CommonConstantUtils.CONSUME;
                    List<String> list = new ArrayList<>();
                    //获取存储的值
                    String lastJson = MmkvUtils.decodeString(uid_key);
    
                    String pId = purchase.getSkus().get(0);
                    String purchaseToken = purchase.getPurchaseToken();
                    String packageName = purchase.getPackageName();
                    //键值对唯一的key
                    String onlyKey = purchaseToken + CommonConstantUtils.CONSUME;
                    if (type == 1) {  //保存
                        //不是空
                        if (!lastJson.isEmpty()) {
                            List<String> list2 = GsonUtil.GsonToList(lastJson, String.class);
                            for (int i = 0; i < list2.size(); i++) {
                                String data = list2.get(i);
                                OrderFailBean bean = GsonUtil.GsonToBean(data, OrderFailBean.class);
                                String tokenKey = bean.getPurchaseToken() + CommonConstantUtils.CONSUME;
                                //是否要保存一条数据
                                if (!tokenKey.equals(onlyKey)) {
                                    list.add(data);
                                }
                            }
                        }
                        //没有相同单据,保存
                        HashMap map = new HashMap();
                        map.put("pId", pId);
                        map.put("purchaseToken", purchaseToken);
                        map.put("packageName", packageName);
                        list.add(GsonUtil.BeanToJson(map));
                        String json = GsonUtil.BeanToJson(list);
                        //保存上传失败的订单
                        MmkvUtils.encode(uid_key, json);
                        MyToash.Log("pay", "--保存消耗的商品json:" + purchaseToken);
                        // MyToash.Log("pay", "--保存消耗的商品json:" + json);
                    } else if (type == 2) { //移除
                        //不是空
                        if (!lastJson.isEmpty()) {
                            int currentIndex = -1;
                            List<String> list3 = GsonUtil.GsonToList(lastJson, String.class);
                            for (int i = 0; i < list3.size(); i++) {
                                String data = list3.get(i);
                                list.add(data);
                                OrderFailBean bean = GsonUtil.GsonToBean(data, OrderFailBean.class);
                                String tokenKey = bean.getPurchaseToken() + CommonConstantUtils.CONSUME;
                                if (tokenKey.equals(onlyKey)) {
                                    currentIndex = i;
                                }
                            }
                            if (currentIndex != -1) {
                                list.remove(currentIndex);
                                String json = GsonUtil.BeanToJson(list);
                                //保存上传失败的订单
                                MmkvUtils.encode(uid_key, json);
                                MyToash.Log("pay", "--移除消耗的商品json:" + json);
                            }
                        }
                    }
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 查询本地消费商品未返回数据
         *
         * @param type
         * @param activity
         * @param purchase
         */
        public void checkRecordLoaclConsumeGoods(Activity activity) {
            try {
                String uid = UserUtils.getUID(activity);
                String uid_key = UserUtils.getUID(activity) + CommonConstantUtils.CONSUME;
                List<String> list = new ArrayList<>();
                //获取存储的值
                String lastJson = MmkvUtils.decodeString(uid_key);
                MyToash.Log("pay", "--查询本地消费后商品未返回数据lastJson:" + lastJson);
                if (!lastJson.isEmpty()) {
                    //不是空
                    list = GsonUtil.GsonToList(lastJson, String.class);
                    if (list != null && list.size() > 0) {
                        //上传
                        for (int i = 0; i < list.size(); i++) {
                            String data = list.get(i);
                            OrderFailBean bean = GsonUtil.GsonToBean(data, OrderFailBean.class);
                            String pId = bean.getpId();
                            String purchaseToken = bean.getPurchaseToken();
                            String packageName = bean.getPackageName();
                            MyToash.Log("pay", "--查询本地消费后商品未返回数据上传本地单据:" + purchaseToken);
                            //上传本地单据
                            UploadLocalFailOrder(activity, uid, pId, packageName, purchaseToken);
                            Thread.sleep(1000);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        /**
         * 获取已经内购的商品
         *
         * @return
         */
        public List<Purchase> queryPurchasesInApp() {
            return queryPurchases(BillingClient.SkuType.INAPP);
        }
    
        /**
         * 获取已经订阅的商品
         *
         * @return
         */
        public List<Purchase> queryPurchasesSubs() {
            return queryPurchases(BillingClient.SkuType.SUBS);
        }
    
        /**
         * 查询最近的购买交易
         *
         * @param skuType
         * @return
         */
        private List<Purchase> queryPurchases(String skuType) {
            if (mBillingClient == null) {
                return null;
            }
            if (!mBillingClient.isReady()) {
                //如果断开google连接,重新开始连接
                startConnection();
            } else {
                Purchase.PurchasesResult purchasesResult = mBillingClient.queryPurchases(skuType);
    
                if (purchasesResult != null) {
                    if (purchasesResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        List<Purchase> purchaseList = purchasesResult.getPurchasesList();
                      /*  if (isAutoConsumeAsync) {
                            if (purchaseList != null) {
                                for (Purchase purchase : purchaseList) {
                                    if (skuType.equals(purchase.getSku())) {
                                        ConsumeParams.Builder consumeParams = ConsumeParams.newBuilder();
                                        consumeParams.setPurchaseToken(purchase.getPurchaseToken());
                                *//*        consumeParams
                                        consumeParams.setDeveloperPayload(purchase.getDeveloperPayload());*//*
                                        consumeAsync(consumeParams.build(), purchase);
                                    }
                                }
                            }
                        }*/
                        return purchaseList;
                    }
                }
    
            }
            return null;
        }
    
        /**
         * 获取有效订阅的数量
         *
         * @return -1查询失败,0没有有效订阅,>0具有有效的订阅
         */
        public int getPurchasesSizeSubs() {
            List<Purchase> list = queryPurchasesSubs();
            if (list != null) {
                return list.size();
            }
            return -1;
        }
    
        /**
         * 通过sku获取订阅商品序号
         *
         * @param sku
         * @return
         */
        public int getSubsPositionBySku(String sku) {
            return getPositionBySku(sku, BillingClient.SkuType.SUBS);
        }
    
        /**
         * 通过sku获取内购商品序号
         *
         * @param sku
         * @return 成功返回需要 失败返回-1
         */
        public int getInAppPositionBySku(String sku) {
            return getPositionBySku(sku, BillingClient.SkuType.INAPP);
        }
    
        private int getPositionBySku(String sku, String skuType) {
    
           /* if (skuType.equals(BillingClient.SkuType.INAPP)) {
                int i = 0;
                for (String s : inAppSKUS) {
                    if (s.equals(sku)) {
                        return i;
                    }
                    i++;
                }
            } else if (skuType.equals(BillingClient.SkuType.SUBS)) {
                int i = 0;
                for (String s : subsSKUS) {
                    if (s.equals(sku)) {
                        return i;
                    }
                    i++;
                }
            }*/
            return -1;
        }
    
        private void executeServiceRequest(final Runnable runnable) {
            if (startConnection()) {
                runnable.run();
            }
        }
    
        /**
         * 通过序号获取订阅sku
         *
         * @param position
         * @return
         */
        public String getSubsSkuByPosition(int position) {
           /* if (position >= 0 && position < subsSKUS.length) {
                return subsSKUS[position];
            } else {
                return null;
            }*/
            return null;
        }
    
        /**
         * 通过序号获取内购sku
         *
         * @param position
         * @return
         */
        public String getInAppSkuByPosition(int position) {
          /*  if (position >= 0 && position < inAppSKUS.length) {
                return inAppSKUS[position];
            } else {
                return null;
            }*/
            return null;
        }
    
        /**
         * 通过sku获取商品类型(订阅获取内购)
         *
         * @param sku
         * @return inapp内购,subs订阅
         */
        public String getSkuType(String sku) {
           /* if (Arrays.asList(inAppSKUS).contains(sku)) {
                return BillingClient.SkuType.INAPP;
            } else if (Arrays.asList(subsSKUS).contains(sku)) {
                return BillingClient.SkuType.SUBS;
            }*/
            return null;
        }
    
        /**
         * 检测GooglePlay服务是否可用(需要导入包api "com.google.android.gms:play-services-location:11.8.0",也可以不检查,跳过这个代码)
         *
         * @param context
         * @return
         */
        public static boolean isGooglePlayServicesAvailable(Context context) {
            GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
            if (googleApiAvailability != null) {
                int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(context);
                return resultCode == ConnectionResult.SUCCESS;
            }
            return false;
            //return_img true;//不检查直接跳过
        }
    
        public GoogleBillingUtil setOnQueryFinishedListener(OnQueryFinishedListener onQueryFinishedListener) {
            mOnQueryFinishedListener = onQueryFinishedListener;
            return mGoogleBillingUtil;
        }
    
        public GoogleBillingUtil setOnPurchaseFinishedListener(OnPurchaseFinishedListener onPurchaseFinishedListener) {
            mOnPurchaseFinishedListener = onPurchaseFinishedListener;
            return mGoogleBillingUtil;
        }
    
        public OnStartSetupFinishedListener getOnStartSetupFinishedListener() {
            return mOnStartSetupFinishedListener;
        }
    
        public GoogleBillingUtil setOnStartSetupFinishedListener(OnStartSetupFinishedListener onStartSetupFinishedListener) {
            mOnStartSetupFinishedListener = onStartSetupFinishedListener;
            return mGoogleBillingUtil;
        }
    
        public static OnConsumeResponseListener getmOnConsumeResponseListener() {
            return mOnConsumeResponseListener;
        }
    
        public GoogleBillingUtil setOnConsumeResponseListener(OnConsumeResponseListener onConsumeResponseListener) {
            mOnConsumeResponseListener = onConsumeResponseListener;
            return mGoogleBillingUtil;
        }
    
        /**
         * 本工具查询回调接口
         */
        public interface OnQueryFinishedListener {
            //Inapp和sub都走这个接口查询的时候一定要判断skuType
            public void onQuerySuccess(String skuType, List<SkuDetails> list);
    
            public void onQueryFail(int responseCode);
    
            public void onQueryError();
        }
    
        /**
         * 本工具购买回调接口(内购与订阅都走这接口)
         */
        public interface OnPurchaseFinishedListener {
    
            public void onPurchaseSuccess(Purchase purchase);
    
            public void onPurchaseFail(int responseCode);
    
            public void onPurchaseError();
    
        }
    
        /**
         * google服务启动接口
         */
        public interface OnStartSetupFinishedListener {
            public void onSetupSuccess();
    
            public void onSetupFail(int responseCode);
    
            public void onSetupError();
        }
    
        /**
         * 消耗回调监听器
         */
        public interface OnConsumeResponseListener {
            public void onConsumeSuccess(String purchaseToken);
    
            public void onConsumeFail(int responseCode);
        }
    
        public boolean isReady() {
            return mBillingClient != null && mBillingClient.isReady();
        }
    
        public boolean isAutoConsumeAsync() {
            return isAutoConsumeAsync;
        }
    
        public void setIsAutoConsumeAsync(boolean isAutoConsumeAsync) {
            this.isAutoConsumeAsync = isAutoConsumeAsync;
        }
    
        /**
         * 清除所有监听器,防止内存泄漏
         * 如果有多个页面使用了支付,需要确保上个页面的cleanListener在下一个页面的GoogleBillingUtil.getInstance()前使用。
         * 所以不建议放在onDestory里调用
         */
        public static void cleanListener() {
            mOnPurchaseFinishedListener = null;
            mOnQueryFinishedListener = null;
            mOnStartSetupFinishedListener = null;
            mOnConsumeResponseListener = null;
            if (builder != null) {
                builder.setListener(null);
            }
        }
    
        /**
         * 断开连接google服务
         * 注意!!!一般情况不建议调用该方法,让google保留连接是最好的选择。
         */
        public static void endConnection() {
            //注意!!!一般情况不建议调用该方法,让google保留连接是最好的选择。
            if (mBillingClient != null) {
                if (mBillingClient.isReady()) {
                    mBillingClient.endConnection();
                    mBillingClient = null;
                }
            }
        }
    
        private static void log(String msg) {
            if (IS_DEBUG) {
                Log.i(TAG, msg);
            }
        }
    
        /**
         * 查询失败的订单
         * skuType :,BillingClient.SkuType.INAPP;  BillingClient.SkuType.SUBS
         * 0:PurchaseState.UNSPECIFIED_STATE:未知状态
         * 1:PurchaseState.PURCHASED:付款完成
         * 2:PurchaseState.PENDING:购买正在等待付款完成。
         */
        public void queryFailOrder(Activity activity, String skuType) {
            MyToash.Log("pay", "-----查询需要补货的商品:");
            if (mBillingClient != null) {
                Purchase.PurchasesResult result = mBillingClient.queryPurchases(skuType);
                if (BillingClient.BillingResponseCode.OK == result.getResponseCode()) {
                    for (Purchase purchase : result.getPurchasesList()) {
                        //PURCHASED --已购买
                        if (Purchase.PurchaseState.PURCHASED == purchase.getPurchaseState()) {
                            //MyToash.Log("pay", "----------需要补货的商品:");
                            //调用google去消费
                            getConsumeGoods(activity, purchase);
                        }
                    }
                }
            }
        }
    
        /**
         * 公共消费商品接口
         */
        public void getConsumeGoods(Activity activity, Purchase purchase) {
            if (purchase != null) {
                MyToash.Log("pay", "-----开始消耗商品:" + purchase.toString());
                //本地发送书券成功之后,调用消耗接口
                ConsumeParams.Builder consumeParams = ConsumeParams.newBuilder();
                consumeParams.setPurchaseToken(purchase.getPurchaseToken());
                //调用消耗商品方法
                consumeAsync(activity, consumeParams.build(), purchase);
            }
        }
    
        /**
         * 正常流程-调用本地接口发送书券和书币
         */
        public void getHttpPay(Activity activity, Purchase purchase) {
            if (purchase != null) {
                String pId = purchase.getSkus().get(0);
                String purchaseToken = purchase.getPurchaseToken();
                String packageName = purchase.getPackageName();
                //保存本地单据
                saveLocalFaileOrder(activity, purchase);
                //调用本地发书券接口
                GoPay.httpPay(activity, pId, purchaseToken, "", packageName, new GooglePayActivity.UpPay() {
                    @Override
                    public void paySuccess(String success) {
                        MyToash.Log("pay", "--本地接口调用成功:" + success);
                        //WaitDialogUtils.dismissDialog();
                        ShareUitls.putString(activity, BaseKey.SP_BOOKID, "");
                        ShareUitls.putString(activity, "goods_id", null);
                        ShareUitls.putString(activity, "productId", null);
                        ShareUitls.putString(activity, "productToken", null);
                        //通知刷新页面
                        EventBus.getDefault().post(new RefreshMine());
                        //成功提示
                        MyToash.ToashSuccess(activity, success);
                        //删除本地的数据
                        deleteLocalFaileOrder(activity, purchaseToken);
                    }
    
                    @Override
                    public void payFail(String msg) {
                        //本地接口调用失败
                        MyToash.Log("pay", "----本地接口调用失败:" + msg);
                    }
                });
            }
        }
    
        /**
         * 保存本地失败的单据
         *
         * @param activity
         */
        private void saveLocalFaileOrder(Activity activity, Purchase purchase) {
            try {
                String pId = purchase.getSkus().get(0);
                String purchaseToken = purchase.getPurchaseToken();
                String packageName = purchase.getPackageName();
                //用户id
                String uid = UserUtils.getUID(activity);
                List<String> list = new ArrayList<>();
    
                //获取存储的值
                String lastJson = MmkvUtils.decodeString(uid);
                if (!lastJson.isEmpty()) {
                    //不是空,只有第一次请求失败保存
                    List<String> list2 = GsonUtil.GsonToList(lastJson, String.class);
                    for (int i = 0; i < list2.size(); i++) {
                        String data = list2.get(i);
                        list.add(data);
                    }
                }
                //没有相同单据,保存
                HashMap map = new HashMap();
                map.put("pId", pId);
                map.put("purchaseToken", purchaseToken);
                map.put("packageName", packageName);
                list.add(GsonUtil.BeanToJson(map));
    
                String json = GsonUtil.BeanToJson(list);
                //保存上传失败的订单
                MmkvUtils.encode(uid, json);
                MyToash.Log("pay", "----保存上传失败的订单json:" + json);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 删除本地失败的单据
         *
         * @param activity
         */
        private void deleteLocalFaileOrder(Activity activity, String purchaseToken) {
            try {
                //用户id
                String uid = UserUtils.getUID(activity);
                String lastJson = MmkvUtils.decodeString(uid);
                if (!lastJson.isEmpty()) {
                    MyToash.Log("pay", "----查询准备要删除上传失败的订单:" + lastJson);
                    //不是空
                    List<String> list = GsonUtil.GsonToList(lastJson, String.class);
                    //是否有相等的下标
                    int index = -1;
                    for (int i = 0; i < list.size(); i++) {
                        String data = list.get(i);
                        OrderFailBean bean = GsonUtil.GsonToBean(data, OrderFailBean.class);
                        String token = bean.getPurchaseToken();
                        if (purchaseToken.equals(token)) {
                            index = i;
                        }
                    }
                    //删除数据
                    if (index != -1) {
                        list.remove(index);
                        String json = GsonUtil.BeanToJson(list);
                        //保存数据
                        MmkvUtils.encode(uid, json);
                        MyToash.Log("pay", "----删除上传失败的订单:" + json);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 查询订单失败--调用本地接口发送书券和书币
         */
        public void getLocalFailOrder(Activity activity) {
            try {
                //用户id
                String uid = UserUtils.getUID(activity);
                List<String> list = new ArrayList<>();
                //获取存储的值
                String lastJson = MmkvUtils.decodeString(uid);
                MyToash.Log("pay", "---查询失败的订单lastJson:" + lastJson);
                if (!lastJson.isEmpty()) {
                    //不是空
                    list = GsonUtil.GsonToList(lastJson, String.class);
                    for (int i = 0; i < list.size(); i++) {
                        String data = list.get(i);
                        OrderFailBean bean = GsonUtil.GsonToBean(data, OrderFailBean.class);
                        String pId = bean.getpId();
                        String purchaseToken = bean.getPurchaseToken();
                        String packageName = bean.getPackageName();
                        //上传失败的单据
                        UploadLocalFailOrder(activity, uid, pId, packageName, purchaseToken);
                        Thread.sleep(1000);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 上传本地单据
         *
         * @param pId
         * @param packageName
         * @param purchaseToken
         */
        private void UploadLocalFailOrder(Activity activity, String uid, String pId, String packageName, String purchaseToken) {
            try {
                //调用本地发书券接口
                GoPay.httpPay(activity, pId, purchaseToken, "", packageName, new GooglePayActivity.UpPay() {
                    @Override
                    public void paySuccess(String success) {
                        MyToash.Log("pay", "后台上传失败订单成功:" + success);
                        //WaitDialogUtils.dismissDialog();
                        ShareUitls.putString(activity, BaseKey.SP_BOOKID, "");
                        ShareUitls.putString(activity, "goods_id", null);
                        ShareUitls.putString(activity, "productId", null);
                        ShareUitls.putString(activity, "productToken", null);
                        //通知刷新页面
                        EventBus.getDefault().post(new RefreshMine());
                        //删除本地的数据
                        deleteLocalFaileOrder(activity, purchaseToken);
                        //移除消费无响应数据
                        deleteRecordLoaclConsumeGoods(activity, pId, purchaseToken, packageName);
                    }
    
                    @Override
                    public void payFail(String msg) {
                        //本地接口调用失败
                        try {
                            if (!TextUtils.isEmpty(msg)) {
                                int subIndex = msg.indexOf(",");
                                if (subIndex > 0) {
                                    String code = msg.substring(0, subIndex);
                                    String message = msg.substring(subIndex, msg.length());
                                    if ("806".equals(code)) {
                                        //删除本地的数据
                                        deleteLocalFaileOrder(activity, purchaseToken);
                                        //移除消费无响应数据
                                        deleteRecordLoaclConsumeGoods(activity, pId, purchaseToken, packageName);
                                    }
                                }
                            }
                            MyToash.Log("pay", "后台上传失败订单失败:" + msg);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        /**
         * 新-只删除消费商品无响应的状态
         *
         * @param activity
         * @param lastJson
         * @param pId
         * @param purchaseToken
         * @param packageName
         */
        private void deleteRecordLoaclConsumeGoods(Activity activity, String pId, String purchaseToken, String packageName) {
            try {
                String uid_key = UserUtils.getUID(activity) + CommonConstantUtils.CONSUME;
                List<String> list = new ArrayList<>();
                //获取存储的值
                String lastJson = MmkvUtils.decodeString(uid_key);
                //不是空
                if (!lastJson.isEmpty()) {
                    int currentIndex = -1;
                    List<String> list3 = GsonUtil.GsonToList(lastJson, String.class);
                    for (int i = 0; i < list3.size(); i++) {
                        String data = list3.get(i);
                        list.add(data);
                        OrderFailBean bean = GsonUtil.GsonToBean(data, OrderFailBean.class);
                        String tokenKey = bean.getPurchaseToken() + CommonConstantUtils.CONSUME;
                        if ((tokenKey).equals(purchaseToken + CommonConstantUtils.CONSUME)) {
                            currentIndex = i;
                        }
                    }
                    if (currentIndex != -1) {
                        list.remove(currentIndex);
                        String json = GsonUtil.BeanToJson(list);
                        //保存上传失败的订单
                        MmkvUtils.encode(uid_key, json);
                        MyToash.Log("pay", "--移除消耗的商品json:" + json);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 调用支付之前创建订单
         * goods_id:商品ID
         * content_type:内容类型 1小说
         */
        public void getCreateOrder(Activity activity, String goods_id, String content_type, CallCheckOrder CallCheckOrder) {
            ReaderParams params = new ReaderParams(activity);
            params.putExtraParams("goods_id", goods_id);
            params.putExtraParams("content_type", content_type);
            params.putExtraParams("book_id", ShareUitls.getString(activity, BaseKey.SP_BOOKID, ""));
            String json = params.generateParamsJson();
            //调用本地发书券接口
            //MyToash.Log("lyy", "--json:" + json);
            HttpUtils.getInstance().sendRequestRequestParams(activity, Api.mCreateOrderUrl, json, new HttpUtils.ResponseListener() {
                        @Override
                        public void onResponse(final String result) {
                            WaitDialogUtils.dismissDialog();
                            MyToash.Log("pay", "--创建订单成功" + result);
                            if (CallCheckOrder != null) {
                                CallCheckOrder.call("success");
                            }
                        }
    
                        @Override
                        public void onErrorResponse(String error) {
                            WaitDialogUtils.dismissDialog();
                            MyToash.Log("pay", "--创建订单失败" + error);
                        }
                    }
            );
        }
    
        public interface CallCheckOrder {
            void call(String result);
        }
    }
    
    

    参考链接:

    相关文章

      网友评论

          本文标题:google pay支付以及支付掉单问题

          本文链接:https://www.haomeiwen.com/subject/qhfphdtx.html