0

0

关于微信开放平台那些事,第三方平台开发

coldplay.xixi

coldplay.xixi

发布时间:2020-09-15 16:34:15

|

4319人浏览过

|

来源于juejin

转载

关于微信开放平台那些事,第三方平台开发

关于微信开放平台那些事,第三方平台开发
关于微信开放平台那些事,第三方平台开发

假如说,有多个业务,功能模式相同的公众号/小程序,如果只是小程序开发,那是不是需要复制多套代码,改appid信息,在微信公众号后台,配置域名服务器以及密钥等繁琐的信息,每改一个提交发布一次,进行重复的步骤。随着要维护的公众号/小程序数量逐步增加,需要投入的资源以及成本也随之增加。

有没有想过,只需要开发一套公众号/小程序代码,以之为模板,再来一套后台管理系统,把在微信公众号后台做的那些事都搬到我们自己的系统中。来一个业务相同的小程序,只需要管理员授权后,只要在我们的系统中点点几个按钮,就可以把小程序发布上线,一次开发供 N 个公众号使用,提供标准化的接口服务来满足业务的基础需求。通过扫描二维码授权给平台,帮助 N 多个公众号代实现业务,不再需要理解繁琐参数设置,并且密码不提供给开发者,保证安全,真正做到解放运营同学和开发的双手,有更多的时间去谈女朋友,那该多好。没错,微信第三方平台开发就是来帮你节省更多时间去把妹的神器。

相关学习推荐:微信公众号开发教程

概述

微信公众平台-第三方平台(简称第三方平台)开放给所有通过开发者资质认证后的开发者使用。在得到公众号或小程序运营者(简称运营者)授权后,第三方平台开发者可以通过调用微信开放平台的接口能力,为公众号或小程序的运营者提供账号申请、小程序创建、技术开发、行业方案、活动营销、插件能力等全方位服务。同一个账号的运营者可以选择多家适合自己的第三方为其提供产品能力或委托运营。

从业务特征上来说,第三方平台必须如图所示:

关于微信开放平台那些事,第三方平台开发

从具体的业务场景上说,第三方平台包括以下场景:

提供行业解决方案,如针对电商行业的解决方案,或针对旅游行业的解决方案等;

行业:(横向)提供更加专业的运营能力,精细化运营用户公众号或小程序;

功能:(纵向)对公众平台功能的优化,如专门优化图文消息视觉样式和排版的工具,或专门定制的 CRM 用户管理功能,或功能强大的小程序插件等。

接入第三方开发的前提是要有微信开放平台应用,详细创建步骤请参考

developers.weixin.qq.com/doc/oplatfo…

关于微信开放平台那些事,第三方平台开发

1、获取验证票据

验证票据(component_verify_ticket),在第三方平台创建审核通过后,微信服务器会向其 ”授权事件接收URL” 每隔 10 分钟以 POST 的方式推送 component_verify_ticket

接收 POST 请求后,只需直接返回字符串 success。为了加强安全性,postdata 中的 xml 将使用服务申请时的加解密 key 来进行加密,在收到推送后需进行解密。

public void saveTicket(HttpServletRequest request, HttpServletResponse response) throws IOException {
  String msgSignature = request.getParameter("msg_signature");// 微信加密签名
  String timeStamp = request.getParameter("timestamp");// 时间戳    
  String nonce = request.getParameter("nonce"); // 随机数  
  BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(),"UTF-8"));
  StringBuffer sb = new StringBuffer();
  String line = null;
  while ((line = br.readLine()) != null) {
    sb = sb.append(line);
  }
  String postData = sb.toString();
  try {
    AuthorizedUtils.saveComponentVerifyTicket(msgSignature, timeStamp, nonce, postData);
  } catch (Exception e) {
    logger.error("系统异常", e);
  } finally {
    // 响应消息
    PrintWriter out = response.getWriter();
    out.print("success");
  }
}复制代码

2、获取令牌

