评论

小程序服务商开发者,搭建一个mvp第三方平台必备的开发功能模块构成

平台提供的有很多接口,但不是每个接口我们都必须要用代码去实现。小程序第三方平台需要哪些必要功能模块呢?下面为大家分享小程序服务商开发者,搭建一个mvp第三方平台必备的开发功能模块构成,及部分关键代码。

我们在搭建小程序第三方平台过程发现官方提供的有很多接口,但不是每个接口都需要开发者用代码去实现。比如代码包管理的删除接口,就可以通过登录open.weixin.qq.com里,在列表看着更加详细的代码包版本介绍通过官方提供的界面就可以删除。即如果不是特殊需要,此接口可以不做开发。
那么我们搭建一个小程序服务商第三方平台需要哪些必要的功能模块呢?

必备功能模块概况

首先用一张图总概括下搭建一个mvp小程序服务商第三方平台必备的开发功能模块

第三方平台权限集

先用一张图表明第三方平台账号在授权后可用的权限集的部分。

只有平台先申请某一个权限,经过审核且全网发布后,旗下小程序才能在授权时选择某权限。有以下等 A>=B, B>=C;也就是第三方平台即使有每个微信提供的每个权限集,通过管理员授权后也不一定有全部权权限。原因:

1 单一授权被授权给其他第三方平台账号,或管理员授权时选择不把某一个权限授权给平台。比如开发和代码管理权限集
2 旗下小程序自身主体资质性质自带,不能拥有某个api权限。案例参考3
3 最终授权成功的权限集里,每个权限下都有多个api,所以在用某个api前需要看是由有权限。比如开发和代码管理权限集下,setwebviewdomain这个api不支持个人主体资质的appid调用
4 授权成功后,用token就可以用第三方平台提供的api代调用实现业务,或代调用小程序开发文档的api(标志参数需要access_token)里的接口,来实现产品开发。

授权及回调域名验证

####### 说明 #######
发起域名必须要在合法登记的域名名单内,且用户授权同意后的跳转url必须要在资料登记。体现在第三方平台创建时的以下两项配置中。
① 授权发起页域名
② 授权事件接收URL

授权回调URL源码
  public void ProcessRequest(HttpContext context)
  {

      Request = context.Request;
      Response = context.Response;

      string signature = Request.QueryString["signature"];
      string msg_signature = Request.QueryString["msg_signature"];
      string timestamp = Request.QueryString["timestamp"];
      string nonce = Request.QueryString["nonce"];


      #region Response body

      // 微信并不会因为返回失败就再发送一次消息,相反如果不返回success, 微信会延迟推送
      string ResMsg = "success";

      if (Request.HttpMethod == "POST")
      {
          using (Stream stream = Request.InputStream)
          {
              Byte[] postBytes = new Byte[stream.Length];
              stream.Read(postBytes, 0, (Int32)stream.Length);
              string postString = Encoding.UTF8.GetString(postBytes);

              if (postString.Contains("<AppId>"))
              {
                  XElement xdoc = XElement.Parse(postString);
                  CurAppID = xdoc.Element("AppId").Value.Trim();

                  LoadAppInfo(CurAppID);

                  string postStringXmlSrc = string.Empty;

                  Tencent.WXBizMsgCrypt wxcpt = new Tencent.WXBizMsgCrypt(CurAppToken, CurAppEncodingAESKey, CurAppID);
                  int ret = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, postString, ref postStringXmlSrc);

                  if (ret == 0)
                  {
                      xdoc = XElement.Parse(postStringXmlSrc);

                      if (xdoc != null)
                      {
                          string InfoType = xdoc.Element("InfoType").Value.Trim();
                          if (InfoType == "component_verify_ticket")
                          {
                              string componentVerifyTicket = xdoc.Element("ComponentVerifyTicket").Value.Trim();
                              WeixinDataHelper.UpdateComponentVerifyTicket(CurAppID, componentVerifyTicket);
                          }
                          else if (InfoType == "unauthorized")
                          {
                              string authorizedAppId = xdoc.Element("AuthorizerAppid").Value.Trim();
                              WeixinDataHelper.Unauthorized(CurAppID, authorizedAppId);
                          }
                          else
                          {
                              // 微信平台上填写的授权URL 目前就支持这两种 InfoType
                          }
                      }
                  }
              }
          }
      }
      else if (Request.HttpMethod == "GET")
      {
          ResMsg = Request.QueryString["echostr"];
      }

      ResponseEnd(ResMsg);

      #endregion
  }

