对接微信新版SDKv3版
签名生成规则,微信的官方文档里面说明的还算可以吧,不过个人觉得不太理想- -。 自己调试的时候调试了半天才找了错误原因。
https://wechatpay-api.gitbook.io/wechatpay-api-v3
微信v3接口更换了新版签名方式
商户需要使用自身的私钥对API URL、消息体等关键数据的组合进行SHA-256 with RSA签名。
请求的签名信息通过HTTP头
Authorization
传递,具体说明请见签名生成指南。 没有携带签名或者签名验证不通过的请求,都不会被执行,并返回
401 Unauthorized
。官方有给提供了类库和SDK
不过我这里项目没有用着composer, 使用官方提供的话 需要改动太大,所以这里就自己做了一个简单的封装, 所以不清楚官方提供的库具体如何。
//生成v3 Authorization protected function createAuthorization( $url ){ if (!in_array('sha256WithRSAEncryption', \openssl_get_md_methods(true))) { throw new \RuntimeException("当前PHP环境不支持SHA256withRSA"); } $url_parts = parse_url($url); $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : "")); //私钥地址 $mch_private_key = $this->mch_private_key; //商户号 $merchant_id = $this->mch_id; //当前时间戳 $timestamp = time(); //随机字符串 $nonce = $this->createNoncestr(); //POST请求时 $body = $this->body ; $message = "GET\n". $canonical_url."\n". $timestamp."\n". $nonce."\n". $body."\n"; //生成签名 openssl_sign($message, $raw_sign, openssl_get_privatekey(file_get_contents($mch_private_key)), 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); //Authorization 类型 $schema = 'WECHATPAY2-SHA256-RSA2048'; //生成token $token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"', $merchant_id,$this->serial_no, $nonce, $timestamp, $sign); $header = [ 'Content-Type:application/json', 'Accept:application/json', 'User-Agent:*/*', 'Authorization: '. $schema . ' ' . $token ]; return $header; }
/** * 作用:产生随机字符串,不长于32位 */ public function createNoncestr( $length = 32 ) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str =""; for ( $i = 0; $i < $length; $i++ ) { $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; }
注意:
我这里缺少代码直接获取商户序列号的方法,serial_no
可以自己查看官方文档或者 我这里是直接 获取的证书信息里面的序列号, 也可以通过 https://myssl.com/cert_decode.html 去查看证书的序列号。