令牌(component_access_token)是第三方平台接口的调用凭据。令牌的获取是有限制的,每个令牌的有效期为 2 小时,请自行做好令牌的管理,在令牌快过期时(比如1小时50分),重新调用接口获取。

public static ComponentToken getComponentToken(String ticket) {
    
RedisService redisService = RedisService.load();

ComponentToken componentToken = redisService.load(ComponentToken.COMPONENTTOKEN_ID, ComponentToken.class);  
if (componentToken == null) {
  String encryptAppId = ThirdPlat.PLAT_APPID;
  String appId = EnDecryptUtil.d3esDecode(encryptAppId);
  String encryptSecret = ThirdPlat.PLAT_SECRET;
  String secret = EnDecryptUtil.d3esDecode(encryptSecret);
      
  String requestUrl = AuthAccessUrl.COMPONENT_ACCESS_URL;
  Map map = new HashMap<>(); 
  map.put("component_appid", appId); //第三方平台appid
  map.put("component_appsecret", secret); //第三方平台appsecret
  map.put("component_verify_ticket", ticket); 
  String outputStr = JSONObject.toJSONString(map);
  logger.warn("请求数据"+outputStr);
  JSONObject jsonObject = HttpRequestUtils.httpRequest(requestUrl, "POST", outputStr);
    if (null != jsonObject) {
    long expires = System.currentTimeMillis() + 7200;
    try{
      expires = System.currentTimeMillis() + jsonObject.getIntValue("expires_in");        
    }catch (Exception e) {
    }
    try {
      componentToken = new ComponentToken();
      componentToken.setComponentAccessToken(jsonObject.getString("component_access_token"));
      componentToken.setExpiresIn(expires);
      redisService.save(componentToken, ComponentToken.class);
    } catch (Exception e) {
      componentToken = null;
      logger.error("系统异常", e);
    }
  }
} else {
  long sysTime = System.currentTimeMillis();
  if (sysTime >= componentToken.getExpiresIn()) {
    redisService.delete(ComponentToken.COMPONENTTOKEN_ID, ComponentToken.class);
    componentToken = getComponentToken(ticket);
  }else{
  }
}
return componentToken;
}复制代码
关于微信开放平台那些事,第三方平台开发

3、快速创建小程序

快速创建小程序接口优化了小程序注册认证的流程,能帮助第三方平台迅速拓展线下商户,拓展商户的服务范围,占领小程序线下商业先机。采用法人人脸识别方式替代小额打款等认证流程,极大的减轻了小程序主体、类目资质信息收集的人力成本。第三方平台只需收集法人姓名、法人微信、企业名称、企业代码信息这四个信息,便可以向企业法人下发一条模板消息来采集法人人脸信息,完成全部注册、认证流程。以及法人收到创建成功后的小程序APPID时,同时下发模板消息给法人,提示法人进行邮箱和密码的设置,便于后续法人登陆小程序控制台进行管理。

通过该接口创建小程序默认为“已认证”。为降低接入小程序的成本门槛,通过该接口创建的小程序无需交 300 元认证费。

关于微信开放平台那些事,第三方平台开发
关于微信开放平台那些事,第三方平台开发
public AjaxResult fastRegister(String merchantId) {
  Merchant merchant = merchantService.getById(merchantId);
  if (merchant == null) {
      logger.warn("快速创建小程序---->失败,merchant为null");
      return AjaxResult.error("快速创建小程序失败,merchant为null",null);
  } else {
      RedisService redisService = RedisService.load();
      ComponentVerifyTicket componentVerifyTicket = redisService.load(ComponentVerifyTicket.COMPONENT_VERIFY_TICKET_ID,
              ComponentVerifyTicket.class);
    if (componentVerifyTicket == null) {
        logger.warn("快速创建小程序---->失败,component_verify_ticket为null");
        return AjaxResult.error("快速创建小程序失败,component_verify_ticket为null",null);
    } else {
        ComponentToken componentToken = AuthorizedUtils.getComponentToken(componentVerifyTicket.getComponentVerifyTicket());
        RegisterWeappOut out = new RegisterWeappOut();
        out.setName(merchant.getName())
                .setCode(merchant.getCode())
                .setCode_type(merchant.getCodeType())
                .setLegal_persona_wechat(merchant.getLegalPersonaWechat())
                .setLegal_persona_name(merchant.getLegalPersonaName())
                .setComponent_phone(merchant.getComponentPhone());
        JSONObject obj = BaseUtils.createRegisterWeapp(componentToken,out);
        if (obj.getInteger("errcode") == 0 && "ok".equalsIgnoreCase(obj.getString("errmsg"))) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
        }
    }
}
} 
复制代码

