微信公众号迁移流程、openid转换接口

微信公众号暂不支持更换主体,进行操作一般需要迁移账号

转移流程图

注意点⚠️:

2023年11月24日起,新提交订单的迁移内容选择“全部关注用户”时,目标账号关注用户数必须小于等于1000,否则不支持发起迁移。
操作流程:
1.准备并提交审核
	审核(几个小时)--(中间可能需要接听审核电话)--审核通过---
2.操作确认迁移
	双方管理员微信上点确认迁移;微信自动通知用户迁移公告
3.操作迁移(无任何处理)
	账号A冻结24小时(这时账号A只能看迁移进度)---开始迁移(冻结24小时后才操作)---
4.迁移成功
	迁移成功(A账号被回收,B账号正常使用)

补充
2.1 如果需要转换用户openId,
	需要在确认迁移时,保存关注旧公众号用户openId
	在迁移成功后,调用用户openId转换接口进行处理

2.2 双方管理员可以在【微信】上点迁移确认了(两个号同一个管理员的话只要老号确认)
	
3.1常见功能以下4项不能迁移:如果想延用老号的设置内容,需要提前在新号设置一下
	【1】头像【2】介绍【3】自定义菜单【4】自动回复

3.2 冻结24小时后才开始迁移, 结束时间以具体的内容量为准(一般冻结后等2小时左右成功)。  
3.3 迁移完成后老号主管理员的手机微信上会收到一个【迁移完成】的通知

4.1 迁移成功之前,公众号使用者没有任何影响,菜单配置内容均可正常使用

迁移完成通知


转换用户openId 代码
public static void changeOpenId throws Exception {
    String tokenResult = getAccessToken();
    
    JSONObject wxAccessTokenObj = JSON.parseObject(tokenResult);
    String token = wxAccessTokenObj.getString("access_token");
    if (StringUtil.isBlank(token)) throw new RuntimeException("获取核心信息缺失");

    String path = "https://api.weixin.qq.com/cgi-bin/changeopenid?access_token=" + token;
	
	//需要转换的openId列表
    List<String> convertOpenIds = Arrays.asList(
            "a", "b", "c");

    int batchSize = 100;
    for (int i = 0; i < convertOpenIds.size(); i += batchSize) {
        int end = Math.min(i + batchSize, convertOpenIds.size());
        List<String> batchList = convertOpenIds.subList(i, end);

        JSONObject reqParam = new JSONObject();
        reqParam.put("from_appid", "wxa"); //此处为原账号的appid
        reqParam.put("openid_list", batchList);
      
        String result = sendPost(path, JSON.toJSONString(reqParam));
        log.info("result={}", result);
        if (StringUtil.isBlank(result)) throw new RuntimeException("获取新openId结果失败");
      
        JSONObject resultObj = JSON.parseObject(result);
        String errcode = resultObj.getString("errcode");
        if (!"0".equals(errcode)) throw new RuntimeException("获取新openId响应状态异常" + errcode+"["+resultObj.getString("errmsg")+"]");
      
        JSONArray resultList = resultObj.getJSONArray("result_list");
        if (ObjectUtils.isEmpty(resultList)) throw new RuntimeException("获取新openId响应列表异常");
        for (Object item : resultList) {
            JSONObject itemObj = JSON.parseObject(JSON.toJSONString(item));
            String new_openid = itemObj.getString("new_openid");
            if (StringUtil.isBlank(new_openid)) continue;
          	//对用户进行操作openId...
            System.out.println("new_openid=" + new_openid);
        }
    }
}
/**
 * 获取微信accessToken
 */
private static String getAccessToken() {
     StringBuffer accessTokenUrl = new StringBuffer();
     accessTokenUrl.append(WeChatProperties.wxAccessTokenPath)
             .append("?grant_type=client_credential")
             .append("&appid=")
             //新appId
             .append(WeChatProperties.appId)
             .append("&secret=")
             //新secret
             .append(WeChatProperties.secret);

     String url = accessTokenUrl.toString();
     log.info("getAccessToken url:{}", url);
     String tokenResult = null;
     try {
         tokenResult = sendGet(url, null, false);
     } catch (Exception e) {
         log.error("getAccessToken Exception ", e);
     }
     log.info("getAccessToken result:{}", tokenResult);
     return tokenResult;
}
/**
 * @param url 发送请求的URL
 * @param param
 * @param isJson 请求参数param是否为json格式
 */
