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