4、获取预授权码

预授权码(pre_auth_code)是第三方平台方实现授权托管的必备信息,每个预授权码有效期为 10 分钟。需要先获取令牌才能调用。

public static String getPreAuthCode(String ticket) {
ComponentToken componentToken = getComponentToken(ticket);
String encryptAppId = ThirdPlat.PLAT_APPID;
String appId = EnDecryptUtil.d3esDecode(encryptAppId);
String url = AuthAccessUrl.PRE_AUTH_CODE_URL + componentToken.getComponentAccessToken();
Map map = new HashMap();
map.put("component_appid", appId);
    JSONObject jsonObject = HttpRequestUtils.httpRequest(url, "POST", JSONObject.toJSONString(map));   
return jsonObject.getString("pre_auth_code");
}复制代码

5、引导商户授权获取授权信息

第三方服务商构建授权链接放置自己的网站,用户点击后,弹出授权页面。

关于微信开放平台那些事,第三方平台开发
关于微信开放平台那些事,第三方平台开发
关于微信开放平台那些事,第三方平台开发
public AjaxResult getMchWebAuthUrl(@PathVariable("id") String id) {
RedisService redisService = RedisService.load();
ComponentVerifyTicket componentVerifyTicket = redisService.load(ComponentVerifyTicket.COMPONENT_VERIFY_TICKET_ID,
    ComponentVerifyTicket.class);
if(componentVerifyTicket == null){
  return AjaxResult.error("引入用户进入授权页失败,component_verify_ticket为null",null);
}else{
  String preAuthCode = AuthorizedUtils.getPreAuthCode(componentVerifyTicket.getComponentVerifyTicket());
  String encryptAppId = ThirdPlat.PLAT_APPID;
  String appId = EnDecryptUtil.d3esDecode(encryptAppId);
  String auth_type = ThirdPlat.AUTH_TYPE;
  String requestUrl = AuthAccessUrl.WEB_AUTH_URL;
  try {
    requestUrl = requestUrl.replace("COMPONENT_APPID", appId).replace("PRE_AUTH_CODE", preAuthCode)
        .replace("REDIRECT_URI", URLEncoder.encode(ThirdPlat.REDIRECT_URI.replace("MERCHANTID", id),"UTF-8")).replace("AUTH_TYPE", auth_type);
  } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
  }
  logger.warn("步骤2:引入用户进入授权页---->成功,url为:" + requestUrl);
  return AjaxResult.success("操作成功",requestUrl);
  
}
}复制代码

6、设置小程序基本信息

设置小程序名称,当名称没有命中关键词,则直接设置成功;当名称命中关键词,需提交证明材料,并需要审核。修改小程序的头像。修改功能介绍。修改小程序隐私设置,即修改是否可被搜索。