各种票据有效性维护机制

1 授权后得到授权码(authorization_code )
需要用授权码去调用接口换取令牌,并保存。
2 获取令牌和刷新令牌
用授权码获得令牌authorizer_access_token和刷新令牌authorizer_refresh_token。  需要保存令牌和刷新令牌。
3 刷新令牌authorizer_access_token
用刷新令牌定期去微信网关拉取令牌,维持令牌的有效性,保证后期代实现接口时令牌有效性。约1h左右的时间去刷新一次令牌。刷新令牌服务需要有重试机制,因为瞬时网络原因会返回失败,需要重试。

消息与事件处理平台

1 第三方平台component_verify_ticke更新
平台审核通过后,每隔10分钟定时推送一次component_verify_ticket,开发者需要保存在数据库。再授权场景获取预授权码时需要用到这个有效的ticket。
2 授权状态变更(成功,变更,取消)
3 代码审核通知消息
4 注意:
① 这里的消息时加密的需要先解密。
② 有开发者反馈说不知道返回信息时旗下哪个appid,这里补充下,appid是再请求头的request参数里直接返回的。
③  消息与通知解密部分代码
  public void ProcessRequest(HttpContext context)
    {
        HttpRequest Request = context.Request;
        HttpResponse Response = context.Response;

        // 所属的已授权公众号的appid
        string AppID = Request.QueryString["AppID"];

        string reqSignature = Request.QueryString["signature"];
        string reqMsgSignature = Request.QueryString["msg_signature"];
        string reqTimestamp = Request.QueryString["timestamp"];
        string reqNonce = Request.QueryString["nonce"];

        if (string.IsNullOrEmpty(AppID) || !WeixinHelper.ValidateWeixinInterface(reqSignature, WeixinResources.ComponentAppToken, reqTimestamp, reqNonce))
        {
            ResponseEnd(Response, string.Empty,AppID);
            return;
        }

        if (AppID == WeixinResources.AutoTestAppID)
        {
            string _tmsg = new WeixinAutoTestHandler(Request, Response, WeixinResources.ComponentAppID).GetMsg();
            ResponseEnd(Response, _tmsg,AppID);
            return;
        }

        #region Response body

        string ResMsg = string.Empty;

        if (Request.HttpMethod == "POST")
        {
            using (Stream stream = Request.InputStream)
            {
                Byte[] postBytes = new Byte[stream.Length];
                stream.Read(postBytes, 0, (Int32)stream.Length);
                string postString = Encoding.UTF8.GetString(postBytes);

                string Msg = string.Empty;

                // 解密
                Tencent.WXBizMsgCrypt wxcpt = new Tencent.WXBizMsgCrypt(WeixinResources.ComponentAppToken, WeixinResources.ComponentAppEncodingAESKey, WeixinResources.ComponentAppID);
                int ret = 0;
                ret = wxcpt.DecryptMsg(reqMsgSignature, reqTimestamp, reqNonce, postString, ref Msg);
                if (ret != 0)
                {
                    ResponseEnd(Response, string.Empty,AppID);
                    return;
                }

                // 生成响应消息
                string resMsg = WeixinHelper.ReturnMessageAsThirdPlatform(AppID, Msg);

                // 加密消息
                string EncryptMsg = string.Empty;
                ret = wxcpt.EncryptMsg(resMsg, reqTimestamp, reqNonce, ref EncryptMsg);
                if (ret != 0)
                {
                    EncryptMsg = string.Empty;
                }

                ResMsg = EncryptMsg;
            }
        }
        else if (Request.HttpMethod == "GET")
        {
            ResMsg = Request.QueryString["echostr"];
        }

        ResponseEnd(Response, ResMsg,AppID);

        #endregion
    }
