第三方平台小程序开发遇到问题,当第三方平台调用商家授权小程序时,可以正常返回 :
这里:授权小程序APPID及平台APPID
{"authorizer_appid": "wx6a79d9e20634b4fb", componet_appid: "wxc24950555e542854"}
授权商家小程序ID: wx6a79d9e20634b4fb (这个小程序是通过快速创建企业小程序接口创建的,商家也已授权)
调用小程序详情接口:https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=" + component_access_token;
返回如下: API权限集ID:18 已经拿到。
{
"authorizer_info": {
"nick_name": "",
"service_type_info": {
"id": 0
},
"verify_type_info": {
"id": 0
},
"user_name": "gh_61f6bc98c7a7",
"alias": "",
"qrcode_url": "http://mmbiz.qpic.cn/mmbiz_jpg/GAUFLLdxPuNsnVPvMkZSzGWu8QGpHdkpJkFnvnl9TJzYibLic4bBM0dTJxPNWwdnPmRxnH4InG3JgUDvU0yfrTag/0",
"business_info": {
"open_pay": 1,
"open_shake": 0,
"open_scan": 0,
"open_card": 0,
"open_store": 0
},
"idc": 1,
"principal_name": "佛山市花梵花艺设计有限公司",
"signature": "",
"MiniProgramInfo": {
"network": {
"RequestDomain": [],
"WsRequestDomain": [],
"UploadDomain": [],
"DownloadDomain": [],
"BizDomain": [],
"UDPDomain": [],
"TCPDomain": [],
"PrefetchDNSDomain": [],
"NewRequestDomain": [],
"NewWsRequestDomain": [],
"NewUploadDomain": [],
"NewDownloadDomain": [],
"NewBizDomain": [],
"NewUDPDomain": [],
"NewTCPDomain": [],
"NewPrefetchDNSDomain": []
},
"categories": [],
"visit_status": 0
},
"register_type": 6,
"account_status": 1,
"basic_config": {
"is_phone_configured": false,
"is_email_configured": false
}
},
"authorization_info": {
"authorizer_appid": "wx6a79d9e20634b4fb",
"authorizer_refresh_token": "refreshtoken@@@DUewg9oNgD22AYF8hgS1Tv5UF4uVnpWHVkEeXjXsM-0",
"func_info": [
{
"funcscope_category": {
"id": 17
}
},
{
"funcscope_category": {
"id": 18
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 19
}
},
{
"funcscope_category": {
"id": 25
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 30
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 31
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 36
}
},
{
"funcscope_category": {
"id": 37
}
},
{
"funcscope_category": {
"id": 40
}
},
{
"funcscope_category": {
"id": 41
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 45
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 48
}
},
{
"funcscope_category": {
"id": 49
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 51
}
},
{
"funcscope_category": {
"id": 52
}
},
{
"funcscope_category": {
"id": 57
}
},
{
"funcscope_category": {
"id": 65
}
},
{
"funcscope_category": {
"id": 67
}
},
{
"funcscope_category": {
"id": 70
}
},
{
"funcscope_category": {
"id": 71
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 73
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 76
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 81
},
"confirm_info": {
"need_confirm": 0,
"already_confirm": 0,
"can_confirm": 0
}
},
{
"funcscope_category": {
"id": 84
}
},
{
"funcscope_category": {
"id": 85
}
},
{
"funcscope_category": {
"id": 86
}
},
{
"funcscope_category": {
"id": 88
}
},
{
"funcscope_category": {
"id": 93
}
},
{
"funcscope_category": {
"id": 99
}
},
{
"funcscope_category": {
"id": 102
}
},
{
"funcscope_category": {
"id": 104
}
},
{
"funcscope_category": {
"id": 105
}
},
{
"funcscope_category": {
"id": 112
}
}
]
}
}
接着,调用: https://api.weixin.qq.com/wxa/gettemplatedraftlist?access_token= 商家授权的appid ( authorizer_appid )
返回: 48001 api unauthorized
请帮我定位一下问题,谢谢!
微信: 13926003676
已经解决。 代商家获取小程序详情接口,在这分享一下:
@RequestMapping(value = {"/qurey/minin/info"}, method = RequestMethod.POST) public JSONObject queryMiniNameStatus(@RequestBody JSONObject body) { try { return wechatPlatformService.queryMiniInfo(body); } catch (Exception e) { log.error(StackTool.error(e, 100)); return new JSONObject().fluentPut("resCode", Constants.KEY_OP_FAIL).fluentPut("resMsg", e.getMessage()); } } /** * 查询小程序名称设置状态 * * @param body * @return * @throws Exception * */ public JSONObject queryMiniInfo(JSONObject body) throws Exception { String component_appid = body.getString("component_appid"); String authorizer_appid = body.getString("authorizer_appid"); PlatformGrant grant = getApiToken(component_appid, authorizer_appid); HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=utf-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_XML.toString()); restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); String url = "https://api.weixin.qq.com/cgi-bin/account/getaccountbasicinfo?access_token=" + grant.getAuthorizer_access_token(); body.remove("component_appid"); body.remove("authorizer_appid"); HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(body, headers); JSONObject res = restTemplate.postForObject(url, formEntity, JSONObject.class); log.info("---->小程序基本信息查询 res {}", res); Integer status = res.getInteger("errcode"); JSONObject head_image_info = res.getJSONObject("head_image_info"); if (head_image_info != null) { String head_image_url = head_image_info.getString("head_image_url"); if ( StringUtils.isEmpty(grant.getHead_image_url()) ) { grant.setHead_image_url(head_image_url); platformGrantRepository.save(grant); log.info("--->更新小程序的图像<---- {}",head_image_url); } } JSONObject result = new JSONObject(); if (status != null && status.intValue() == 0) { result.put("resCode", "0"); result.put("resMsg", "OK"); result.put("result", res); } else { result.put("resCode", Constants.KEY_OP_FAIL); result.put("resMsg", res.getString("errmsg")); } return result; }
其中,获取第三方授权的 access_token 放在缓存中,过期了才向微信获取,并且持久化到表 PlatformGrant 中。以下是源码参照:
/** * 获取/刷新接口调用令牌 * @param component_appid: 第三方平台appid * @param grant: * @return */ public PlatformGrant getApiToken(String component_appid, String authorizer_appid) throws Exception { String component_access_token = getComponentAccessToken(component_appid); PlatformGrant grant = getPlarformGrant(component_appid,authorizer_appid) ; if (grant == null) { throw new RuntimeException("平台未保存用户的授权信息"); } // 先不着急重新调用接口获取 if ( grant.getExpires_in() != null && grant.getUpdate_time() != null) { if (DateUtil.valid(grant.getUpdate_time(), grant.getExpires_in())){ // 没有过期 return grant; } } HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=utf-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); JSONObject reqBody = new JSONObject(); reqBody.put("component_access_token", component_access_token); reqBody.put("component_appid", component_appid); reqBody.put("authorizer_appid", authorizer_appid); reqBody.put("authorizer_refresh_token", grant.getAuthorizer_refresh_token()); HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(reqBody, headers); restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); String url = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token="+component_access_token; JSONObject json = restTemplate.postForObject(url, formEntity, JSONObject.class); log.info(">>>授权码获取授权信息 返回:{}",json); if ( json.getIntValue("errcode") != 0 ) { // {"errcode":61023,"errmsg":"refresh_token is invalid rid: 6228c03e-19027c0c-7a98021d"} if (json.getString("errmsg").indexOf("refresh_token is invalid") != -1) { //需要从数据库取 } } String authorizer_access_token = json.getString("authorizer_access_token"); String authorizer_refresh_token = json.getString("authorizer_refresh_token"); int expires_in = json.getIntValue("expires_in"); grant = new PlatformGrant(); grant.setComponent_appid(component_appid); grant.setAuthorizer_access_token(authorizer_access_token); grant.setAuthorizer_appid(authorizer_appid); grant.setAuthorizer_refresh_token(authorizer_refresh_token); grant.setExpires_in(expires_in); return savePlatformGrant(grant); }
先从缓存中获取商家授权acess_token,获取不到或过期了再实时查询
/** * 获取平台 component_access_token 有效期2h * @return */ public String getComponentAccessToken(String appId) { WechatToken token = null; String key= RedisTool.getComponentAccessTokenKey(appId); //先从缓存中取: try { token =( WechatToken)redisTemplate.opsForValue().get(key); if( null != token) { log.info("---成功获取ComponetAccessToken:{}",token.toString()); return token.getToken(); } }catch(Exception e) { log.warn("----->getComponentAccessToken异常<-----"); log.error(StackTool.error(e,100)); } log.info("--缓存中未获取到ComponetAccessToken 即时查询接口 ----" ); String url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; JSONObject reqBody = new JSONObject(); String appSecret = null; if (appId.equals(wXBizMsgCrypt.getAppId())) { appSecret = wXBizMsgCrypt.getAppSecret(); }else{ MuchApiWechat api = muchApiWechatRepository.findMuchApiWechat(appId); if (api == null) { throw new RuntimeException("平台没有配置第三方小程序"); // wxc24950555e542854 } appSecret = api.getAppsecret(); } reqBody.put("component_appid", appId); reqBody.put("component_appsecret", appSecret); String component_verify_ticket = getComponentVerifyTicket(appId); if (StringUtils.isEmpty(component_verify_ticket)) { throw new RuntimeException("component_verify_ticket为空,请联系平台技术人员"); } reqBody.put("component_verify_ticket", component_verify_ticket); HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=utf-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_XML.toString()); HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(reqBody, headers); restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); JSONObject result = restTemplate.postForObject(url, formEntity, JSONObject.class); log.info(">>>获取令牌返回: result="+result); // result={"errcode":61004,"errmsg":"access clientip is not registered requestIP: XX rid: 63a0f0bf-21116836-466eea46"} Integer errcode = result.getInteger("errcode") ; if (errcode != null && errcode.intValue() != 0) { throw new RuntimeException(result.getString("errmsg")); } String component_access_token = result.getString("component_access_token"); if (!StringUtils.isEmpty(component_access_token)) { Long now=System.currentTimeMillis()/1000; token = new WechatToken(now,component_access_token ); try{ redisTemplate.opsForValue().set(key, token , 7200, TimeUnit.SECONDS); }catch(Exception e){ log.warn("redis component_access_token 异常"); } } log.info("---->第三方平台 access_token:{}", component_access_token); return component_access_token; }
最后, 通过第三方平台来管理商家微信小程序,也可以由商家来自助管理。如:设置小程序图像、小程序介绍等信息。贴一张图片大家看看效果。微信的接口调用正确了还是非常稳定的。 之所以调用出错是没有使用商家的授权 authorizer_access_token