博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
thinkPHP实现APP微信支付
阅读量:6979 次
发布时间:2019-06-27

本文共 5129 字,大约阅读时间需要 17 分钟。

控制器
class Pay extends Controller{  const WX_PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";  const NOTIFY_URL = "http://xxx.xxx.com/wx_notify";  const WX_APPID = "wx***********";  const WX_MCHID = "1********";  const WX_MCHKEY = "*********"; //key是在商户平台API安全里自己设置的  public function wxPay()   {    $money = input('post.money/s','','trim');    $nonce_str = randCode(); //调用随机字符串生成方法获取随机字符串    $data['appid'] = self::WX_APPID; //appid    $data['mch_id'] = self::WX_MCHID; //商户号    $data['body'] = "APP支付测试";    $data['spbill_create_ip'] = getIp(); //ip地址    $data['total_fee'] = $money/100; //金额    $data['out_trade_no'] = time().mt_rand(10000,99999); //商户订单号,不能重复    $data['nonce_str'] = $nonce_str; //随机字符串    $data['notify_url'] = self::NOTIFY_URL; //回调地址,用户接收支付后的通知,必须为能直接访问的网址,不能跟参数    $data['trade_type'] = 'APP'; //支付方式    //将参与签名的数据保存到数组 注意:以上几个参数是追加到$data中的,$data中应该同时包含开发文档中要求必填的剔除sign以外的所有数据    $data['sign'] = getSign($data,self::WX_MCHKEY); //获取签名    $xml = ToXml($data); //数组转xml    //curl 传递给微信方    $url = self::WX_PAY_URL;    //运行curl    $data = curlHttpRequest($url, $xml);    //返回结果    if($data){      //返回成功,将xml数据转换为数组.      $re = FromXml($data);      if($re['return_code'] != 'SUCCESS'){        echo json_encode("code"=>"201","data"=>"","msg"=>'签名失败');      } else {        //接收微信返回的数据,传给APP!        $arr =array(          'prepayid' =>$re['prepay_id'],          'appid' => self::WX_APPID,          'partnerid' => self::WX_MCHID,          'package' => 'Sign=WXPay',          'noncestr' => $nonce_str,          'timestamp' =>time(),        );        //第二次生成签名        $sign = getSign($arr,self::WX_MCHKEY);        $arr['sign'] = $sign;        echo json_encode("code"=>"200","data"=>$arr,"msg"=>'签名成功');      }   } else {    $error = curl_errno($ch);    curl_close($ch);    echo json_encode("code"=>"201","data"=>'"","msg"=>'curl出错,错误码:$error');  }  // 微信支付回调  public function wxNotify(){    //接收微信返回的数据数据,返回的xml格式    $xmlData = file_get_contents('php://input');    //将xml格式转换为数组    $data = FromXml($xmlData);    //用日志记录检查数据是否接受成功,验证成功一次之后,可删除。    $file = fopen('./log.txt', 'a+');    fwrite($file,var_export($data,true));    //为了防止假数据,验证签名是否和返回的一样。    //记录一下,返回回来的签名,生成签名的时候,必须剔除sign字段。    $sign = $data['sign'];    unset($data['sign']);    if($sign == getSign($data)){      //签名验证成功后,判断返回微信返回的      if ($data['result_code'] == 'SUCCESS') {        //根据返回的订单号做业务逻辑        $arr = array(          'pay_status' => 1,        );        $re = M('order')->where(['order_sn'=>$data['out_trade_no']])->save($arr);        //处理完成之后,告诉微信成功结果!        if($re){          echo '
';exit();        }      } else {        //支付失败,输出错误信息        $file = fopen('./log.txt', 'a+');        fwrite($file,"错误信息:".$data['return_msg'].date("Y-m-d H:i:s"),time()."\r\n");       }    } else {      $file = fopen('./log.txt', 'a+');      fwrite($file,"错误信息:签名验证失败".date("Y-m-d H:i:s"),time()."\r\n");     }  }}?>
 

  

调用方法 function.php
";    foreach ($data as $key=>$val)    {      if (is_numeric($val)){        $xml.="<".$key.">".$val."
";      }else{        $xml.="<".$key.">
";      }    }    $xml.="";    return $xml;  }  function randCode()  {    $str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';//62个字符    $str = str_shuffle($str);    $str = substr($str,0,32);    return $str;  }  function getSign($params,$key)   {    ksort($params); //将参数数组按照参数名ASCII码从小到大排序    foreach ($params as $key => $item) {      if (!empty($item)) { //剔除参数值为空的参数        $newArr[] = $key.'='.$item; // 整合新的参数数组      }    }    $stringA = implode("&", $newArr); //使用 & 符号连接参数    $stringSignTemp = $stringA."&key=".$key; //拼接key    // key是在商户平台API安全里自己设置的    $stringSignTemp = MD5($stringSignTemp); //将字符串进行MD5加密    $sign = strtoupper($stringSignTemp); //将所有字符转换为大写    return $sign;  }  function getIp()  {    if ($_SERVER['REMOTE_ADDR']) {      $ip = $_SERVER['REMOTE_ADDR'];    } elseif (getenv("REMOTE_ADDR")) {      $ip = getenv("REMOTE_ADDR");    } elseif (getenv("HTTP_CLIENT_IP")) {      $ip = getenv("HTTP_CLIENT_IP");    } else {      $ip = "unknown";    }    return $ip;  }  function curlHttpRequest($url,$xml)  {    //header("Content-type:text/xml"););    $ch = curl_init();    curl_setopt($ch,CURLOPT_URL, $url);    if(stripos($url,"https://")!==FALSE){      curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);    } else {      curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);      curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验    }    //设置header    curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);    curl_setopt($ch, CURLOPT_HEADER, FALSE);    //要求结果为字符串且输出到屏幕上    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);    //设置超时    curl_setopt($ch, CURLOPT_TIMEOUT, 30);    curl_setopt($ch, CURLOPT_POST, TRUE);    //传输文件    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);    //释放句柄    curl_close($ch);    //运行curl    $data = curl_exec($ch);    //返回结果    return $data;  }?>
 

  

转载于:https://www.cnblogs.com/qhorse/p/9719232.html

你可能感兴趣的文章
Extjs:添加查看全部按钮
查看>>
UNIX/Linux系统管理技术手册(3)----bash 数组和算术运算
查看>>
LINQ之路19:LINQ to XML之X-DOM更新、和Value属性交互
查看>>
笔记之远程桌面服务(RDS)
查看>>
怎样操作vue.js使用3DES加密
查看>>
js实现点击<li>标签弹出其索引值
查看>>
DIV限制宽度,字符断行,避免变形
查看>>
通过进程ID获得该进程主窗口的句柄
查看>>
快速把web项目部署到weblogic上
查看>>
.Net 文件流 System.IO之Stream
查看>>
Jmeter 笔记
查看>>
一个JS对话框,可以显示其它页面,
查看>>
IDEA ctrl+alt+L 格式化快捷键无效时解决
查看>>
前端小知识
查看>>
子弹实例化的代码
查看>>
URAL 2027 URCAPL, Episode 1 (模拟)
查看>>
hadoop install start-dfs.sh 失败
查看>>
各种小记
查看>>
Java关键字final、static使用总结
查看>>
Bootstrap 模态框上下居中
查看>>