在调用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;
}
