新闻详情

googlePlay订阅商品对接流程

发布时间:2018-05-18 10:49:04 点击数:

googlePlay订阅商品对接流程

第一步.配置Google实时开发者通知

具体流程可以参考Google实时开发者通知或者中文文档(备份)
一、网域验证

登录对应的Google账号去https://search.google.com/search-console/验证,使用域名前缀-html验证的方式,下载对应html文件给放到自己域名对应的服务器上

二、添加网域到Google Console

在这里插入图片描述

三、创建对应的Google Pub/Subs
  1. 创建一个主题
    在这里插入图片描述

  2. 添加google-play-developer-notifications@system.gserviceaccount.com为该主题的Pub/Sub发布者
    在这里插入图片描述

  3. 创建一个订阅
    在这里插入图片描述

四、在Google Play添加对应的主题名称

在这里插入图片描述

各步骤所需参数及网址

Google实时开发者通知账户:


google-play-developer-notifications@system.gserviceaccount.com

Google Search Console(网域验证):


https://search.google.com/search-console/

Google Cloud Console(Google云-订阅):


https://console.cloud.google.com/cloudpubsub

Google Console(Google控制台)


https://console.developers.google.com/apis

Google Play Console(Google Play控制台)


https://play.google.com/apps/publish

第二步.开发Google实时开发者通知(订阅回调)接口

对应回调接收接口开发参考Google实时开发者通知(订阅回调)接口开发

回调接口:

@RequestMapping(value = "/googleNotify")public String googleNotify(@RequestBody(required = false) byte[] body,HttpServletRequest request, HttpServletResponse response) {
    Map<String, String> params = new HashMap<String, String>();
    JSONObject paramJson = null;
    try {
        String paramStr = null;
        String bodyStr = null;
        try {
            bodyStr = new String(body, "utf-8");
            paramStr = bodyStr;
            //回调具体内容见下方
            log.debug("googleNotify params :{}",paramStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!CStr.isEmpty(paramStr)){
            paramJson = JSON.parseObject(URLDecoder.decode(paramStr,"utf-8"));
            try {
                JSONObject msgJson = paramJson.getJSONObject("message");
                String data = msgJson.getString("data");
                log.debug("googleNotify data :{}",paramStr);
                String developerNotificationStr = new String(Base64.getDecoder().decode(data), "UTF-8");
                JSONObject developerNotificationJson = JSON.parseObject(developerNotificationStr);
                String packageName = developerNotificationJson.getString("packageName");
                String eventTimeMillis = developerNotificationJson.getString("eventTimeMillis");
                JSONObject subscriptionNotificationJson = developerNotificationJson.getJSONObject("subscriptionNotification");
                String purchaseToken = subscriptionNotificationJson.getString("purchaseToken");
                String subscriptionId = subscriptionNotificationJson.getString("subscriptionId");
                /**
                 * notificationType    int
                 * 通知的类型。它可以具有以下值:
                 * (1) SUBSCRIPTION_RECOVERED - 从帐号保留状态恢复了订阅。
                 * (2) SUBSCRIPTION_RENEWED - 续订了处于活动状态的订阅。
                 * (3) SUBSCRIPTION_CANCELED - 自愿或非自愿地取消了订阅。如果是自愿取消,在用户取消时发送。
                 * (4) SUBSCRIPTION_PURCHASED - 购买了新的订阅。
                 * (5) SUBSCRIPTION_ON_HOLD - 订阅已进入帐号保留状态(如已启用)。
                 * (6) SUBSCRIPTION_IN_GRACE_PERIOD - 订阅已进入宽限期(如已启用)。
                 * (7) SUBSCRIPTION_RESTARTED - 用户已通过“Play”>“帐号”>“订阅”重新激活其订阅(需要选择使用订阅恢复功能)。
                 * (8) SUBSCRIPTION_PRICE_CHANGE_CONFIRMED - 用户已成功确认订阅价格变动。
                 * (9) SUBSCRIPTION_DEFERRED - 订阅的续订时间点已延期。
                 * (10) SUBSCRIPTION_PAUSED - 订阅已暂停。
                 * (11) SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED - 订阅暂停计划已更改。
                 * (12) SUBSCRIPTION_REVOKED - 用户在有效时间结束前已撤消订阅。
                 * (13) SUBSCRIPTION_EXPIRED - 订阅已过期。
                 */
                int notificationType = subscriptionNotificationJson.getIntValue("notificationType");
                JSONObject resultJson = googleNotify(notificationType,packageName,subscriptionId,purchaseToken,CNum.longVal(eventTimeMillis));
                if(resultJson != null){
                    //===========================================
                    
                    /** 回调后对应的购买流程 **/
                    
                    //===========================================
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;}

回调内容(data内容为base64加密后内容,使用 new String(Base64.getDecoder().decode(data), “UTF-8”) 解密即可):

{
    "message": {
        "data": "ewogICAgInZlcnNpb24iOiAiMS4wIiwKICAgICJwYWNrYWdlTmFtZSI6ICLljIXlkI0iLAogICAgImV2ZW50VGltZU1pbGxpcyI6ICLml7bpl7TmiLMo5q+r56eSKSIsCiAgICAic3Vic2NyaXB0aW9uTm90aWZpY2F0aW9uIjogewogICAgICAgICJ2ZXJzaW9uIjogIjEuMCIsCiAgICAgICAgIm5vdGlmaWNhdGlvblR5cGUiOiA0LAogICAgICAgICJwdXJjaGFzZVRva2VuIjogIuaUr+S7mOS7pOeJjCIsCiAgICAgICAgInN1YnNjcmlwdGlvbklkIjogIuiuoumYheeahOWVhuWTgWlkIgogICAgfQp9",
        "messageId": "消息id",
        "message_id": "消息id",
        "publishTime": "2019-11-14T03:58:43.608Z",
        "publish_time": "2019-11-14T03:58:43.608Z"
    },
    "subscription": "projects/{project_id}/topics/{topic_name}"}

data内容:

{
    "version": "1.0",
    "packageName": "包名",
    "eventTimeMillis": "时间戳(毫秒)",
    "subscriptionNotification": {
        "version": "1.0",
        "notificationType": 4,
        "purchaseToken": "支付令牌",
        "subscriptionId": "订阅的商品id"
    }}

googleNotify方法(处理谷歌订单流程这里,普通支付和订阅是一样的,普通支付时查询订单状态的api地址subscriptions需要替换为products):

public JSONObject googleNotify(int notificationType, String packageName, String subscriptionId, String purchaseToken, long eventTimeMillis, int appId) {
	JSONObject resultJson = null    try {
        if (notificationType > 0) {
            //获取查询令牌
            JSONObject refreshJson = new JSONObject();
			//grant_type固定为refresh_token
            refreshJson.put("grant_type", "refresh_token");
			//client_id、client_secret、refresh_token为创建时获取的固定内容,具体见《GooglePay订阅支付订单校验配置流程》
            refreshJson.put("client_id", '你的client_id');
            refreshJson.put("client_secret", '你的client_secret');
            refreshJson.put("refresh_token", '你的refreshToken');
            JSONObject refreshTokenJson = CHttpsUtil.postJsonData("https://accounts.google.com/o/oauth2/token", refreshJson.toJSONString());
            if (refreshTokenJson.getString("access_token") == null) {
                return null;
            }
            String googleAccessToken = refreshTokenJson.getString("access_token");
            if (googleAccessToken == null) {
                log.error("googleNotify googleAccessToken==null");
                break;
            }
            //查询谷歌订单状态
			//查询地址为:https://www.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{purchaseToken}?access_token={googleAccessToken}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append("https://www.googleapis.com/androidpublisher/v3/applications/")
							.append(packageName)
							//.append("/purchases/products/")
							.append("/purchases/subscriptions/")
							.append(subscriptionId).append("/tokens/")
							.append(purchaseToken)
							.append("?access_token=")
							.append(googleAccessToken);
			JSONObject resultJson = CHttpsUtil.getJsonData(stringBuilder.toString());
            if (resultJson == null) {
                log.error("googleNotify resultJson==null");
                break;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return resultJson;}