关于微信开放平台那些事,第三方平台开发
关于微信开放平台那些事,第三方平台开发
public AjaxResult setBasicInfo(BasicInfo basicInfo) throws IOException {
  Merchant merchant = merchantService.getById(basicInfo.getMerchantId());
  if (merchant == null) {
      logger.warn("设置基本信息---->失败,merchant为null");
      return AjaxResult.error("设置基本信息失败,merchant为null",null);
  } else {
      AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
      //修改头像
      if (StringUtils.isNotEmpty(basicInfo.getHeadImage())) {
          UploadIn uli = new UploadIn();
          uli.setType("image").setUrlPath(basicInfo.getHeadImage());
          JSONObject uploadJson = BaseUtils.upload(info,uli);
          String mediaId = uploadJson.getString("media_id");
          ModifyHeadImageIn mhi = new ModifyHeadImageIn();
          mhi.setHead_img_media_id(mediaId).setX1("0").setY1("0").setX2("1").setY2("1");
          JSONObject obj = BaseUtils.modifyHeadImage(info,mhi);
          if (!obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) || !ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
              return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE),obj.getString(ResStatus.ERRMSG));
          } else {
              merchant.setAppletsHeadImg(basicInfo.getHeadImage());
          }
      }
      //修改名称
      if (StringUtils.isNotEmpty(basicInfo.getNickname())) {
          UploadIn uli = new UploadIn();
          uli.setType("image").setUrlPath(merchant.getBusinessLicense());
          JSONObject uploadJson = BaseUtils.upload(info,uli);
          String mediaId = uploadJson.getString("media_id");
          SetNicknameIn sni = new SetNicknameIn();
          sni.setNick_name(basicInfo.getNickname());
          sni.setLicense(mediaId);
          JSONObject obj = BaseUtils.setNickname(info,sni);
          if (!obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) || !ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
              return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE),obj.getString(ResStatus.ERRMSG));
          } else {
              merchant.setAppletsName(basicInfo.getNickname());
              if (obj.containsKey("audit_id") && StringUtils.isNotEmpty(obj.getString("audit_id"))) {
                  merchant.setAuditId(obj.getString("audit_id"));
              }
          }
      }
      //修改功能介绍
      if (StringUtils.isNotEmpty(basicInfo.getSignature())) {
          ModifySignatureIn msi = new ModifySignatureIn();
          msi.setSignature(basicInfo.getSignature());
          JSONObject obj = BaseUtils.modifySignature(info, msi);
          if (!obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) || !ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
              return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE),obj.getString(ResStatus.ERRMSG));
          } else {
              merchant.setAppletsSignature(basicInfo.getSignature());
          }
      }
      //修改隐私设置,即修改是否可被搜索
      if (StringUtils.isNotEmpty(basicInfo.getStatus())) {
          SearchStatusIn ssi = new SearchStatusIn();
          ssi.setStatus(basicInfo.getStatus());
          JSONObject obj = BaseUtils.changeWxaSearchStatus(info, ssi);
          if (!obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) || !ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
              return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE),obj.getString(ResStatus.ERRMSG));
          } else {
              merchant.setSearchStatus(basicInfo.getStatus());
          }
      }
      merchantService.updateById(merchant);
      return AjaxResult.success();
  }
}复制代码

7、支付授权

即填写商户号和商户号密钥,以及上传p12证书

关于微信开放平台那些事,第三方平台开发

8、设置服务器域名

LHT蓝海豚团购导航
LHT蓝海豚团购导航

Lht蓝海豚(大维)团购导航系统是一套开源程序,采用PHP+MySql平台开发,具有强大的多规则API采集功能、精确化引导消费功能,卓越的负载能力和访问速度,全面支持第三方整合(微博、短信等)前台功能团购名站:显示分类下的所有团购网站,点击团购站,可直接进行查看、推荐、收藏精品商城:为网民推荐展示非团购网站的网上商城今日团购:显示各团购网站正在进行的团购团购排行:今日团购商品可按价格、行业、折扣、

下载

授权给第三方的小程序,其服务器域名只可以为第三方平台的服务器,当小程序通过第三方平台发布代码上线后,小程序原先自己配置的服务器域名将被删除,只保留第三方平台的域名,所以第三方平台在代替小程序发布代码之前,需要调用接口为小程序添加第三方平台自身的域名。

注意:

需要先将域名登记到第三方平台的小程序服务器域名中,才可以调用接口进行配置。

最多可以添加1000个合法服务器域名;其中,Request域名、Socket域名、Uploadfile域名、Download域名、Udp域名的设置数量均最大支持200个。

每月可提交修改申请50次。

