收藏
回答

接入虚拟支付接口,报sig_method must be hmac_sha256 ?

在调用pay_v2.getBalance接口时,出现签名错误,按照官方给的例子测试,签名算法是没有问题的,但是换成真实数据后就一直提示:"errcode":90018,"errmsg":"[sig_method] sig_method must be hmac_sha256// 导出云函数入口函数。各项参数都检查了,没有错。请问官方和各位大佬,这是怎么回事啊,完整代码如下:

exports.main = async (event, context) => {

    const session_key = await getSessionKey(event.code);

    console.log("session_key = " + session_key);

    if(!session_key) return {code:-1, error: "no session_key"};

    const access_token = await getAccessToken();

    console.log("access_token = " + access_token);

    if(!access_token) return {code:-2, error: "no access_token"};

    const balance = await getBalance(access_token, session_key);

    console.log("balance = " + balance);

    if(balance == -1) return {code:-3, error: "查询余额失败"};

};


async function getSessionKey(code) {

    try {

        // 调用微信 auth.code2Session 接口

        const response = await axios.get('https://api.weixin.qq.com/sns/jscode2session', {

            params: {

                appid: APPID,

                secret: APP_SECRET,

                js_code: code,

                grant_type: 'authorization_code'

            }

        });


        const data = response.data;


        if (data.session_key) {

            return data.session_key

        } else {

            console.error("getSessionKey fail: 没有值");

            return null;

        }

    } catch (error) {

        console.error("getSessionKey fail: " + error.message);

        return null;

    }

}


async function getAccessToken () {

    try {

        const response = await axios.get('https://api.weixin.qq.com/cgi-bin/token', {

            params: {

                grant_type: 'client_credential',

                appid: APPID,

                secret: APP_SECRET

            }

        });


        const data = response.data;


        if (data.access_token) {

            return data.access_token;

        } else {

            console.error("getAccessToken fail: 没有值");

            return null;

        }

    } catch (error) {

        console.error("getAccessToken fail:" + error.message);

        return null;

    }

};


async function getBalance(access_token, session_key) {

    const timestamp = Math.floor((new Date().getTime())/1000);

    const openid = cloud.getWXContext().OPENID;

    const body = {

        openid: openid,

        offer_id: OFFER_ID,

        ts: timestamp,

        zone_id: "1",

        env:1,

        user_ip:"192.168.124.6"

    }

    const bodyString = JSON.stringify(body);

    // 生成签名

    const signature = generateSignature(bodyString, session_key);

    // 生成支付签名

    const pay_sig = generatePaySignature("/wxa/game/getbalance", bodyString, PAY_SANBOX_APP_KEY);

    const config =  {

        headers: {

            'Content-Type': 'application/json',

        },

        timeout: 10000,

        params: {

            access_token,

            signature,

            sig_method: 'HMAC-SHA256',

            pay_sig

        }

    }

    console.log("getBalance config:" + JSON.stringify(config));

    

    try {

        const response = await axios.post(url_getbalance, body, config);


        const data = response.data;

        console.log("getBalance data:"+JSON.stringify(data));


        if (data.balance) {

            return data.balance;

        } else {

            console.error("getBalance fail: " + data.errmsg);

            return -1;

        }

    } catch (error) {

        console.error("getBalance fail:" + error.message);

        return -1;

    }

}


// 生成随机字符串函数

function generateNonceStr() {

    return Math.random().toString(36).substring(2, 18);

}


/**

 * 生成用户登录态签名(signature)

 * @param {string} postBody - HTTP POST 请求的数据包体(JSON 字符串)

 * @param {string} sessionKey - 当前用户有效的 session_key

 * @returns {string} - 用户登录态签名 signature

 */

function generateSignature(postBody, session_key) {

    const signature = crypto.createHmac('sha256', session_key).update(postBody).digest('hex');

    return signature;

}


/**

 * 生成支付请求签名(pay_sig)

 * @param {string} uri - 不带参数的 API 路径,例如:'/wxa/game/getbalance'

 * @param {string} postBody - HTTP POST 请求的数据包体(JSON 字符串)

 * @param {string} appKey - 当前支付环境对应的 AppKey

 * @returns {string} - 支付请求签名 pay_sig

 */

function generatePaySignature(uri, postBody, appKey) {

    const needSignMsg = uri + '&' + postBody;

    console.log("needSignMsg: " + needSignMsg);

    const paySig = crypto.createHmac('sha256', appKey).update(needSignMsg).digest('hex');

    console.log("paySig: " + paySig);

    return paySig;

}

回答关注问题邀请回答
收藏
登录 后发表内容