public static string ReturnMessageAsThirdPlatform(string AppID, string requestMsg)
       {
           string responseContent = string.Empty;

           XmlDocument xmlDoc = new XmlDocument();
           xmlDoc.LoadXml(requestMsg);

           XmlNode MsgType = xmlDoc.SelectSingleNode("/xml/MsgType");
           if (MsgType != null)
           {
               switch (MsgType.InnerText)
               {
                   case "event":
                       responseContent = EventHandleAsThirdPlatform(AppID, xmlDoc);  //事件处理
                       break;
                   case "text":
                   case "image":
                   case "voice":
                   case "video":
                   case "shortvideo":
                   case "location":
                       responseContent = TextHandleAsThirdPlatform(AppID, xmlDoc);  //消息处理
                       break;
                   default:
                       break;
               }
           }

           return responseContent;
       }

代小程序域名设置机制

1 小程序服务器域名

为授权小程序设置服务器域名
requestdomain request合法域名
wsrequestdomain socket合法域名
uploaddomain uploadFile合法域名
downloaddomain downloadFile合法域名

2 小程序业务域名

为授权小程序提供业务域名
web-view的合法域名
第三方平台先登记后,在给旗下小程序授权
旗下小程序可以使用配置域名的子域名作为业务域名

代小程序代码包管理机制

1 提交代码包

①ext.json的配置项更改体现在代码包配置json数据里。ext_json字段对应ext.json里的字段,这里template_id关联第三方平台》小程序模板管理里的模板ID。

② 那么要提交小程序的appid呢?还是通过ext_json字段来配置。ext_jsonjson字符串里的extAppid就是第三方平台账号旗下授权,本次要提交代码的小程序appid,通过上传代码时候的来指定extAppid就可以给一个小程序代提交代码。

2 提交审核
3 收到审核通知审核通过后提交上线
4 查询最近一次提交审核进度
5 回退到上一个版本

第三方代码模板管理

1 创建小程序账号,授权给平台账号,并绑定到第三方平台账号的开发小程序列表

2 用开发小程序appid创建项目的开发代码包模板

3 用开发小程序appid提交代码到草稿箱

4从草稿箱添加到模板库

最后一次编辑于  08-01  
点赞 8
收藏
评论

5 个评论

  • 仙森ღ₅₂₀¹³¹⁴
    仙森ღ₅₂₀¹³¹⁴
    07-31

    超赞

    07-31
    赞同 2
    回复 4
  • 小源杰
    小源杰
    10-16

    从问答过来,最近也在搞这个第三方平台,非常有用.

    10-16
    赞同
    回复 1
    • aholy.cium
      aholy.cium
      10-16
      对的。这个对于新手搭建第三方平台很有一定的帮助。我主页有个open开发者交流群,欢迎加入
      10-16
      回复
  • 沧浪淼客
    沧浪淼客
    08-26

    大佬,请教一下: 假设现在要给500家门店做同1个小程序,只是每家门店的信息不同,那该怎么办?

    看官方说企业主体也只能绑定50个小程序(即使能绑定500个,每次更新代码要登录500个账号,想想就头大)

    所以还是最好只申请1个小程序,然后给每个门店分发1个包含各自独立信息的二维码,这种方法可行吧?

    08-26
    赞同
    回复 3
    • aholy.cium
      aholy.cium
      08-26
      500个门店是一个主体下的吗?请问是什么行业,新零售还是全国范围餐饮零售行业
      08-26
      回复
    • 沧浪淼客
      沧浪淼客
      08-26回复aholy.cium
      额..是同一主体....公众号关联是不行的..有限制...我们应该用开放平台第三方小程序(刚看文档不熟悉,上面yy错误了)...
      08-26
      回复
    • aholy.cium
      aholy.cium
      08-26回复沧浪淼客

      根据我的经验理解,你家小程序不一定需要第三方平台。

      1第三方平台是给软件开发类服务商使用的;

      2 创建第三方平台为了多个类型账号关联产生UnionID

      不是多个门店就要多个小程序。一个小程序可以关联多个门店。


      08-26
      回复
  • 惠嘉伟-Javey
    惠嘉伟-Javey
    08-01

    wow厉害,感谢整理分享

    08-01
    赞同
    回复 1
    • aholy.cium
      aholy.cium
      08-01
      有错误的图,已更正和排版
      08-01
      回复
  • x_Qiang
    x_Qiang
    07-31

    有的markdown语法没显示

    07-31
    赞同
    回复 2
    • aholy.cium
      aholy.cium
      08-01
      谢提醒,明天再改一下,写成兼容模式的。
      08-01
      回复
    • x_Qiang
      x_Qiang
      08-01
      甭客气哈哈哈😂
      08-01
      回复