关于微信开放平台那些事,第三方平台开发
关于微信开放平台那些事,第三方平台开发
public AjaxResult modifyDomain(ModifyDomain modifyDomain) {
  Merchant merchant = merchantService.getById(modifyDomain.getMerchantId());
  if (merchant == null) {
      logger.warn("设置服务器域名---->失败,merchant为null");
      return AjaxResult.error("设置服务器域名失败,merchant为null",null);
  } else {
      AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
      ModifyDomainOut out = new ModifyDomainOut();
      out.setAction(modifyDomain.getAction());
      String[] requests = modifyDomain.getRequestdomain().split(",");
      List requestList = Arrays.asList(requests);
      out.setRequestdomain(requestList);
      String[] wsrequests = modifyDomain.getWsrequestdomain().split(",");
      List wsrequestList = Arrays.asList(wsrequests);
      out.setWsrequestdomain(wsrequestList);
      String[] uploads = modifyDomain.getUploaddomain().split(",");
      List uploadList = Arrays.asList(uploads);
      out.setUploaddomain(uploadList);
      String[] downloads = modifyDomain.getDownloaddomain().split(",");
      List downloadsList = Arrays.asList(downloads);
      out.setDownloaddomain(downloadsList);
      JSONObject obj = BaseUtils.modifyDomain(info, out);
      if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
          return AjaxResult.success();
      } else {
          return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
      }
  }
}复制代码

9、设置业务域名

授权给第三方的小程序,其业务域名只可以为第三方平台的服务器,当小程序通过第三方发布代码上线后,小程序原先自己配置的业务域名将被删除,只保留第三方平台的域名,所以第三方平台在代替小程序发布代码之前,需要调用接口为小程序添加业务域名。

注意:

需要先将业务域名登记到第三方平台的小程序业务域名中,才可以调用接口进行配置。

为授权的小程序配置域名时支持配置子域名,例如第三方登记的业务域名如为 qq.com,则可以直接将 qq.com 及其子域名(如 xxx.qq.com)也配置到授权的小程序中。

最多可以添加100个业

关于微信开放平台那些事,第三方平台开发
关于微信开放平台那些事,第三方平台开发
public AjaxResult webviewDomain(WebviewDomain webviewDomain) {
  Merchant merchant = merchantService.getById(webviewDomain.getMerchantId());
  if (merchant == null) {
      logger.warn("设置业务域名---->失败,merchant为null");
      return AjaxResult.error("设置业务域名失败,merchant为null",null);
  } else {
      AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
      SetWebViewDomainOut out = new SetWebViewDomainOut();
      out.setAction(webviewDomain.getAction());
      String[] webviews = webviewDomain.getWebviewdomain().split(",");
      List webviewList = Arrays.asList(webviews);
      out.setWebviewdomain(webviewList);
      JSONObject obj = BaseUtils.setWebViewDomain(info, out);
      if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
          return AjaxResult.success();
      } else {
          return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
      }
  }
}复制代码

10、上传小程序代码

第三方平台需要先将草稿添加到代码模板库,或者从代码模板库中选取某个代码模板,得到对应的模板 id(template_id);然后调用本接口可以为已授权的小程序上传代码。

关于微信开放平台那些事,第三方平台开发
public AjaxResult commit(CommitModel model) {
  Merchant merchant = merchantService.selectMerchantById(model.getMerchantId());
  if (merchant == null) {
      logger.warn("上传代码---->失败,merchant为null");
      return AjaxResult.error("上传代码,merchant为null",null);
  }
  AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
  CommitIn commitIn = new CommitIn();
  String value = model.getValue();
  String[] items = value.split("_");
  String version = items[2];
  commitIn.setTemplate_id(items[0])
          .setUser_desc(items[1])
          .setUser_version(version);

  //第三方自定义的配置
  JSONObject obj = new JSONObject();
  obj.put("extAppid", merchant.getAppid());
  Map map = new HashMap<>();
  map.put("merchantId", model.getMerchantId());
  map.put("userVersion", commitIn.getUser_version());
  obj.put("ext", map);
  map = new HashMap<>();
  Map maps = new HashMap<>();
  maps.put("pages/index/index", map);
  obj.put("extPages", maps);
  commitIn.setExt_json(JSONObject.toJSONString(obj));
  //接受微信返回的数据
  obj = CodeUtils.commit(info, commitIn);
  if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
      AppletsRelease ar = appletsReleaseService.getOne(new LambdaQueryWrapper()
              .eq(AppletsRelease::getMerchantId,merchant.getId()));
      if(ar == null){
          ar = new AppletsRelease();
          ar.setMerchantId(model.getMerchantId()).setHistoryversion(version);
      } else{
          ar.setHistoryversion(version);
      }
      appletsReleaseService.saveOrUpdate(ar);
      return AjaxResult.success();
  } else {
      return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
  }
}复制代码
关于微信开放平台那些事,第三方平台开发