public static String sendGet(String url, Map<String,Object> param,boolean isJson) throws IOException {
    log.debug("sendGet url={},param={}",url,param);
    String result = "";
    BufferedReader in = null;
    OutputStreamWriter writer = null;
    try {
        if(!isJson && param != null && param.size() > 0){
            StringBuffer sbuff = new StringBuffer(url);
            sbuff.append("?");
            Iterator<Map.Entry<String, Object>> iterator =
                    param.entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<String, Object> next = iterator.next();
                sbuff.append(next.getKey()).append("=").append(next.getValue().toString()).append("&");
            }
            url = sbuff.substring(0, sbuff.length() - 1);
        }
        log.debug("sendGet real url={}",url);
        URL realUrl = new URL(url);
        // 打开和URL之间的连接
        URLConnection connection = openConnection(realUrl);
        // 设置通用的请求属性
        connection.setRequestProperty("accept", "*/*");
        connection.setRequestProperty("connection", "Keep-Alive");
        connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        if(isJson && param != null && param.size() > 0){
            OutputStream outputStream = connection.getOutputStream();
            outputStream.write(JSONObject.toJSONString(param).getBytes());
        }
        //建立连接
        connection.connect();
        in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line;
        while ((line = in.readLine()) != null) {
            result += line;
        }
    } catch (IOException e) {
        log.error("发送GET请求出现异常!",e);
        e.printStackTrace();
        throw e;
    }
    // 使用finally块来关闭输入流
    finally {
        try {
            if (in != null) {
                in.close();
            }
            if (writer != null){
                writer.close();
            }
        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }
    return result;
}


public static String sendPost(String url, String param) throws IOException {
    log.info("sendPost url={},param={}",url,param);
    OutputStreamWriter out = null;
    BufferedReader in = null;
    String result = "";
    try {
        URL realUrl = new URL(url);
        // 打开和URL之间的连接
        HttpURLConnection conn = (HttpURLConnection) openConnection(realUrl);

        // 发送POST请求必须设置如下两行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestMethod("POST"); // POST方法

        // 设置通用的请求属性

        conn.setRequestProperty("accept", "*/*");
        conn.setRequestProperty("connection", "Keep-Alive");
        conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        conn.connect();
        // 获取URLConnection对象对应的输出流
        out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
        // 发送请求参数
        out.write(param);
        // flush输出流的缓冲
        out.flush();
        // 定义BufferedReader输入流来读取URL的响应
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            // 读取响应内容
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } else {
            log.error("发送 POST 请求失败,响应状态码: {}", responseCode);
            throw new IOException("HTTP request failed with status code: " + responseCode);
        }
    } catch (IOException e) {
        log.error("发送 POST 请求出现异常!",e);
        e.printStackTrace();
        throw e;
    }
    // 使用finally块来关闭输出流、输入流
    finally {
        try {
            if (out != null) {
                out.close();
            }
            if (in != null) {
                in.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    return result;
}

参考内容

官方地址:
https://kf.qq.com/faq/170112Q7vIfi1701122AVZvY.html
微信公众号H5获取用户的openid通常涉及到微信的JS-SDK,这是一个JavaScript库,允许公众号开发者在网页上集成微信功能,包括用户授权登录。以下是基本步骤: 1. **引入微信JS-SDK**:首先,在你的HTML页面中引入微信的JSSDK文件,一般是在`<head>`部分添加以下链接: ```html <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js" charset="utf-8"></script> ``` 2. **配置信息**:在窗口加载完成之后,通过`wx.config`函数设置AppID、timestamp、nonceStr、signature等参数。这通常在页面底部的`window.onload`或`$(document).ready`回调中完成。 ```javascript wx.config({ debug: false, // 开启调试模式,可以查看错误信息 appId: 'your_app_id', // 你的公众号AppID timestamp: 'time_from_server', // 时间戳 nonceStr: 'random_string', // 随机字符串 signature: 'signature_from_server', // 签名 jsApiList: ['checkJsApi'] // 需要使用的JSAPI列表,如需获取openid则需要包含getJsApi }); ``` 3. **调用接口**:调用`wx.checkJsApi`检查所需的JSAPI是否已经可用,然后使用`wx.getMenuInfo`或`wx.getUserInfo`来获取用户信息,其中`getUserInfo`可以返回openid。 ```javascript wx.ready(function () { wx.getUserInfo({ success: function (res) { var openid = res.userInfo.openid; // 使用openid做后续操作 }, fail: function (err) { // 处理获取失败的情况 } }); }); ``` 4. **处理权限弹窗**:如果用户尚未授权,会触发微信的授权弹窗,用户同意后才会获取到openid。 记住,上述代码示例中的`your_app_id`、`time_from_server`、`random_string`、`signature_from_server`都是需要从服务器端获取的真实值。并且在生产环境中,`debug`应设为`false`。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值