第三方应用开发 服务端API 开发指南 企业微信帐号ID安全性全面升级
企业微信帐号ID安全性全面升级

目录

  • 概述
  • 一、企业corpid的升级方案
  •       1.1 升级前后对比
  •       1.2 升级之后的接口变化
  •       1.3 历史已授权企业的方案
  •       1.4 corpid转换
  • 二、企业员工userid的升级方案
  •       2.1 升级前后对比
  •       2.2 升级之后的接口变化
  •       2.3 历史已授权企业的方案
  •       2.4 userid的转换
  • 三、企业员工external_userid的升级方案
  •       3.1 升级前后对比
  •       3.2 升级之后的接口变化
  •       3.3 历史已授权企业的方案
  •             企业管理员的授权
  •             同意授权转换external_userid事件
  •             转换external_userid
  •             转换客户群成员external_userid
  •             设置迁移完成
  • 四、企业客户微信unionid的升级方案
  •       4.1 升级之后的接口变化
  •       4.2 unionid查询external_userid
  • FAQ
  • 概述

    为更好地保护企业与用户的数据,企业微信对帐号相关的ID将做全面的升级,涉及的ID有corpid、userid、external_userid与unionid。基本的原则如下:

    1. 企业corpid
      第三方应用获取的corpid不再是明文的corpid,将升级为第三方服务商级别的加密corpid。同一服务商的所有应用获取的corpid一致;不同服务商获取的corpid不同。
    2. 企业员工userid
      第三方应用获取的userid不再是明文的userid,将升级为第三方服务商级别的加密userid。同一服务商的所有应用获取的userid一致;不同服务商获取的userid不同。
    3. 企业外部联系人external_userid
      第三方应用获取的企业外部联系人external_userid,将升级为第三方服务商与企业级别的加密external_userid,同一服务商的所有应用获取的external_userid一致;不同服务商获取的external_userid不同;同一外部联系人,在不同的授权企业下,同一服务商获取的external_userid不同。以上外部联系人包括微信与企业微信联系人。
    4. 企业客户微信unionid
      第三方应用在获取客户详情时,企业微信将不再返回企业客户的微信unionid。服务商需要在企业客户在微信中使用服务时,根据从微信开放平台获取的unionid与openid,调用企业微信提供的转换接口,查询出对应的微信用户external_userid。

    需要开发者重点关注的是,对于新授权的企业,返回的ID都为升级后的ID;对于历史授权的企业,每种ID的过渡兼容方案有所不同。
    新授权企业的定义如下:未授权过服务商的任一应用;曾经授权过,但全部取消授权之后再重新授权。(若当前已授权服务商的应用,再增加授权同一服务商的其他应用,则视为历史授权企业。)

    一、企业corpid的升级方案

    1.1 升级前后对比

    假设一个企业的明文corpid是CorpIdA,分别授权了服务商A与服务商B的两个应用,升级之前,所有应用能获取到的corpid均为CorpIdA,如下:

    升级之后,服务商A与服务商B名下应用可以获取到的corpid分别为CorpIdA1, CorpIdA2。自建应用仍保持为CorpIdA。

    1.2 升级之后的接口变化

    所有接口无论是入参,还是返回结果,涉及corpid的字段名皆不变;所有回调事件,涉及corpid的字段名皆不变。
    例如,获取企业永久授权码中,corpid字段在升级之后依然保持字段名为corpid。
    例如,获取企业凭证中,auth_corpid字段在升级之后依然保持字段名为auth_corpid。
    例如,变更授权通知中,AuthCorpId字段依然保持字段名AuthCorpId。
    例如,成员关注及取消关注事件中,ToUserName字段在升级之后依然保持字段名为ToUserName。
    在一些使用corpid作为url或小程序路径参数时,升级之后,参数名不变,仅需将参数值替换为升级后的ID。例如,微信进入居民上报小程序中,path参数中的strcorpid字段在升级之后依然保持字段名为strcorpid。

    【重要】从2021年11月17号开始,对于新授权的企业,将启用升级后的corpid。第三方应用理论上代码不需要做任何调整,即可兼容升级之后的corpid。

     

    1.3 历史已授权企业的方案

    对于历史已授权的企业,所有接口与回调返回的corpid仍然为明文corpid,暂无须整改。

    1.4 corpid转换

    将明文corpid转换为第三方应用获取的corpid
    请求方式:POST(HTTPS
    请求地址:https://qyapi.weixin.qq.com/cgi-bin/service/corpid_to_opencorpid?provider_access_token=ACCESS_TOKEN

    请求参数:

    {
      "corpid":"xxxxx"
    }

    参数说明:

    参数必须说明
    provider_access_token应用服务商的provider_access_token,获取方法参见服务商的凭证
    corpid待获取的企业ID

     

    权限说明:

    仅限第三方服务商,转换已获授权企业的corpid

    返回结果:

    
     "errcode":0,
     "errmsg":"ok",
     "open_corpid":"AAAAAA"
    

    参数说明:

    参数说明
    errcode返回码
    errmsg对返回码的文本描述内容
    open_corpid该服务商第三方应用下的企业ID

    二、企业员工userid的升级方案

    2.1 升级前后对比

    假设一个企业员工的明文userid是UserIdA,企业分别授权了服务商A与服务商B的两个应用,升级之前,所有应用能获取到的userid均为UserIdA,如下:

    升级之后,服务商A与服务商B名下应用可以获取到的userid分别为UserIdA1, UserIdA2。自建应用仍保持为UserIdA。

    2.2 升级之后的接口变化

    所有接口无论是入参,还是返回结果,涉及userid的字段名皆不变;所有回调事件,涉及userid的字段名皆不变。
    例如,获取部门成员中,userid字段在升级之后依然保持字段名为userid。
    例如,日历接口中,organizer字段在升级之后依然保持字段名为organizer。
    例如,成员通知事件中,UserID字段依然保持字段名UserID。
    例如,成员关注及取消关注事件中,FromUserName字段在升级之后依然保持字段名为FromUserName。
    在一些使用userid作为url或小程序路径参数时,升级之后,参数名不变,仅需将参数值替换为升级后的ID。例如,微信进入居民上报小程序中,path参数中的userid字段在升级之后依然保持字段名为userid。
    【注意】userid明文不区分大小写,而userid密文则大小写敏感,故使用userid的地方,不能再转为纯小写或纯大写。

    【重要】从2021年11月17号开始,对于新授权的企业,将启用升级后的userid。第三方应用理论上代码不需要做任何调整,即可兼容升级之后的userid。

     

    2.3 历史已授权企业的方案

    对于历史已授权的企业,所有接口与回调返回的userid仍然为明文userid,暂无须整改。

    2.4 userid的转换

    将自建应用获取的userid转换为第三方应用获取的userid

    请求方式:POST(HTTPS
    请求地址:https://qyapi.weixin.qq.com/cgi-bin/batch/userid_to_openuserid?access_token=ACCESS_TOKEN

    请求参数:

    {
      "userid_list":["aaa", "bbb"]
    }

    参数说明:

    参数必须说明
    access_token代开发自建应用或第三方应用的接口凭证
    userid_list获取到的成员ID列表,最多不超过1000个

     

    权限说明:

    仅代开发自建应用或第三方应用可调用
    成员需要在应用的可见范围内

    返回结果:

    {
        "errcode": 0,
        "errmsg": "",
        "open_userid_list": [
            {
                "userid": "aaa",
                "open_userid": "sdflajsldjflad",
            }
        ],
        "invalid_userid_list":["bbb"]
    }

    参数说明:

    参数说明
    errcode返回码
    errmsg对返回码的文本描述内容
    open_userid_list该服务商第三方应用下的成员ID
    open_userid_list.userid转换成功的userid
    open_userid_list.open_userid转换成功的userid对应的该服务商应用下的成员ID

     

    三、企业员工external_userid的升级方案

    3.1 升级前后对比

    假设一个用户同时属于三家企业的客户,这三家企业分别授权了服务商A与服务商B的应用,升级之前,同一个服务商获取到同一个用户的external_userid一致,不同服务商不一致,具体如下:

    升级之后,属于不同企业的同一个客户,同一服务商获取到的external_userid不一致,
    不同服务商获取的external_userid也不一致,具体如下:

    3.2 升级之后的接口变化

    所有接口无论是入参,还是返回结果,涉及external_userid的字段名皆不变;所有回调事件,涉及external_userid的字段名皆不变。
    例如,获取客户详情中,external_userid字段在升级之后依然保持字段名为external_userid。
    例如,企业客户事件中,ExternalUserID字段依然保持字段名ExternalUserID。

    【重要】从2021年11月17号开始,对于新授权的企业,将启用升级后的external_userid。第三方应用理论上代码不需要做任何调整,即可兼容升级之后的external_userid。

     

    3.3 历史已授权企业的方案

    【重要】对于历史已授权的企业,在2022年3月1号之前,所有接口与回调返回的external_userid仍然为旧的external_userid,从2022年3月1号0点开始逐步升级历史授权的企业,升级的企业对应的所有输入与返回的external_userid字段,将启用升级后的external_userid。所以服务商需要在此之前完成历史数据的迁移整改。由于涉及历史数据的迁移,需要企业管理员重新授权,具体流程如下:

    1. 2022年3月1号之前属于过渡期,仍然可使用旧的external_userid。
    2. 企业用户在进入第三方应用页面时,企业微信会弹出授权确认页。
    3. 如果企业管理员同意授权,企业微信会回调“同意授权转换external_userid事件”给服务商。
    4. 服务商可以为该企业开启迁移流程,调用“转换external_userid”把历史external_userid转换为新external_userid。
    5. 迁移完成后调用“设置迁移完成”将该企业设置状态为迁移成功。
    6. 设置后企业微信所有接口与回调将为该企业启用新的external_userid。

    企业管理员的授权

    同意授权转换external_userid事件

    推送到服务商设置的接收事件回调url上(应用管理-通用开发参数-系统事件接收URL)
    请求方式:POST(HTTPS
    请求地址:https://127.0.0.1/service/receive?msg_signature=3a7b08bb8e6dbce3c9671d6fdb69d15066227608&timestamp=1403610513&nonce=380320359

    请求包体:
    xml请求示例:

    <xml>
    	<AuthCorpId><![CDATA[xxxx]]></AuthCorpId>
    	<InfoType><![CDATA[agree_external_userid_migration]]></InfoType>
    	<ServiceCorpId><![CDATA[xxxx]]></ServiceCorpId>
    	<TimeStamp>1403610513</TimeStamp>
    </xml>

    json请求示例:

    {
    	"AuthCorpId": "xxxx",
    	"InfoType": "agree_external_userid_migration",
    	"ServiceCorpId": "xxxx",
    	"TimeStamp": 1403610513
    }
    服务商的响应必须在1000ms内完成

    参数说明:

    参数说明
    AuthCorpId同意授权的企业ID
    InfoTypeagree_external_userid_migration
    ServiceCorpId服务商企业ID
    TimeStamp时间戳

    转换external_userid

    请求方式:POST(HTTPS
    请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_new_external_userid?access_token=ACCESS_TOKEN

    请求参数:

    {
      "external_userid_list":["xxxxx","yyyyyy"]
    }

    参数说明:

    参数必须说明
    access_token调用接口凭证。服务商可通过“获取企业access_token”获得此调用凭证
    external_userid_list旧外部联系人id列表,建议200个,最多不超过1000个

    权限说明:

    该企业授权了该服务商第三方应用
    客户联系和家校场景中,external_userid对应的跟进人需要在应用可见范围内
    微信客服场景中,仅支持48小时内客服会话的external_userid

    返回结果:

    
     "errcode":0,
     "errmsg":"ok",
     "items":[
     	{
     		"external_userid":"xxxxx",
     		"new_external_userid":"AAAA"
     	},
     	{
     		"external_userid":"yyyyy",
     		"new_external_userid":"BBBB"
     	}
     ]
    
    如果传入了新的external_userid,则原样返回。

    参数说明:

    参数说明
    errcode返回码
    errmsg对返回码的文本描述内容
    new_external_userid新外部联系人id

    转换客户群成员external_userid

    转换external_userid接口不支持客户群的场景,如果需要转换客户群中无好友关系的群成员external_userid,需要调用本接口,调用时需要传入客户群的chat_id

    请求方式:POST(HTTPS
    请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get_new_external_userid?access_token=ACCESS_TOKEN

    请求参数:

    {
      "chat_id":"wrOgQhDgAAMYQiS5ol9G7gK9JVAAAA",
      "external_userid_list":["xxxxx","yyyyyy"]
    }

    参数说明:

    参数必须说明
    access_token调用接口凭证。服务商可通过“获取企业access_token”获得此调用凭证
    chat_id客户群ID
    external_userid_list旧外部联系人id列表,最多不超过1000个

    权限说明:

    该企业授权了该服务商第三方应用
    客户群的群主需要在应用可见范围内

    返回结果:

    
     "errcode":0,
     "errmsg":"ok",
     "items":[
     	{
     		"external_userid":"xxxxx",
     		"new_external_userid":"AAAA"
     	},
     	{
     		"external_userid":"yyyyy",
     		"new_external_userid":"BBBB"
     	}
     ]
    
    如果传入了新的external_userid,则原样返回。

    参数说明:

    参数说明
    errcode返回码
    errmsg对返回码的文本描述内容
    new_external_userid新外部联系人id

    设置迁移完成

    企业授权确认之后,且服务商完成了新旧external_userid的迁移,即可主动将该企业设置为“迁移完成”,设置之后,从该企业获取到的将是新的external_userid。注意,该接口需要使用provider_access_token来调用,对于有多个应用的服务商,可逐个应用进行external_userid的转换,最后再使用provider_access_token调用该接口完成设置。设置迁移完成之后,就不能为该企业再调用转换external_userid接口了。

    当该企业同时是服务商, 并对自己授权的情况,无需调用本接口。自授权应用不在此次回收范围之内。

    请求方式:POST(HTTPS
    请求地址:https://qyapi.weixin.qq.com/cgi-bin/service/externalcontact/finish_external_userid_migration?provider_access_token=ACCESS_TOKEN

    请求参数:

    {
      "corpid":"xxxxx"
    }

    参数说明:

    参数必须说明
    provider_access_token应用提供商的provider_access_token,获取方法参见服务商的凭证
    corpid企业corpid

     

    权限说明:

    该企业授权了该服务商第三方应用

    返回结果:

    
     "errcode":0,
     "errmsg":"ok"
    

    参数说明:

    参数说明
    errcode返回码
    errmsg对返回码的文本描述内容

     

    四、企业客户微信unionid的升级方案

    为了更好的保护微信用户的隐私,企业微信接口将不再返回企业客户的微信unionid。服务商需要在企业客户在微信中使用服务时,根据从微信开放平台获取的unionid与openid,调用企业微信提供的转换接口,查询出对应的微信用户external_userid。

    4.1 升级之后的接口变化

    从2021年11月17号开始新授权的企业,以下接口将不再返回unionid。从2022年3月1号0点开始逐步升级历史授权的企业,升级后的企业将不再返回unionid。如果为历史授权企业调用接口设置迁移完成,该企业也将不再返回unionid。

    4.2 unionid查询external_userid

    当微信用户在微信中使用第三方应用的小程序或公众号时,第三方可将获取到的unionid与openid,调用此接口转换为企业客户或学生家长的external_userid。该接口调用频次有限,每个服务商每小时仅可调用2万次,每天仅可调用24万次,应由用户的主动行为来触发查询,严禁批量进行ID转换,如有发现违规行为,将封禁服务商的接口调用权限。同时建议服务商的小程序路径或公众号页面链接带上corpid参数,如此可明确地转换出该企业对应的external_userid,以获得更好的性能。

    请求方式:POST(HTTPS
    请求地址:https://qyapi.weixin.qq.com/cgi-bin/service/externalcontact/unionid_to_external_userid_3rd?suite_access_token=ACCESS_TOKEN

    请求参数:

    {
      "unionid":"xxxxx",
      "openid":"xxxxx",
      "corpid":"xxxxx", //建议尽可能传入corpid参数,可获得更好的性能
    }

    参数说明:

    参数必须说明
    suite_access_token第三方应用access_token
    unionid微信用户的unionid
    openid微信用户的openid
    corpid需要换取的企业corpid,不填则拉取所有企业

     

    权限说明:

    1. 该企业授权了该服务商第三方应用
    2. 调用频率最大为2万次/小时,24万次/天
    3. unionid和openid的主体需与服务商的主体一致
    4. openid与unionid必须是在同一个小程序或同一个公众号获取到的
    5. 相应外部成员跟进人在应用可见范围内 或 相应外部成员所属外联群群主在应用可见范围内。
    6. 当微信用户为家长时,仅返回应用的可见范围内的家长。
    7. 外联群场景中,本接口corpid为必填项。
    8. 微信客服场景中,仅返回48小时内客服会话的external_userid。

    返回结果:

    
     "errcode":0,
     "errmsg":"ok",
     "external_userid_info":[
     		{
    			"corpid":"AAAAA", 
    			"external_userid":"BBBB"
    		}, 
    		{
    			"corpid":"CCCCC", 
    			"external_userid":"DDDDD"
    		}
    	]
    

    参数说明:

    参数说明
    errcode返回码
    errmsg对返回码的文本描述内容
    external_userid_info该unionid对应的外部联系人信息
    external_userid_info.corpid所属企业id
    external_userid_info.external_userid外部联系人id

     

    FAQ

    1. 当前企业已经安装了服务商的应用,再安装同一服务商的另一个应用,属于新授权还是历史授权呢?
      答:属于历史授权,只有当前企业未安装该服务商的任何应用,才属于新的授权。
    2. 修改应用的可见范围,属于新授权还是历史授权?
      答:属于历史授权。
    3. 企业将服务商的所有应用都取消授权了,再重新授权,这时属于新授权还是历史授权?
      答:属于新授权。
    4. 帐号ID升级是否对自建代开发应用生效,对自建代开发应用是否有影响?
      答:帐号ID升级对自建代开发应用不生效。若服务商对于企业同时提供了自建代开发应用和第三方应用,企业微信提供了userid转换接口,服务商可调用接口将企业主体的userid转换为服务商主体的userid,详见代开发应用与第三方应用的兼容
    5. 之前部分通讯录接口已经有返回open_userid字段,这个与userid是什么关系?
      答:如果是新授权的企业,密文userid就与原来的open_userid一致。
    6. 仅提供标准的saas应用,还需要做适配工作吗?
      答:对于非客户联系、微信客服或通讯录应用的其他标准saas应用,也没有提供代开发应用的业务,理论上无须做任何适配工作。如果所服务的企业有遇到使用问题,欢迎向我们反馈,我们将一起探讨合理的解决方案。
    7. 家校沟通中的家长external_userid也需要升级吗?
      答:也需要。上文中提到的external_userid转换接口、unionid查询external_userid都适用于家校沟通场景。
    8. 如果管理员没有授权,能够调用调用“转换external_userid”接口把历史external_userid转换为新external_userid吗?
      答:不能,只有管理员授权了,才能调用“转换external_userid”接口
    9. 如果“同意授权转换external_userid事件”回调失败了,会影响“转换external_userid”接口的调用吗?
      答:不影响,回调事件仅是为了提高实时性。
    10. 怎么判断一个企业的管理员是否已经授权“同意授权转换external_userid事件”?
      答:企业管理员同意授权时,企业微信会回调事件给服务商,如果服务商没有成功接收到该事件,可以直接调用“转换external_userid”接口,若能成功转换,则代表企业已经授权,否则代表企业仍未授权。
    11. 从2022年3月1号之后,还能调用“unionid查询external_userid”吗?
      答:仍能调用。
    12. 客户群中部分群成员不是企业的客户(与企业服务人员没有好友关系),可以从旧的external_userid转换为新的external_userid吗?
      答:支持,调用转换客户群成员external_userid接口可以进行转换。
    上一篇
    回调配置
    下一篇
    企业授权应用