本人是写java的,奈何公司需要php所以我秉承着“我是公司一块砖,哪里需要哪里搬”的原则就当了一名实习php程序员,最近做了PHP 支付 但是为了保证是微信返回给我们不是“假数据”,在微信里面也有提示
所以就与要验证数据的有效性
因为在微信回调中会返回微信那边产生的订单号,所以就可以用这个查询,微信也有这个接口
然后返回参数很多我不一一截图了注意几个重要的参数就好了
好了 现在开始贴代码
/**
* 验证回调数据是否为假数据
* @param array $params 回调返回的数据(当然可以直接微信传入订单号)
* @return bool
*/
public function is_sign(array $params):bool
{
Log::info('生成XML---------------------------------------------------------');
$data = [
// 公众账号ID
'appid' => 'wx424714c0ce78fd3e',
// 商户号
'mch_id' => '1529275771',
// 微信订单号
'transaction_id' => $params['transaction_id'],
// 任意32位字符串
'nonce_str' => $this->getRandChar(32),
// 加密方式
'sign_type' => 'MD5'
];
// 签名
$data['sign']=$this->get_sign($data);
Log::info('生成XML-----------');
$_xml = $this->set_xmldata($data);
Log::info('发送请求----------------------------------------------------');
$res = $this->send_prePaycurl($_xml,"https://api.mch.weixin.qq.com/pay/orderquery");
Log::info('验证是否是假通知--------------------------', $res);
if ($res['return_code']=='SUCCESS' && $res['trade_state']=='SUCCESS'){
return true;
}else{
return false;
}
}
下面就是我在is_sign方法中调用的各类方法
/**
* 获取指定长度的随机字符串
* @param $length
* @return string|null
*/
function getRandChar($length)
{
$str = null;
$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
$max = strlen($strPol) - 1;
for ($i = 0; $i < $length; $i++) {
$str .= $strPol[rand(0, $max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
}
return $str;
}
/**
* 一次签名的函数
* @param $data
* @return string
*/
private function get_sign($data)
{
ksort($data);
$str = '';
foreach ($data as $key => $value) {
$str .= !$str ? $key . '=' . $value : '&' . $key . '=' . $value;
}
$str .= '&key=' . $this->api_key;
$sign = strtoupper(md5($str));
return $sign;
}
/**
* 生成xml格式的函数
* @param $data
* @return string
*/
private function set_xmldata($data)
{
$xmlData = "<xml>";
foreach ($data as $key => $value) {
$xmlData .= "<" . $key . "><![CDATA[" . $value . "]]></" . $key . ">";
}
$xmlData = $xmlData . "</xml>";
return $xmlData;
}
/**
* 通过curl发送数据给微信接口的函数
* @param $xmlData
* @return bool
*/
private function send_prePaycurl($xmlData,$_url)
{
$url =$_url;
$header[] = "Content-type: text/xml";
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $xmlData);
$data = curl_exec($curl);
if (curl_errno($curl)) {
print curl_error($curl);
}
if ($data) {
curl_close($curl);
return $this->_xmldataparse($data);
} else {
$error = curl_errno($curl);
echo "curl出错,错误码:$error" . "<br>";
echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
curl_close($curl);
return false;
}
}
/**
* xml数据解析函数
* @param $data
* @return array
*/
private function _xmldataparse($data)
{
$msg = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
return $msg;
}
到此微信回调后数据的有效性也就验证完成了,有更简单的方法请提出 ^_^