vendor/wxpay/pay.php
doneOrder(); $timeStamp = time(); $this->params = array( 'appId' => Config::APPID, 'timeStamp'=> "$timeStamp", 'nonceStr' => $this->getNonceStr(), 'package' => 'prepay_id=' . $this->prepay_id, 'signType' => 'MD5' ); $this->params['paySign'] = $this->MakeSign(); } /** * 统一下单 * @return array */ public function doneOrder(){ $this->params['mch_id'] = Config::MCHID; $this->params['appid'] = Config::APPID; $this->params['sign'] = $this->MakeSign($this->params); $response = $this->FromXml($this->postXmlCurl($this->ToXml(), $this->url, false)); $this->prepay_id = $response['prepay_id']; } /** * 验证 * @return array 返回数组格式的notify数据 */ public function notify(){ //获取xml $xml = file_get_contents('php://input'); //转成php数组 $this->params = $this->FromXml($xml); //保存原sign $data_sign = $this->params['sign']; //sign不参与签名 unset($this->params['sign']); $sign = $this->makeSign(); //判断签名是否正确 判断支付状态 if ($sign===$data_sign && $this->params['return_code']=='SUCCESS' && $this->params['result_code']=='SUCCESS') { $result = $this->params; $str = ''; }else{ $result = false; $str = ' '; } echo $str; return $result; } /** * 生成签名 * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值 */ public function MakeSign() { //签名步骤一:按字典序排序参数 ksort($this->params); $string = $this->ToUrlParams(); //签名步骤二:在string后加入KEY $string = $string . '&key=' . Config::KEY; //签名步骤三:MD5加密 $string = md5($string); //签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result; } /** * 格式化参数格式化成url参数 */ public function ToUrlParams() { $buff = ''; foreach($this->params as $k => $v) { if($k!='sign' && $v!='' && !is_array($v)){ $buff .= $k . '=' . $v . '&'; } } $buff = trim($buff, '&'); return $buff; } /** * 以post方式提交xml到对应的接口url * @param string $xml 需要post的xml数据 * @param string $url url * @param bool $useCert 是否需要证书,默认不需要 * @param int $second url执行超时时间,默认30s * @throws WxPayException */ private static function postXmlCurl($xml, $url, $useCert = false, $second = 30) { $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); //如果有配置代理这里就设置代理 if(Config::CURL_PROXY_HOST != "0.0.0.0" && Config::CURL_PROXY_PORT != 0){ curl_setopt($ch,CURLOPT_PROXY, Config::CURL_PROXY_HOST); curl_setopt($ch,CURLOPT_PROXYPORT, Config::CURL_PROXY_PORT); } curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验 //设置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); if($useCert == true){ //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT, Config::SSLCERT_PATH); curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY, Config::SSLKEY_PATH); } //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //运行curl $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); curl_close($ch); throw new Exception("curl出错,错误码:$error"); } } /** * 输出xml字符 * @throws WxPayException **/ public function ToXml() { if(!is_array($this->params) || count($this->params) <= 0) { throw new Exception('数组数据异常!'); } $xml = ' '; foreach($this->params as $key=>$val) { if(is_numeric($val)){ $xml .= '<'.$key.'>'.$val.' '; }else{ $xml .= '<'.$key.'> '; } } $xml .= ' '; return $xml; } /** * 将xml转为array * @param string $xml * @throws WxPayException */ public function FromXml($xml) { if(!$xml){ throw new Exception('xml数据异常!'); } //将XML转为array //禁止引用外部xml实体 libxml_disable_entity_loader(true); $this->params = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $this->params; } /** * * 产生随机字符串,不长于32位 * @param int $length * @return 产生的随机字符串 */ public function getNonceStr($length = 32) { $chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; $str = ''; for($i = 0; $i<$length; $i++){ $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; }}?>
vendor/wxpay/config.php
vendor/cert/apiclient_cert.pem vendor/cert/apiclient_key.pem 控制器Controller
Vendor('wechat.pay');class Wechat extends Base{ public function wxPay(){ $payobj = new \pay(); $openid = input('post.openid/s'); $needMoney = input('post.money/s'); if (!empty($openid)) { //统一下单 $orderid = $this->build_order_no(); $notify_url = 'http://xxxxxx/Wechat/notify'; $payobj->params = [ 'openid' => $openid, 'body' => 'body', 'out_trade_no' => $orderid, 'total_fee' => $needMoney * 100, 'nonce_str' => $this->getNonceStr(), 'spbill_create_ip' => getIp(), 'notify_url' => $notify_url, 'trade_type' => 'JSAPI' ]; $payobj->GetJsApiParameters(); $data = [ 'order_num' => $orderid, 'user_open_id' => $openid, 'pay_money' => $needMoney, ]; $oid = Db::name('order_pay')->insert($data); if($oid){ return ['status'=>'0','info'=>'ok','data'=>json_encode($payobj->params)]; } return ['status'=>'-1','info'=>'下单失败,请重试']; } } //微信支付回调 public function notify(){ $payobj = new \pay(); $result = $payobj->notify(); if($result){ //成功后回调 $where['order_num'] = $result['out_trade_no']; //根据需求处理逻辑 } } /** * 生成订单号码 * @return string */ public function build_order_no() { return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 6), 1))), 0, 8) . mt_rand(100,999); } /** * 产生随机字符串,不长于32位 * @param int $length * @return 产生的随机字符串 */ public function getNonceStr($length = 32) { $chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; $str = ''; for($i = 0; $i<$length; $i++){ $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; }}
页面上View 引用jquery; 引用layui.js 引用jweixin-1.1.0.js