11、成员管理

第三方平台在帮助旗下授权的小程序提交代码审核之前,可先让小程序运营者体验,体验之前需要将运营者的个人微信号添加到该小程序的体验者名单中。

注意: 如果运营者同时也是该小程序的管理员,则无需绑定,管理员默认有体验权限。

关于微信开放平台那些事,第三方平台开发
/**
* 绑定体验者
* @parambindTester
* @return
*/
@Override
public AjaxResult bindTester(BindTester bindTester) {
  Merchant merchant = merchantService.getById(bindTester.getMerchantId());
  if (merchant == null) {
      logger.warn("绑定体验者---->失败,merchant为null");
      return AjaxResult.error("绑定体验者失败,merchant为null",null);
  } else {
      AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
      JSONObject obj = MemberUtils.bindTester(info, bindTester.getWechatId());
      if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
      AppletsTester at = new AppletsTester();
        at.setMerchantId(bindTester.getMerchantId()).setWechatId(bindTester.getWechatId()).setUserStr(obj.getString("userstr"));
        appletsTesterService.insertAppletsTester(at);
        return AjaxResult.success();
    } else {
        return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
    }
}
}

/**
* 解除体验者
* @paramtesterIds
* @return
*/
@Override
public AjaxResult unbindTester(Long[] testerIds) {
  for (Long id : testerIds) {
      AppletsTester tester = appletsTesterService.getById(id);
      if (tester == null) {
          logger.warn("解除体验者---->失败,tester为null");
          return AjaxResult.error("解除体验者,tester为null",null);
      }
      Merchant merchant = merchantService.getById(tester.getMerchantId());
      if (merchant == null) {
          logger.warn("解除体验者---->失败,merchant为null");
          return AjaxResult.error("解除体验者,merchant为null",null);
          }
        AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
        JSONObject obj = MemberUtils.unbindTester(info, tester.getWechatId());
        if("0".equals(obj.getString("errcode")) && "ok".equalsIgnoreCase(obj.getString("errmsg"))){
            appletsTesterService.removeById(id);
        } else {
            return AjaxResult.error(obj.getInteger("errcode"),obj.getString("errmsg"));
        }
    }
    return AjaxResult.success();
}复制代码

12、获取体验版二维码

关于微信开放平台那些事,第三方平台开发
public AjaxResult getQrcode(String merchantId) {
  Merchant merchant = merchantService.getById(merchantId);
  if (merchant == null) {
      logger.warn("获取体验二维码---->失败,merchant为null");
      return AjaxResult.error("获取体验二维码,merchant为null",null);
  }
  AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
  String qrcodeUrl =  CodeUtils.getQrcode(info, "pages/index/index");
  return AjaxResult.success("操作成功",qrcodeUrl);
}复制代码

13、提交审核

