PHP微信支付结果通知与回调策略分析

本文实例讲述了PHP微信支付结果通知与回调策略。分享给大家供大家参考,具体如下:

支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答。

对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。 (通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒)

注意:同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。

推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。

特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失。

$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
exit($str);
//微信支付回调
public function order_notice(){
    $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
    //将服务器返回的XML数据转化为数组
    $data = $this->FromXml($xml);
    // 保存微信服务器返回的签名sign
    $data_sign = $data['sign'];
    // sign不参与签名算法
    unset($data['sign']);
    //$sign = self::makeSign($data);
    $sign = $this->makeSign($data);
    Clog::setLog($data,'order_notice');
    // 判断签名是否正确 判断支付状态
    if ( ($sign===$data_sign) && ($data['return_code']=='SUCCESS') && ($data['result_code']=='SUCCESS') ) {
      //获取服务器返回的数据
      $order_num = $data['out_trade_no'];     //订单单号
      $openid = $data['openid'];         //付款人openID
      $total_fee = $data['total_fee'];      //付款金额
      $transaction_id = $data['transaction_id']; //微信支付流水号
      $res = $this->order_notice_data_deal($order_num,$openid,$total_fee,$transaction_id);
      if (!$res) {
        $result = -2;
      } else {
        $result = 0;
      }
    }else{
      $result = -1;
    }
    // 返回状态给微信服务器
    if ($result == 0) { // 成功之后不会再回调
      $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
    } elseif ($result == -1){ // 失败后会继续发送几次回调
      $str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
    } elseif ($result == -2) { // 失败后会继续发送几次回调
      $str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[更改状态失败]]></return_msg></xml>';
    }
    Clog::setLog($result,'order_notice_result');
    exit($str);
}

附上微信支付助手函数

