官方接口

微信小程序码共有3个接口可以生成:

pagescene

具体的差异和参数可以通过链接查看官方文档

Golang实现

我根据自己的需要,选择了接口1的形式来实现,其他的接口只是接口url和参数的差异,整体流程和调用方式都是一样的。

获取ACCESS_TOKEN

func requestToken(appid, secret string) (string, error) {
	u, err := url.Parse("https://api.weixin.qq.com/cgi-bin/token")
	if err != nil {
		log.Fatal(err)
	}
	paras := &url.Values{}
	//设置请求参数
	paras.Set("appid", appid)
	paras.Set("secret", secret)
	paras.Set("grant_type", "client_credential")
	u.RawQuery = paras.Encode()
	resp, err := http.Get(u.String())
	//关闭资源
	if resp != nil && resp.Body != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		return "", errors.New("request token err :" + err.Error())
	}

	jMap := make(map[string]interface{})
	err = json.NewDecoder(resp.Body).Decode(&jMap)
	if err != nil {
		return "", errors.New("request token response json parse err :" + err.Error())
	}
	if jMap["errcode"] == nil || jMap["errcode"] == 0 {
		accessToken, _ := jMap["access_token"].(string)
		return accessToken, nil
	} else {
		//返回错误信息
		errcode := jMap["errcode"].(string)
		errmsg := jMap["errmsg"].(string)
		err = errors.New(errcode + ":" + errmsg)
		return "", err
	}
}
复制代码

获取小程序码

func GetQRCode(id string) ([]byte, error) {
	//上面生成的access code 判断为空时重新请求
	if appAccessTokenForClient == "" {
		accessToken, err := requestToken(appId, appSecret)
		if err != nil {
			return nil, err
		}
		appAccessTokenForClient = accessToken
	}
	strUrl := fmt.Sprintf("https://api.weixin.qq.com/wxa/getwxacode?access_token=%s", appAccessTokenForClient)

	parm := make(map[string]string)
	parm["path"] = fmt.Sprintf("pages/index/index?id=%s", id)
	jsonStr, err := json.Marshal(parm)
	if err != nil {
		return nil, errors.New("json Marshal QRCode paramter err :" + err.Error())
	}
	req, err := http.NewRequest("POST", strUrl, bytes.NewBuffer([]byte(jsonStr)))
	if err != nil {
		return nil, errors.New("get QRCode err :" + err.Error())
	}

	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, errors.New("get QRCode err :" + err.Error())
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, errors.New("get QRCode err :" + err.Error())
	}

	return body, nil
}
复制代码

常见问题

整个过程主要在调试时比较费时间,微信接口返回的错误信息比较范,记录下主要遇到的几种问题

40159

{\"errcode\":40159,\"errmsg\":\"invalid length for path, or the data is not json string hint: [Id2VBa0339xa11]\"}
path
pagepathpath

40169

errCode: 40169 errMsg: "openapi.wxacode.getUnlimited:fail invalid length for scene, or the data is not json string rid: 62764ad3-09f60c12-58046222"
scene