? 微信支付的支付接口更新了到了apiv3 ,主要难题还是在签名生成,只要这个解决,其他都不是问题,看了下签名生成的步骤,下面贴出详细的代码,封装调用方法:
<?php
/**
?*?微信公共配置方法
?*/
/*备注: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证书,要在后台申请,而不是以前的证书。
|