关于微信开放平台那些事,第三方平台开发
public AjaxResult submitAudit(SubmitAudit submit) {
  Merchant merchant = merchantService.getById(submit.getMerchantId());
  if (merchant == null) {
      logger.warn("获取体验二维码---->失败,merchant为null");
      return AjaxResult.error("获取体验二维码,merchant为null", null);
  }
  AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
  List categorys = submit.getCategory();
  submit.setFirst_id(categorys.get(0).split("-")[0])
          .setFirst_class(categorys.get(0).split("-")[1])
          .setSecond_id(categorys.get(1).split("-")[0])
          .setSecond_class(categorys.get(1).split("-")[1])
          .setTag(submit.getTag().replace(",", " "));
  List submits = new ArrayList<>();
  submits.add(submit);
  JSONObject sa = CodeUtils.submitAudit(info, submits);
  if (sa.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(sa.getString(ResStatus.ERRMSG))) {
      JSONObject obj = CodeUtils.getAuditStatus(info, sa.getString("auditid"));
      if (obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
          AppletsRelease ar = appletsReleaseService.getOne(new LambdaQueryWrapper()
                  .eq(AppletsRelease::getMerchantId,merchant.getId()));
          if (ar == null) {
              return AjaxResult.error("请先上传代码");
          }
          ar.setMerchantId(submit.getMerchantId())
                  .setAuditId(sa.getString("auditid"))
                  .setStatus(obj.getString("status"))
                  .setRemark(obj.getString("screenshot"));
          if (AppletsRelease.STATUS_0.equals(ar.getStatus())) {
              ar.setRemark(AppletsRelease.MSG_0);
          } else if (AppletsRelease.STATUS_1.equals(ar.getStatus())) {
              ar.setReason(obj.getString("reason"))
                      .setScreenshot(obj.getString("screenshot"))
                      .setRemark(AppletsRelease.MSG_1);
          } else if (AppletsRelease.STATUS_2.equals(ar.getStatus())) {
              ar.setRemark(AppletsRelease.MSG_2);
          } else if (AppletsRelease.STATUS_3.equals(ar.getStatus())) {
              ar.setRemark(AppletsRelease.MSG_3);
          } else if (AppletsRelease.STATUS_4.equals(ar.getStatus())) {
              ar.setRemark(AppletsRelease.MSG_4);
          }
          appletsReleaseService.updateById(ar);
          return AjaxResult.success();
      } else {
          return AjaxResult.error(obj.getInteger(ResStatus.ERRCODE), obj.getString(ResStatus.ERRMSG));
      }
  } else {
      return AjaxResult.error(sa.getInteger(ResStatus.ERRCODE), sa.getString(ResStatus.ERRMSG));
  }
}复制代码

14、审核撤回

注意: 单个帐号每天审核撤回次数最多不超过 1 次,一个月不超过 10 次。

关于微信开放平台那些事,第三方平台开发
public AjaxResult undoCodeAudit(String[] ids) {
  StringBuilder sb = new StringBuilder();
  for (String id : ids) {
      Merchant merchant = merchantService.getById(id);
      AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
      JSONObject obj = CodeUtils.undoCodeAudit(info);
      if (obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
          AppletsRelease ar = appletsReleaseService.getOne(new LambdaQueryWrapper()
                  .eq(AppletsRelease::getMerchantId,merchant.getId()));
          ar.setStatus(AppletsRelease.MSG_3);
          appletsReleaseService.updateById(ar);
      } else{
          sb.append(merchant.getName()+",");
      }
  }
  if (sb.length() == 0) {
      return AjaxResult.success();
  } else {
      String name = sb.substring(0, sb.length()-1);
      return AjaxResult.error(name+"审核撤回失败");
  }
}复制代码

15、发布已通过审核的小程序

关于微信开放平台那些事,第三方平台开发
public AjaxResult releaseApplets(String[] ids) {
  StringBuilder sb = new StringBuilder();
  for (String id : ids) {
      Merchant merchant = merchantService.getById(id);
      AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
      JSONObject obj = CodeUtils.release(info);
      if (obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG))) {
          AppletsRelease ar = appletsReleaseService.getOne(new LambdaQueryWrapper()
                  .eq(AppletsRelease::getMerchantId,merchant.getId()));
          ar.setStatus(AppletsRelease.STATUS_5);
          appletsReleaseService.updateById(ar);
      } else{
          sb.append(merchant.getName()+",");
      }
  }
  if (sb.length() == 0) {
      return AjaxResult.success();
  } else {
      String name = sb.substring(0, sb.length()-1);
      return AjaxResult.error(name+"发布失败");
  }
}复制代码

