需要先准备三个参数:商户id 证书序列号 商户的私钥
商户id
证书序列号
商户的私钥
apiclient_key.pem (这个找不到了可以在后台重新获取一个新的,但是获取新的旧的就不能用了,所以线上如果有在用,就要把新的换上去,不然获取新的,线上还是旧的证书这样就会支付失败)
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDC5TmnJb0O1gnG
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PFkDEp/lCXGbHu+6x7mjeK649e89QK6ybr8+1u8BGEz6ZrV682Mb6MQa/lihv3DT
5wP72QrxR3QtTlCuiktUzHOWDGGunD4APgQ4QtT6yi65+Ez7A+ygIV/CFeaSX42q
Cg2ar4BXFaO5+BYSltyoBcPnXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END PRIVATE KEY-----
签名的流程:
1 获取签名参数(获取提交api的url 时间戳 随机字符串 接口需要的参数)
2.将签名的参数设置组装成为微信要求的格式
3.对数据进行加密
4.获得有一个签名。
下面举一个例子,如 查询申请单状态API 这个是GET请求,构建如下内容https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/business_code/2000002194274660
HTTP请求方法\n
URL\n
请求时间戳\n
请求随机串\n
请求报文主体\n
GET\n
/v3/applyment4sub/applyment/business_code/2000002194274660\n
1623329244\n
asdasdsaddd\n
\n
使用php做签名则如下,伪代码
<?php
$sign_content="GET\n";//请求方式 POST GET PUT DELETE等
$sign_content.="/v3/applyment4sub/applyment/business_code/2000002194274660\n";//这个是接口uri内容
$sign_content.="1623329244\n";//这个是时间戳
$sign_content.="asdasdsaddd\n"//这个是随机字符串
$sing_content.="\n"//这个为接口请求的参数
openssl_sign($sign_content, $raw_sign, '这个是商户的私钥' 'sha256WithRSAEncryption');
$sign = base64_encode($raw_sign);//这里就得到签名值了
//得到了签名值要怎么使用呢?
//先组装一下签名等信息的字符串先,到时候要发送请求的时候要用到
$sgin_str = 'mchid=商户id,nonce_str=随机字符串对应上面的,timestamp=时间戳对应上面的,serial_no=商户证书序列号,signature=刚刚得到的签名';
//这个是在请求头里面加进去,然后发起请求就完成了
//Authorization: WECHATPAY2-SHA256-RSA2048 mchid=商户id,nonce_str=随机字符串对应上面的,timestamp=时间戳对应上面的,serial_no=商户证书序列号,signature=刚刚得到的签名
实际可运行php代码 完整的一个流程 包括签名 发起查询的请求
<?php
function sign($url, $http_method, $timestamp, $nonce, $body, $mch_private_key, $mch_id, $serial_no)
{
$url_parts = parse_url($url);
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
$message =
$http_method . "\n" .
$canonical_url . "\n" .
$timestamp . "\n" .
$nonce . "\n" .
$body . "\n";
openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
$sign = base64_encode($raw_sign);
if (empty($sign)) return '';
$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $mch_id, $nonce, $timestamp, $serial_no, $sign);
return $token;
}
$mch_id = "1111";//商户id
$serial_no = "2222";//商户证书序列号
//这个是商户的私钥 可以本地文件
$mch_private_key =<<<EOF
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCbzikvBsorZKJh
ZpLZmcsFTXo2atWVX18ATiRT5k/qacPCSf5cAaVwfE4NghpEHYgGm56/dmkR7CDu
BEIqDmy4plj9lSwfsDJGh+jzbw==
-----END PRIVATE KEY-----
EOF;
//$mch_private_key = file_get_contents('/web/xcx_interface/Xcxpay/Certificate/Fws/apiclient_key.pem‘);//商户的私钥本地的文件//用本地文件证书也可以
$url = "https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/business_code/2000002194274660";
$sign = sign($url, 'GET', time(), md5(time()), '', $mch_private_key, $mch_id, $serial_no);//获取到了签名和其他内容
$header[] = 'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36';
$header[] = 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign;
$header[] = 'Content-Type: application/json';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSLVERSION, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$response_data = json_decode($response, true);
print_r($response_data);