PHP
PHP在微信支付API v3环境下请求接口
PHP在微信支付API v3环境下请求接口
今天接到一个需求,需要调用微信商家券接口,看了下文档,起初也是有点懵逼,因为代码示例或者SDK都很少,百度上也几乎没有,最终决定自己写。
大概看了下文档介绍,主要难题还是在签名生成,只要这个解决,其他都不是问题,看了下签名生成的步骤,跟之前自己写的上传图片到腾讯云COS上的过程有点类似,所以也参考了下,并根据文档的介绍,最终成功完成调用,下面贴出详细的代码,封装调用方法:
<?php /** * 微信公共配置方法 * Created by PhpStorm. * User: pc001 * Date: 2020/5/20 * Time: 14:20 */ /*备注:apiclient_cert.p12是商户证书文件,除PHP外的开发均使用此证书文件*/ #微信基础信息 $wxMerchantId = "商户号"; //商户号 $wxMerchantApiCertificate = __DIR__ . "/cert/apiclient_cert.pem"; //商户证书 $wxMerchantApiPrivateKey = __DIR__ . "/cert/apiclient_key.pem"; //商户私钥 $wxApiV3Key = "微信API v3密钥"; //微信API v3密钥 $wxApiSerialNo = "商户API证书序列号"; //商户API证书序列号 #############微信构造签名流程############# /** * 生成签名 * @param string $method 请求方法 POST 或者GET * @param string $url 请求URL * @param string $request 请求中的请求报文主体 * @param $wxMerchantId商户号 * @param $certKey商户私钥 * @param $wxApiSerialNo商户API证书序列号 * @return string */ function RequestSign($method = "POST", $url = "", $request = "", $wxMerchantId, $certKey, $wxApiSerialNo) { #截取获取当前请求地址【去除域名】 $url_parts = parse_url($url); $path = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : "")); #获取当前时间戳 $timeStamp = time(); #生成一个随机字符串 $nonceStr = getNonceStr(); #构造签名串 $requestSign = sprintf("%s\n%s\n%s\n%s\n%s\n", $method, $path, $timeStamp, $nonceStr, $request); #计算计算签名值 $sign = calculateSignatureValue($requestSign, $certKey); #设置HTTP头获取Authorization $token = createToken($wxMerchantId, $nonceStr, $timeStamp, $wxApiSerialNo, $sign); #返回 return $token; } /** * 计算签名值 * @param $requestSign * @param $certKey * @return string * 使用商户私钥对待签名串进行SHA256 with RSA签名,并对签名结果进行Base64编码得到签名值 */ function calculateSignatureValue($requestSign, $certKey) { $certKey = file_get_contents($certKey); openssl_sign($requestSign, $raw_sign, $certKey, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); return $sign; } /** * 获取token * @param $merchant_id * @param $nonce * @param $timestamp * @param $serial_no * @param $sign * @return string */ function createToken($merchant_id, $nonce, $timestamp, $serial_no, $sign) { $schema = 'WECHATPAY2-SHA256-RSA2048'; $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $merchant_id, $nonce, $timestamp, $serial_no, $sign); return $token; } /** * 产生随机字符串,不长于32位 * @param int $length * @return string */ function getNonceStr($length = 32) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } /** * post请求 * @param $url * @param $authorization * @return mixed */ function curlPostWithWx($url, $authorization) { $paramsString = json_encode($params); // 初始化curl $ch = curl_init(); // 设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_HEADER, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // post数据 curl_setopt($ch, CURLOPT_POST, 1); // post的变量 curl_setopt($ch, CURLOPT_POSTFIELDS, $paramsString); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen($paramsString), 'Authorization: ' . "WECHATPAY2-SHA256-RSA2048 " . $authorization, 'Accept: application/json', 'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36' ) ); // 运行curl,结果以jason形式返回 $res = curl_exec($ch); curl_close($ch); // 取出数据 $data = json_decode($res, true); return $data; } /** * get请求 * @param $url * @param $authorization * @return mixed */ function curlGetWithWx($url, $authorization) { // 初始化curl $ch = curl_init(); // 设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_HEADER, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen($paramsString), 'Authorization: ' . "WECHATPAY2-SHA256-RSA2048 " . $authorization, 'Accept: application/json', 'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36' ) ); // 运行curl,结果以jason形式返回 $res = curl_exec($ch); curl_close($ch); // 取出数据 $data = json_decode($res, true); //返回 return $data; }
下面我们调用的demo:
#引入文件 require __DIR__ . "/wxComm.php"; #请求接口地址 $url = "https://api.mch.weixin.qq.com/v3/certificates"; #组合基本信息 $params = array(); $request = json_encode($params); #获取authorization $authorization = RequestSign("GET", $url, "", $wxMerchantId, $wxMerchantApiPrivateKey, $wxApiSerialNo); #请求接口 $data = curlGetWithWx($url, $authorization); #输出 echo json_encode($data);
这样我们就成功的在微信支付API v3环境下请求接口,这里是在GET情况下调用接口,其实POST情况下也差不多,只是调用http请求时换了另一个方法,实现过程其实不难,主要是参考的东西太少。
这里要注意一点,这里的证书是指API证书,要在后台申请,而不是以前的证书,具体申请可以查看官方文档。
0条评论