Dai Chong's blog

最近在做一个充值功能,因为是微网站并且是在微信公众号内,所以选择了微信公众号支付。做过微信支付的小伙伴都知道微信支付的模式分为三种:

第一种:普通商户

第二种:服务商

第三种:银行服务

三种支付模式有很明显的不同,第一种就是最常见的普通微信公众号支付,支付需要微信公众号的appid appkey mc_id mc_key 四个支付参数。而这四个参数都是属于单独的微信支
付参数。

第二种是服务商模式,首先要有一个服务商的支付平台,然后通过这个服务商支付平台申请子商户平台。那么支付的时候同样的四个支付参数就要从服务商和子商户获得了,并不是
单独的一个公众号里的参数。具体大家可以看微信的文档。

第三种暂时没做过。

周所众知微信支付异步回调验证订单真实性是非常重要的,如果不做验证,在有人知道你的微信支付回调地址后就能直接请求你的支付回调地址,模仿微信支付回调达到不支付
金额就能充值、购买商品等操作!所以验证订单的真实性是每个程序员必须要做的!

那么具体的验证步骤有哪些呢?

第一步:接收微信返回的参数。
第二步:处理参数。
第三步:使用ksort排序参数,ASCII码从小到大排序.
第四步:在参数后面连接上(商户秘钥设置路径:微信商户平台(pay.weixin.qq.com)–>账户设置–>API安全–>密钥设置)。
第五步:加密生成签名。
第六步:对比加密后的签名。

具体的步骤可以在微信支付开发文档中查看详细的签名生成和对比的步骤!

下面就是我根据微信文档写的代码:

[生成签名及对比] []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$postobj = $GLOBALS['HTTP_RAW_POST_DATA'];//第一种方式
$postobj = file_get_contents("php://input");//第二种方式
$postObj = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);//转化xml数据为数组
$result_code = $postObj['result_code'];//微信返回的参数
if($result_code=="SUCCESS"){//参数值为SUCCESS时说明支付成功
$total_fee = $postObj['total_fee'];
//签名算法 Start
ksort($postObj);//排序参数
$buff = "";
foreach ($postObj as $k => $v)//处理参数按照key=>value的形式组合成字符串
{
if($k != "sign" && $v != "" && !is_array($v)){//去掉参数中的sign(微信返回的签名)
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");//去除末尾的&的符号
$buff = $buff.'&key=秘钥';//连接上商户支付秘钥
$signA = strtoupper(MD5($buff));//MD5加密并转为小写
}
if($postobj['sign']==$signA && $total_fee==真实的支付金额){
//订单真实
//逻辑处理
}else{
//签名错误或支付错误
echo '<xml>
<return_code><![CDATA[FAIL]]></return_code>//success成功 fail失败
<return_msg><![CDATA[OK]]></return_msg>
</xml>';//返回微信消息否则微信会一直请求你的异步回调地址
}

注意:以上是针对服务商支付的签名对比方法,普通商户的方法基本上和这个是一致的(普通商户可能不需要去除sign)。


 评论