16、小程序版本回退

如果没有上一个线上版本,将无法回退

只能向上回退一个版本,即当前版本回退后,不能再调用版本回退接口。

关于微信开放平台那些事,第三方平台开发
public AjaxResult revertCodeRelease(String[] ids) {
  StringBuilder sb = new StringBuilder();
  for (String id : ids) {
      Merchant merchant = merchantService.getById(id);
      AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
      JSONObject obj = CodeUtils.revertCodeRelease(info);
      if (!(obj.getInteger(ResStatus.ERRCODE).equals(ResStatus.CODE) && ResStatus.MSG.equalsIgnoreCase(obj.getString(ResStatus.ERRMSG)))) {
          sb.append(merchant.getName()+",");
      }
  }
  if (sb.length() == 0) {
      return AjaxResult.success();
  } else {
      String name = sb.substring(0, sb.length()-1);
      return AjaxResult.error(null,name+"审核撤回失败");
  }
}复制代码

17、获取小程序码

关于微信开放平台那些事,第三方平台开发
public AjaxResult getMiniQrcode(@PathVariable("merchantId") String merchantId) {
  Merchant merchant = merchantService.getById(merchantId);
  if (merchant == null) {
      logger.warn("获取小程序码---->失败,merchant为null");
      return AjaxResult.error("获取小程序码,merchant为null",null);
  }
  String qrcode;
  if (StringUtils.isNotEmpty(merchant.getAppletImage())) {
      qrcode = merchant.getAppletImage();
  } else {
      AuthorizationInfo info = AuthorizedUtils.getAuthorizationInfo(merchant.getAppid());
      qrcode = WxUtils.getMiniQrcode(merchantId, "pages/index/index", "merchant", "miniQrcode", info.getAuthorizer_access_token());
      merchant.setAppletImage(qrcode);
      merchantService.updateById(merchant);
  }
  return AjaxResult.success("操作成功",qrcode);
}复制代码

相关学习推荐:微信小程序教程

相关文章

微信app下载
微信app下载

微信是一款手机通信软件,支持通过手机网络发送语音短信、视频、图片和文字。微信可以单聊及群聊,还能根据地理位置找到附近的人,带给大家全新的移动沟通体验,有需要的小伙伴快来保存下载体验吧!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

公务员递补名单公布时间 公务员递补要求
公务员递补名单公布时间 公务员递补要求

公务员递补名单公布时间不固定,通常在面试前,由招录单位(如国家知识产权局、海关等)发布,依据是原入围考生放弃资格,会按笔试成绩从高到低递补,递补考生需按公告要求限时确认并提交材料,及时参加面试/体检等后续环节。要求核心是按招录单位公告及时响应、提交材料(确认书、资格复审材料)并准时参加面试。

44

2026.01.15

公务员调剂条件 2026调剂公告时间
公务员调剂条件 2026调剂公告时间

(一)符合拟调剂职位所要求的资格条件。 (二)公共科目笔试成绩同时达到拟调剂职位和原报考职位的合格分数线,且考试类别相同。 拟调剂职位设置了专业科目笔试条件的,专业科目笔试成绩还须同时达到合格分数线,且考试类别相同。 (三)未进入原报考职位面试人员名单。

58

2026.01.15

国考成绩查询入口 国考分数公布时间2026
国考成绩查询入口 国考分数公布时间2026

笔试成绩查询入口已开通,考生可登录国家公务员局中央机关及其直属机构2026年度考试录用公务员专题网站http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/examResult/written_result.html,查询笔试成绩和合格分数线,点击“笔试成绩查询”按钮,凭借身份证及准考证进行查询。

11

2026.01.15

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

65

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

36

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

75

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

21

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

35

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
php-src源码分析探索
php-src源码分析探索

共6课时 | 0.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号