google play 退款订单详情获取

关于查看google play退款订单的前提,首先,需要获取Google API的访问权限,从获取API访问权限上来看,大致分为两种方法,第一种是通过OAuth 客户端访问,需要客户端用户来授权,才能获取Google API的访问权限,然后进行用户订单详情的查询,第二种是不需要用户来授权的,我相信这种方法也是服务端比较喜欢的,毕竟用户授权这种事情你是没办法确定能拿到权限的。对于代表非人类机器人运行的服务器应用(如持续集成系统),建议使用服务帐号。对于直接代表人类用户运行的客户端应用(如 IDE 插件),则可以使用 OAuth 客户端。我目前的项目比较适合服务账号,所以,这里我们就只介绍第二种方法,利用google play开发者账号建立服务账号,直接对其授权,然后再进行对Google API的访问。

前言

这篇文章我们从创建 Google Play 开发者帐号说起,因为我最近为了google退款订单详情的查询踩了不少的坑,也许是英语太差,所以为了更好的理解和开发google退款的流程,我尽量详细介绍,每一个参数。全凭自己理解,不喜勿喷,欢迎大神指点批评。

1. 创建账号以及关联API服务

首先我们需要有 Google Play 开发者帐号,这个账号首先你要有自己的google账号,然后到Google Play Console进行开发者账号的注册开通,这里是需要支付 $25 的注册费用的,注册完成之后就要创建新的API项目(就是创建一个你的应用项目):

  1. 在 Google Play 管理中心转到 API 访问权限页面。
  2. 接受服务条款。
  3. 点击创建新项目

如果您已是 Google Play Developer API 的用户,则可以执行以下这些步骤来关联到您现有的 API 项目。如果您想关联的 API 项目未列出,请确认您的 Google Play 管理中心帐号是否已指定为“所有者”,且 Google Play Developer API 已启用。

  1. 在 Google Play 管理中心转到 API 访问权限页面。
  2. 接受 API 服务条款。
  3. 选择您想关联的项目。
  4. 点击关联

到这里您的 Google Play 管理中心现已关联到 API 项目。一般开始写退款接口的时候google账号都已经是部署好的了应该,所以前面的步骤这里就不细说了

2. 创建服务账号

上边已经创建项目并且也关联了API,下面就可以直接
1.在 Google Play 管理中心转到 API 访问权限页面。
2.点击开发者账号
3.点击API权限
4.点击创建服务账号,按照页面上的说明创建您的服务帐号。
5.在 Google Developers Console 中创建服务帐号后,请点击完成。API 访问权限页面会自动刷新,您的服务帐号将随即列出。

创建服务账号.jpg

6.创建完服务账号需要生成一下密钥,公钥生成.json格式或者P12文件都行,我这里用的时.json文件,后面代码中要用到
6.在用户和权限页面可以看到刚创建的服务账号,接下来只要进行授权就可以使用了
设置账号的访问权限.jpg

3. 调用Google API查询退款订单详情

到了这一步就开始写接口了,我这里用的是Spring boot+cloud的框架,下面就不做解释了,首先调用google API需要引入依赖:

        
            com.google.apis
            google-api-services-androidpublisher
            v3-rev95-1.25.0
        

然后就是服务账号如何获取访问google API的权限,经过我的个人理解和google官方文档总结了一下,把整个代码给摘分开来了,第一部分是获取服务账号访问权限,创建一个访问谷歌api的GoogleCredential 相当于一个权限令牌

    private GoogleCredential getAndroidPublisherScopesOfGoogleCredential()throws Exception{
        //这里是建立服务账号后生成的.json文件,这里这样写需要把.json文件放到相应模块的resources下,想要换一个目录可以随意,但不要忘了改文件路径
        ClassPathResource classPathResource = new ClassPathResource("xxx-xxxx-xxxxxx.json");
        GoogleCredential credential = GoogleCredential.fromStream(classPathResource.getInputStream())
                .createScoped(AndroidPublisherScopes.all());//createScoped给令牌访问权限设置使用的权限范围
        if(credential!=null){
            return credential;
        }else{
            throw new Exception("Get GoogleCredential fails");
        }
    }

因为我需要调用的接口在AndroidPublisher下,所以这里的权限范围设置成了AndroidPublisherScopes.all(),这里的具体API权限范围需要自己去查阅相关文档进行了解,这里不再详细说明。

上面拿到了令牌,下面就build一个要调用的google api的对应工具类


    private AndroidPublisher getAndroidPublisher()throws Exception{
        GoogleCredential credential = this.getAndroidPublisherScopesOfGoogleCredential();
        NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();//其中这两个参数最终也没去搞明白,不知道具体的用处,目测可能是调用googleAPI发送请求用的
        JacksonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();//
        return new AndroidPublisher.Builder(httpTransport, JSON_FACTORY, credential).build();
    }

