关于php 调用接口 微信云支付 HmacSha256 加密 request_content 生成 authen_code
程序员文章站
2022-04-11 17:47:42
...
关于php 调用接口 微信云支付 authen_code 生成 HmacSha256 加密 request_content
因为官方没有给php 的demo , php官方给出的代码
//Message 要加密的字符串内容 secret 加密的key
$s = hash_hmac('sha256', 'Message', 'secret', true);
echo base64_encode($s);
最开始我的代码
$data = [
"out_sub_mch_id"=>"sz011sUX5s7xxxxxxxxx",//商户门店xx
"order_type"=>1,
"start_time"=>1595211255,
"end_time"=>1600049655,
"nonce_str" => 'fewfdsafaaaafeefwf'.rand(10000,99999)
];
dump($data);
$mech_id = '151*****'; //你的商户号
# secret 我的**
$isdir = root_path().'extend/weixin/cert/'.$mech_id."/";
$filename = $isdir.'authcode.key';
$fh = fopen($filename, "r");
$str = fread($fh,filesize($filename));
$key = str_replace("\r\n","<br />",$str);//获取到我的**
$jsonstr = json_encode($data);
print_r($jsonstr);
$repos['request_content'] = $jsonstr;
$code = hash_hmac('sha256',$jsonstr,$key,true);
dump($code);
$code1 = base64_encode($code);
$urlcode1= urlencode($code);
dump($code1);
dump($urlcode1);
打印结果为
^ array:5 [▼
"out_sub_mch_id" => "sz011sUX5s7xxxxxxxxx"
"order_type" => 1
"start_time" => 1595211255
"end_time" => 1600049655
"nonce_str" => "fewfdsafaaaafeefwf78837"
]
{"out_sub_mch_id":"sz011sUX5s7xxxxxxxxx","order_type":1,"start_time":1595211255,"end_time":1600049655,"nonce_str":"fewfdsafaaaafeefwf78837"}
^ b"\x1A-õ;]-Z›ˆ£ù¶$•\x18\x03÷£æKz?lH,¯Œwzâ&"
^ "Gi31O10tWpuIo/m2JJUYrQP3o+ZLej9sSCyvjHd64iY="
^ "%1A-%F5%3B%5D-Z%9B%88%A3%F9%B6%24%95%18%AD%03%F7%A3%E6Kz%3FlH%2C%AF%8Cwz%E2%26"
ok ,乱码 ,一看这肯定不对的 ,身边又没有java,官方给了java的jdk,C的示例,我又用不了。
想出了办法,百度 在线加密,将字符串 key 复制进去 得出的结果
3218d546714f18888f5ff20063cdd0f66d40d34996cda264276d0f62ce1bf9bb
一看这个结果跟我的差了不知道多少,网上各种百度php sha256 加密的,试了个遍
public static function generateSHASign($signpl,$secert){
$signature = self::base64UrlEncode(hash_hmac('sha256',$signpl,$secert,true));
return $signature;
}
public static function base64UrlEncode($str){
return rtrim(strtr(base64_encode($str),'+/','-_'),'=');
}
public static function base64url_decode($data)
{
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
public static function base64url_encode($data)
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
没有效果 ,得出的结果都不是我们想要的,还好,至少不是乱码了,离结果不远了.
最后找到一个方法打印结果 ,奇迹发生了, 结果一样的
$code = bin2hex(hash_hmac('sha256',$str,$key,true))
微信云支付接口调用说明里面 authen_code 全部为大写
最后修改的方法为
public static function upper_bin2hex_hash_hmac($str,$key){
return strtoupper(bin2hex(hash_hmac('sha256',$str,$key,true)));
}
成功!
最后修改后的代码
$isdir = root_path().'extend/weixin/cert/'.$mech_id."/";
$filename = $isdir.'authcode.key';
$fh = fopen($filename, "r");
$str = fread($fh,filesize($filename));
$key = str_replace("\r\n","<br />",$str);
$jsonstr = json_encode($data);
$repos['request_content'] = $jsonstr;
$bin2hex1 =self::upper_bin2hex_hash_hmac($jsonstr,$key);
$auth_info = [
"a"=> [
"authen_type"=>1, "authen_code"=>$bin2hex1
]
];
$repos['authen_info'] = $auth_info;
$repos = json_encode($repos,true);
$url = 'https://pay.qcloud.com/cpay/query_order_list_overview';
$res = $this->http_post_json($url,$repos);
$res = json_decode($res->response_content);