php 实现微信支付
Posted mr.杰瑞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php 实现微信支付相关的知识,希望对你有一定的参考价值。
最近正在做一个支付项目。
场景是在微信小程序支付9.9,然后会让用户体验一个功能。
因为是第一次接触微信支付,这个文档会慢慢补充。
$obj = new PayUnifiedorder();
$obj ->SetAppid($wxpayment['payment']['appid']); //微信分配的小程序ID
$obj ->SetMchId($wxpayment['payment']['mch_id']); //微信支付分配的商户号
$obj ->SetSignType('MD5'); //签名类型,默认为MD5
$obj ->SetBody('OO-XX'); //SetBody 设置商品或支付单简要描述
$obj ->SetAttch('OO'); //附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。
$obj ->SetTotalFee(990); //设置金额 以分为单位 9.9
$order_money = $obj ->SetTotalFee(990);
$obj ->Setip($ip); //当前运行脚本所在的服务器的 IP 地址 //APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP(Native支付是指商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式)
$obj ->SetNotifyUrl('支付会掉用这个地址'); //SetNotify_url 设置接收微信支付异步通知回调地址
$obj ->SetTradType('JSAPI'); //SetTrade_type 设置支付方式,设置取值如下:JSAPI,NATIVE,APP,分别是网页、扫码、APP
$string = $obj ->SetNonceStr(); //生成随机字符串
//获取当前人的openid
$openid = $obj ->GetOpenId($wxpayment['payment']['appid'],$wxpayment['payment']['appsecret'],$code); //调用base.class.php 获取了OpenId之后,我们就可以组合订单了
$obj ->SetOpenid($openid); //设置我们获取的用户OpenId
$order_num = $obj ->CreateOrder(); //生成订单编号2019060410249509
$obj ->SetOrder($order_num); //商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一
//商户key 生成Sign
$key = $obj ->GetSign($wxpayment['payment']['mch_key']); //生成加密串
$obj ->SetSign($key); //回调时候验证使用
$result = $obj ->ToXML();
create_order($order_num,$mobile,$order_money);
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$res = $obj->http->request($url,$result);
$res = $obj->FromXml($res);
微信统一支付PHP接口导致服务器变慢
现象描述:
在接入微信统一支付接口之后,微信中调用创建订单功能,尝试多次之后,服务器对普通请求的响应速度变慢,甚至出现500错误,在重启服务后恢复正常。
问题解决:
该问题经过长时间检查,最终定位到微信接口WxPay.Data.php中WxPayDataBase类的FromXml()方法上,导致问题的代码如下
public function FromXml($xml)
if(!$xml)
throw new WxPayException("xml数据异常!");
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true); //这句导致出现上述问题
$this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $this->values;
网上说改为如下即可解决,但由于线上代码没有出现错误
目前代码并没有改成下面的版本,需要进行测试,先做个记号
public function FromXml($xml)
if(!$xml)
throw new WxPayException("xml数据异常!");
//将XML转为array
//禁止引用外部xml实体
$disableLibxmlEntityLoader = libxml_disable_entity_loader(true); //改为这句
$this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
libxml_disable_entity_loader($disableLibxmlEntityLoader); //添加这句
return $this->values;
支付成功回调接口
$post = post_data_xml(); //接受POST数据XML个数
$post_data = FromXmlArray($post); //微信支付成功,返回回调地址url的数据:XML转数组Array
$postSign = $post_data['sign'];
unset($post_data['sign']);
//unset掉传来的验签 再自己拼接 用同样的加密方式生成 sign
/* 微信官方提醒:
* 商户系统对于支付结果通知的内容一定要做【签名验证】,
* 并校验返回的【订单金额是否与商户侧的订单金额】一致,
* 防止数据泄漏导致出现“假通知”,造成资金损失。
*/
ksort($post_data);// 对数据进行排序
$str = ToUrlParams($post_data)."&key=自己定义的加密串";//对数组数据拼接成key=value字符串
$user_sign = 自己定义的加密进行加密; //再次生成签名,与$postSign比较
if($user_sign != $postSign)
exit('验签失败');
else
if($post_data['return_code']=='SUCCESS' && $post_data['result_code']=='SUCCESS')
//根据订单号来判断是否有这条支付成功的记录
if(记录)
if(判断支付成功的条件,验证订单金额)
//自己的业务逻辑
return_success();
else
exit('微信支付失败');
else
exit('微信支付失败');
else
exit('微信支付失败');
function FromXmlArray($xml)
if(!$xml)
return false;
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$result = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $result;
function ToUrlParams($values)
$buff = "";
foreach ($values as $k => $v)
if($k != "sign" && $v != "" && !is_array($v))
$buff .= $k . "=" . $v . "&";
$buff = trim($buff, "&");
return $buff;
function post_data_xml()
$receipt = $_REQUEST;
if($receipt==null)
$receipt = file_get_contents("php://input");
if($receipt == null)
$receipt = $GLOBALS['HTTP_RAW_POST_DATA'];
return $receipt;
/*
* 给微信发送确认订单金额和签名正确,SUCCESS信息 -xzz0521
*/
function return_success()
$return['return_code'] = 'SUCCESS';
$return['return_msg'] = 'OK';
$xml_post = '<xml>
<return_code>'.$return['return_code'].'</return_code>
<return_msg>'.$return['return_msg'].'</return_msg>
</xml>';
echo $xml_post;exit;
以上是关于php 实现微信支付的主要内容,如果未能解决你的问题,请参考以下文章