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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mr.杰瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值