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 实现微信支付的主要内容,如果未能解决你的问题,请参考以下文章

PHP实现微信申请退款流程实例源码

PHP实现微信小程序支付

PHP实现微信商户支付企业付款到零钱功能代码实例

Api看看PHP是如何实现微信H5支付的?

PHP开发Paypal支付,支付流程和接口实现方案

微信小程序,PHP支付的问题