public function ToXml($array){
    if(!is_array($array)|| count($array) <= 0){
      return ;
    }
    $xml = '<xml version="1.0">';
    foreach ($array as $key=>$val){
      if (is_numeric($val)){
        $xml.="<".$key.">".$val."</".$key.">";
      }else{
        $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
      }
    }
    $xml.="</xml>";
    return $xml;
}
public function FromXml($xml){
    if(!$xml){
      // 人工抛出错误
      throw new Exception("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 MakeSign($data)
{
    //签名步骤一:按字典序排序参数
    ksort($data);
    $string = $this->ToUrlParams($data);
    //签名步骤二:在string后加入KEY
    $string = $string . "&key=".C('WEIXIN_PAY_KEY');
    //签名步骤三:MD5加密
    $string = md5($string);
    //签名步骤四:所有字符转为大写
    $result = strtoupper($string);
    return $result;
}
public function ToUrlParams($array)
{
    $buff = "";
    foreach ($array as $k => $v)
    {
      if($k != "sign" && $v != "" && !is_array($v)){
        $buff .= $k . "=" . $v . "&";
      }
    }
    $buff = trim($buff, "&");
    return $buff;
}
// createNonceStr
public function createNonceStr($length = 16) {
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    $str ="";
    for ( $i = 0; $i < $length; $i++ ) {
      $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
    }
    return $str;
}

更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP微信开发技巧汇总》、《PHP编码与转码操作技巧汇总》、《PHP网络编程技巧总结》、《php字符串(string)用法总结》、《PHP中json格式数据操作技巧汇总》及《PHP针对XML文件操作技巧总结》

希望本文所述对大家PHP程序设计有所帮助。

(0)

相关推荐

  • PHP开发微信支付的代码分享

    微信支付,即便交了保证金,你还是处理测试阶段,不能正式发布.必须到你通过程序测试提交订单.发货通知等数据到微信的系统中,才能申请发布. 然后,因为在微信中是通过JS方式调用API,必须在微信后台设置支付授权目录,而且要到二级三级目录下去,这对于使用MVC框架来说,是个小问题. 使用MVC,在开发环境,url往往是native url格式,不能保证一定是带有路径/的形式 所以,比较可靠的方式,是创建实体的子文件夹,这样的化,在系统整体url方面,需要进行一些改造. 另外,最后一步,js调用时,对于

  • 浅析PHP微信支付通知的处理方式

    通知机制的实现,官方只有文档没有demo代码,对没搞过的人来说,需要花大量时间来做测试. 从文档上说的来看,微信每次通知过来的数据,结构比较复杂,是一个多段数据,除了要取出POST数据外,还要取其它的数据. 这里首先涉及到一个关于php://input与$_POST取值的问题,简单列几点如下: 复制代码 代码如下: 1,Content- Type取值为application/x-www-form-urlencoded时,php会将http请求body相应数据会填入到数组$_POST,填入到$_P

  • php开发微信支付获取用户地址

    使用微信获取地址信息是和微信支付一道申请的,微信支付申请通过,就可以使用该功能. 微信商城中,使用微信支付获取用户的收货地址,可以省略用户输入地址信息的繁复流程,提高用户体验. 但是可能是因为牵扯到用户隐私,所以在使用过程中,需要用户自己主动选择使用该功能,并且是通过点击的操作,我们才可以获取到用户的收货地址,这一点是要注意的. 操作流程如下: 1.用户打开购物车页面,点击结算,跳转到一个微信的oauth2的页面,地址为:https://open.weixin.qq.com/connect/oa

  • php对微信支付回调处理的方法

    应用场景 支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答. 对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功. (通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒) 注意:同样的通知可能会多次发送给商户系统.商户系统必须能够正确处理重复的通知. 推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的

  • PHP微信支付开发实例

    PHP微信支付开发过程,分享给大家,供大家参考,具体内容如下 1.开发环境 Thinkphp 3.2.3 微信:服务号,已认证 开发域名:http://test.paywechat.com (自定义的域名,外网不可访问) 2.需要相关文件和权限 微信支付需申请开通 微信公众平台开发者文档:http://mp.weixin.qq.com/wiki/home/index.html 微信支付开发者文档:https://pay.weixin.qq.com/wiki/doc/api/index.html

  • php微信支付之公众号支付功能

    网上的很多PHP微信扫码支付接入教程都颇为复杂,且需要配置和引入较多的文件,本人通过整理后给出一个单文件版的,希望可以给各位想接入微信扫码支付的带来些许帮助和借鉴意义. 将该文件放到你的授权目录下,并在微信里访问这个文件,即可看到演示效果.效果如下:   需要注意的事项: 1.该文件需放到支付授权目录下,可以在微信支付商户平台->产品中心->开发配置中设置. 2.如提示签名错误可以通过微信支付签名验证工具进行验证:微信公众平台支付接口调试工具 代码如下: <?php header('Co

  • Thinkphp整合微信支付功能

    先上效果图:我要告诉你我这一篇文章写的是微信支付之中的(普通商户而非服务商商户的统一下单JSPI)微信支付: 其实自己整合SDK失败了,用了一个博客博主整合的代码,在这里写一下笔记: 前面准备: 1.微信公众号: 独特的appid.appscrect.接口权限之中设置可以获取用户ID信息权限的域名(每个用户对于不同公众都会有一个特有ID,通过这个ID获取用户微信账号基本信息.详情看微信开发者文档).在微信支付按钮出设置微信支付授权目录(写到发起请求的控制器那一层).设置开发者微信账号为测试白名单

  • ThinkPHP实现微信支付(jsapi支付)流程教程详解

    之前写过一篇文章讲了PHP实现微信支付(jsapi支付)流程 ,详见文章:PHP实现微信支付(jsapi支付)流程. 当时的环境是没有使用框架的,直接在一个域名指向的目录下边新建目录之后访问该目录实现的,但应用到框架中,还是有一些问题,在ThinkPHP中,由于路由规则与支付授权目录有出入,所以会报错.本篇讲讲在TP中集成微信支付的流程. 鹅厂出的SDK和文档,就是让你看不懂,使劲绕,这酸爽用了就知道.文档和SDK不是应该越简单通俗易懂越好么?难道只有使劲重构才能显示出鹅厂程序猿技术的高超咩?额

  • 微信支付PHP SDK —— 公众号支付代码详解

    在微信支付 开发者文档页面 下载最新的 php SDK http://mch.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 这里假设你已经申请完微信支付 1. 微信后台配置  如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请求的哪个文件所在的目录. 例如jsapi 发起请求一般是jsapi.php所在目录 为测试目录,测试白名单即开发人员的微信号. 正式的支付授权目录不能和测试的一样否则会报错.不填

  • 微信支付PHP SDK之微信公众号支付代码详解

    这里假设你已经申请完微信支付 1. 微信后台配置  如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请求的哪个文件所在的目录. 例如jsapi 发起请求一般是jsapi.php所在目录 为测试目录,测试白名单即开发人员的微信号. 正式的支付授权目录不能和测试的一样否则会报错.不填写或者填错授权目录以及测试白名单都会报错. 报错样例: NaNsystem:access_denied 不在测试白名单 2. 配置 lib/WxPay.Config.php文件

  • php官方微信接口大全(微信支付、微信红包、微信摇一摇、微信小店)

    微信入口绑定,微信事件处理,微信API全部操作包含在这些文件中. 内容有:微信摇一摇接口/微信多客服接口/微信支付接口/微信红包接口/微信卡券接口/微信小店接口/JSAPI <?php class WxApi { const appId = ""; const appSecret = ""; const mchid = ""; //商户号 const privatekey = ""; //私钥 public $param

随机推荐