php&nodejs微信支付签名算法逻辑
参考微信的官方文档:点击打开链接
<?php
function main(){
$key = 'ffffffffffff'; //key为商户平台设置的密钥key
$nonce_str = rands(); //随机数
$apiparams=[
'appid'=>'45646fdsfdsfdsfdsfdsfs', //appid
'mch_id'=>'1231324564646', //商户号,以下三个字段根据接口的入参调整
'bill_date'=>'20200912',
'nonce_str'=>$nonce_str,
'bill_type'=>'ALL'
];
$apiparams['sign'] = getSign($apiparams,$key);
}
//随机数
function rands(){
$str = mt_rand(1000,9999);
return md5($str);
}
// 签名算法
function getSign($params,$key){
$params = array_filter($params, function ($k) { // 0和"0"不算空值
return $k !== '';
});
// 二级以上不参与签名,比如二维数组(这个看具体情况)
foreach($params as $key =>$val){
if( is_array($val)){
unset($params[$key]);
}
}
//升序
ksort($params);
//数组转成URL键值对并拼接商户key
$str=urldecode( http_build_query($params)."&key=".$key);
echo $str;
//MD5加密并转成大写
return strtoupper(md5($str));
}
NODEJS
// MD5加密
function md5(str) {
//npm install crypto
const crypto = require('crypto');
const md5 = crypto.createHash('md5');
md5.update(str);
return md5.digest('hex');
}
//签名
function getSign(args,key){
let keys = Object.keys(args); //object转array
keys = keys.sort(); // 参数名ASCII码从小到大排序(字典序)
let newArgs = {};
keys.forEach(function (key) {
if (args[key] != "" && args[key] != 'undefined' && Array.isArray(args[key]) ===false) { //如果参数的值为空不参与签名,或者二级以上;
newArgs[key] = args[key]; //参数名区分大小写;
}
})
// obj转成URL键值对
let str = ''
for (let k in newArgs) {
str += '&' + k + '=' + newArgs[k];
}
str = str.substr(1)+'&key='+key; //最后拼接key
return md5(str).toUpperCase(); //MD5转大写
}签名是否正确,在这里校验:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1