拿到了我们要用的工具类后,下面就可以调用接口了,下面这个接口是我在google官方文档找的,具体连接是:https://developers.google.com/android-publisher/api-ref/purchases/voidedpurchases/list
下面的代码中会经常用到一个参数com.cn.aaaa是项目的完全限定软件包名称,就是应用名称下面的灰色小字,根据自己的设置进行填写


    /**
     * 获取所有退款订单的PurchaseToken(google 采购成功的唯一标识)
     * @return
     * @throws Exception
     */
    private List getPurchaseToken()throws Exception{
        boolean isExistData = true;
        AndroidPublisher publisher = this.getAndroidPublisher();
        AndroidPublisher.Purchases.Voidedpurchases voidedpurchases = publisher.purchases().voidedpurchases();
        //后面还可以跟.setMaxResults 设置返回结果最大值默认1000  .setToken查询更多结果时设置(下一页nextPageToken)
        AndroidPublisher.Purchases.Voidedpurchases.List refundInfo = voidedpurchases.list("com.cn.aaaa");
        VoidedPurchasesListResponse refundList = refundInfo.execute();//执行调用动作,返回结果
        List voidedPurchases = refundList.getVoidedPurchases();
        //获取分页token,若退款订单当前页没有传完,则返回参数中会有NextPageToken,用来循环请求下一页的退款订单
        TokenPagination tokenPagination = refundList.getTokenPagination();
        while (isExistData) {
            if(tokenPagination!=null){
                AndroidPublisher.Purchases.Voidedpurchases.List nextRefundInfo = voidedpurchases.list("com.cn.aaaa").setToken(tokenPagination.getNextPageToken());
                VoidedPurchasesListResponse nextRefundLists = nextRefundInfo.execute();
                List nextVoidedPurchasess = nextRefundLists.getVoidedPurchases();
                tokenPagination = nextRefundLists.getTokenPagination();
                voidedPurchases.addAll(nextVoidedPurchasess);
            }else{
                isExistData = false;
            }
        }
        return voidedPurchases;
    }

这里终于拿到了您的应用中所有的产生退款的订单的PurchaseToken,具体的返回参数解释官方文档却比较详细,可以用上面的连接进行查阅,但是这个返回结果中除了PurchaseToken并没有订单号,而可恨的是我们的库里面根本没有存google的这个采购成功的唯一标识PurchaseToken,然后我就继续开始翻google的官网文档终于找到了一个不太方便的方法,目前我只能找到这一个解决办法。(有那位大神知道其他的简单的方法的话,求指教,留言)


    /**
     * 获取所有退款订单详情
     * @return
     * @throws Exception
     */
    public MessageResult getOrder() throws Exception {
        List purchaseTokenList = this.getPurchaseToken();
        String pakgeName = "com.cn.aaaa";
        List infoList = new ArrayList<>();
        for(VoidedPurchase voidedPurchase : purchaseTokenList) {
            String purchaseToken = voidedPurchase.getPurchaseToken();
            AndroidPublisher publisher = this.getAndroidPublisher();
            List list = new ArrayList<>();
            list.add("您的应用在google中设置的产品ID");
            ......
            list.add("您的应用在google中设置的产品ID");
            //这里之所以写这个list是因为我们只拿到了PurchaseToken,但调用GET产品详情的接口参数中包括这一订单的产品ID,
            //但是我们并不知道哪个订单是退款订单,更不知道是买的那个产品被退款,所以这里只能拿所有产品ID进行轮询
            for (String id : list) {
                AndroidPublisher.Purchases.Products.Get products = publisher.purchases().products().get(pakgeName, id, purchaseToken);
                try {
                    //这里的详细返回参数解释查看官方文档:[https://developers.google.com/android-publisher/api-ref/inappproducts/get](https://developers.google.com/android-publisher/api-ref/inappproducts/get)
                    ProductPurchase info = products.execute();
                    if(info!=null){
                        infoList.add(info);
                    }
                } catch (Exception e) {
                    //这里在异常中处理是因为当参数中的product ID与PurchaseToken代表的订单的product ID不一致时会抛错,所以在这里捕捉后进行后续处理
                    String error = e.getMessage();
                    if (error.indexOf("The purchase token does not match the product ID") > 0) {
                        log.warn("产品ID与Token中的不一致");
                    }else{
                        log.error("查询退款订单详情异常:{}",error);
                    }
                }
            }
        }
        return MessageResult.success(infoList);
    }

到这里就已经结束了,退款订单的所有详情已获取。
注:对于googleAPI的调用,必须放到国外的服务器进行接口的调用,否则国内的网络无法联通,其他任何方法不适用

你可能感兴趣的:(google play 退款订单详情获取)