thinkcmf+jsapi 实现微信支付

首先从小程序端接收订单号、金额等参数,然后后台进行统一下单,把微信支付的订单号返回,在把订单号发送给前台,前台拉起支付,返回参数后更改支付状态。。。

回调

1 public function notify() { 2 $wechat=Db::name('wechat')->where('status',1)->find(); 3 4 //$post = $GLOBALS['HTTP_RAW_POST_DATA']; 5 $post = file_get_contents("php://input"); //接受POST数据XML个数 6 7 8 // $order_over_test['openid']=$post; 9 // Db::name('order_over')->insert($order_over_test); 10 11 $post_data = $this->xml_to_array($post); 12 13 14 15 16 //输出订单号 17 $order_sn = $post_data['out_trade_no']; 18 19 $order_over['order_sn']=$order_sn; 20 $order_over['money']=$post_data['total_fee']; 21 $order_over['openid']=$post_data['openid']; 22 $order_over['time_end']=$post_data['time_end']; 23 24 $order_update['status']='1'; 25 26 // Db::name('order_over')->insert($order_over); 27 28 $order_info=Db::name('order')->where('order_id',$order_sn)->find(); 29 30 if ($post_data['return_code'] == 'SUCCESS') { 31 32 //判断证书是否正确 33 // if ($postSign != $user_sign) { 34 // Log::write('签名不匹配'); 35 // exit; 36 // } 37 if ($order_info['status'] != '1') { 38 39 Db::name('order_over')->insert($order_over); 40 $result=Db::name('order')->where('order_id', $order_sn)->update($order_update); 41 } 42 43 return 'success'; 44 45 } else { 46 47 return 'error'; 48 //$this->error('error!'); 49 } 50} 51 52 public function xmlToArray($xml) 53 { 54 $p = xml_parser_create(); 55 xml_parse_into_struct($p, $xml, $vals, $index); 56 xml_parser_free($p); 57 $data = ""; 58 foreach ($index as $key => $value) { 59 if ($key == 'xml' || $key == 'XML') continue; 60 $tag = $vals[$value[0]]['tag']; 61 $value = $vals[$value[0]]['value']; 62 $data[$tag] = $value; 63 } 64 return $data; 65 66 } 67 68 69 public function xml_to_array($xml){ 70 if(!$xml){ 71 return false; 72 } 73 //将XML转为array 74 //禁止引用外部xml实体 75 libxml_disable_entity_loader(true); 76 $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); 77 return $data; 78 } 79 80 public static function ToUrlParams($data) 81 { 82 $buff = ""; 83 foreach ($data as $k => $v) 84 { 85 if($k != "sign" && $v != "" && !is_array($v)){ 86 $buff .= $k . "=" . $v . "&"; 87 } 88 } 89 90 $buff = trim($buff, "&"); 91 return $buff; 92 } 93

统一下单

1 public function getwxpay($orderSn,$money) 2{ 3 // $orderSn=$orderSn; 4 $body='广告投放'; 5 //$orderSn='HB14257311281654'; 6 //$money= '1'; 7 $money=$money*100; 8 $wechat=Db::name('wechat')->where('status',1)->find(); 9 $order_id=$orderSn; 10 11 // $money= $money; //充值金额 微信支付单位为分 12 13 $appid = $wechat['appid']; //应用APPID 14 $mch_id =$wechat['mch_id']; //微信支付商户号 15 $KEY = $wechat['key']; //微信商户API密钥 16 $out_trade_no = $orderSn ;//平台内部订单号 17 $nonce_str = $this->rand_code();//随机字符串 18 // $openid='oM0TH0nyMtlyrP_J8cOL70oLYaCw'; 19 $openid=session('openid'); 20 21 //获取系统的配置 22 23 //$nonce_str = $this->rand_str(12);//随机字符串 24 $notify_url = "http://**********************t/Wxnotify/notify"; //支付完成回调地址url,不能带参数 25 26 $spbill_create_ip = get_client_ip(); 27 $trade_type = 'JSAPI';//交易类型 默认JSAPI 28 29 //这里是按照顺序的 因为下面的签名是按照(字典序)顺序 排序错误 肯定出错 30 $post['appid'] = $appid; 31 $post['body'] = $body; 32 $post['mch_id'] = $mch_id; 33 $post['nonce_str'] = $nonce_str;//随机字符串 34 $post['notify_url'] = $notify_url; 35 $post['openid'] = $openid; 36 $post['out_trade_no'] = $out_trade_no; 37 $post['spbill_create_ip'] = $spbill_create_ip;//服务器终端的ip 38 $post['total_fee'] = intval($money); //总金额 最低为一分钱 必须是整数 39 $post['trade_type'] = $trade_type; 40 $sign = $this->MakeSign($post, $KEY); //签名 41 $this->sign = $sign; 42 43 $post_xml = " 44 <xml> 45 <appid>$appid</appid> 46 <mch_id>$mch_id</mch_id> 47 <nonce_str>$nonce_str</nonce_str> 48 <body>$body</body> 49 <notify_url>$notify_url</notify_url> 50 <openid>$openid</openid> 51 <out_trade_no>$out_trade_no</out_trade_no> 52 <spbill_create_ip>$spbill_create_ip</spbill_create_ip> 53 <total_fee>{$post["total_fee"]}</total_fee> 54 <trade_type>$trade_type</trade_type> 55 <sign>$sign</sign> 56 </xml>"; 57 58 //统一下单接口prepay_id 59 $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; 60 $xml = $this->http_request($url, $post_xml); //POST方式请求http 61 62 $array = $this->xml2array($xml); //将【统一下单】api返回xml数据转换成数组,全要大写 63 64 $array['my_sign'] = $sign; 65 $array['post_xml'] = $post_xml; 66 $array['source_xml'] = $xml; 67 68 if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') { 69 $time = time(); 70 $tmp = ''; //临时数组用于签名 71 $tmp['appId'] = $appid; 72 $tmp['nonceStr'] = $nonce_str; 73 $tmp['package'] = 'prepay_id=' . $array['PREPAY_ID']; 74 $tmp['signType'] = 'MD5'; 75 $tmp['timeStamp'] = "$time"; 76 77 78 // $data['state'] = 1; 79 $data['timeStamp'] = "$time"; //时间戳 80 $data['nonceStr'] = $nonce_str; //随机字符串 81 $data['signType'] = 'MD5'; //签名算法,暂支持 MD5 82 $data['package'] = 'prepay_id='.$array['PREPAY_ID']; //统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=* 83 $data['paySign'] = $this->MakeSign($tmp, $KEY); //签名,具体签名方案参见微信公众号支付帮助文档; 84 $data['prepay_id'] = $array['PREPAY_ID']; 85 $data['out_trade_no'] = $out_trade_no; 86 $data['order_id'] = $order_id; 87 } else { 88 // $data['statusCode'] = ; 89 $data['statusMsg'] = "请求错误"; 90 $data['data']['RETURN_CODE'] = $array['RETURN_CODE']; 91 $data['data']['RETURN_MSG'] = $array['RETURN_MSG']; 92 } 93 94 95 return $data; 96 97 } 98 99 100 101 102 103 104 105 106 public function postXmlCurl($xml,$url,$second = 30){ 107 $ch = curl_init(); 108 //设置超时 109 curl_setopt($ch, CURLOPT_TIMEOUT, $second); 110 curl_setopt($ch,CURLOPT_URL, $url); 111 curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); 112 curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE); 113 //设置header 114 curl_setopt($ch, CURLOPT_HEADER, FALSE); 115 //要求结果为字符串且输出到屏幕上 116 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 117 //post提交方式 118 curl_setopt($ch, CURLOPT_POST, TRUE); 119 curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 120 //运行curl 121 $data = curl_exec($ch); 122 //返回结果 123 if($data){ 124 curl_close($ch); 125 return $data; 126 }else{ 127 $error = curl_errno($ch); 128 curl_close($ch); 129 echo "curl出错,错误码:$error"."<br>"; 130 } 131 } 132 133 134 135 136 137 //生成签名 138 public function MakeSign($params, $KEY) 139 { 140 //签名步骤一:按字典序排序数组参数 141 ksort($params); 142 $string = $this->ToUrlParams($params); //参数进行拼接key=value&k=v 143 //签名步骤二:在string后加入KEY 144 $string = $string . "&key=" . $KEY; 145 //签名步骤三:MD5加密 146 $string = md5($string); 147 //签名步骤四:所有字符转为大写 148 $result = strtoupper($string); 149 return $result; 150 } 151 152 /** 153 * 格式化参数格式化成url参数 154 */ 155 public static function ToUrlParams($data) 156 { 157 $buff = ""; 158 foreach ($data as $k => $v) 159 { 160 if($k != "sign" && $v != "" && !is_array($v)){ 161 $buff .= $k . "=" . $v . "&"; 162 } 163 } 164 165 $buff = trim($buff, "&"); 166 return $buff; 167 } 168 169 170 171 //发送http请求 172 173 public function http_request($url, $data = null, $headers = array()) 174 { 175 $curl = curl_init(); 176 if (count($headers) >= 1) { 177 curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 178 } 179 curl_setopt($curl, CURLOPT_URL, $url); 180 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 181 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 182 // 183 $zs1 = CMF_ROOT . "cert/apiclient_cert.pem"; 184 $zs2 = CMF_ROOT . "cert/apiclient_key.pem"; 185 186 187 188 // curl_setopt ( $curl, CURLOPT_SSLCERT, $zs1 ); 189 // curl_setopt ( $curl, CURLOPT_SSLKEY, $zs2 ); 190 //设置证书 191 //使用证书:cert 与 key 分别属于两个.pem文件 192 curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM'); 193 curl_setopt($curl, CURLOPT_SSLCERT, $zs1); 194 curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM'); 195 curl_setopt($curl, CURLOPT_SSLKEY, $zs2); 196 197 if (!empty($data)) { 198 curl_setopt($curl, CURLOPT_POST, 1); 199 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); 200 } 201 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 202 $output = curl_exec($curl); 203 curl_close($curl); 204 return $output; 205 } 206 //获取xml里面数据,转换成array 207 public function xml2array($xml) 208 { 209 $p = xml_parser_create(); 210 xml_parse_into_struct($p, $xml, $vals, $index); 211 xml_parser_free($p); 212 $data = ""; 213 foreach ($index as $key => $value) { 214 if ($key == 'xml' || $key == 'XML') continue; 215 $tag = $vals[$value[0]]['tag']; 216 $value = $vals[$value[0]]['value']; 217 $data[$tag] = $value; 218 } 219 return $data; 220 221 } 222 223 //随机字符串 224 public function rand_code($length = 16) { 225 226 $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 227 228 $str = ""; 229 230 for ($i = 0; $i < $length; $i++) { 231 232 $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); 233 234 } 235 236 return $str; 237 238 } 239 240 public function ToXml($data=array()) 241 242 { 243 if(!is_array($data) || count($data) <= 0) 244 { 245 return '数组异常'; 246 } 247 248 $xml = "<xml>"; 249 foreach ($data as $key=>$val) 250 { 251 if (is_numeric($val)){ 252 $xml.="<".$key.">".$val."</".$key.">"; 253 }else{ 254 $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; 255 } 256 } 257 $xml.="</xml>"; 258 return $xml; 259 }

前台页面拉起微信支付

1<!DOCTYPE html> 2<html> 3<head> 4 <title>订单支付 {$site_info.site_name|default=''}</title> 5 <meta name="keywords" content="{$site_info.site_seo_keywords|default=''}"/> 6 <meta name="description" content="{$site_info.site_seo_description|default=''}"> 7 8<include file="public@head"/> 9 10 11 12</head> 13<body > 14<include file="public@top"/> 15<hook name="before_head_end"/> 16<!-- top --> 17 18 19 20<div class="zt"> 21<div class="am-container"> 22 23<div> 24 <div class="order_info"> 25 <h3 class="am-text-center">核实订单</h3> 26</div> 27 28 <div class="order_money am-text-center"> 29 <table class="am-table "> 30 <tr> 31 <td>订单号</td> 32 <td class="am-text-right">{$order_info['order_id']}</td> 33 </tr> 34 <tr> 35 <td>金额</td> 36 <td class="am-text-right">{$order_info['money']}</td> 37 <input type="hidden" name="money" id="money_input" value=""> 38 </tr> 39 </table> 40 </div> 41 42 <div class="am-form-group"> 43 44 45 <button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" >立即支付</button> 46 47 </div> 48</div> 49</div> 50</div> 51 52 53<include file="public@footer"/> 54 55 56<!-- <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> --> 57 <script type="text/javascript"> 58 59 //调用微信JS api 支付 60 function jsApiCall() 61 { 62 63 WeixinJSBridge.invoke( 64 'getBrandWCPayRequest', { 65 "appId":'{$wechat['appid']}', //公众号名称,由商户传入 66 "timeStamp":'{$wxpay_status['timeStamp']}', //时间戳,自1970年以来的秒数 67 "nonceStr":'{$wxpay_status['nonceStr']}', //随机串 68 "package":'{$wxpay_status['package']}', 69 "signType":"MD5", //微信签名方式: 70 "paySign":'{$wxpay_status['paySign']}'//微信签名 71 }, 72 function(res){ 73 console.log(res); 74 WeixinJSBridge.log(res.err_msg); 75 //alert('err_code:'+res.err_code+'err_desc:'+res.err_desc+'err_msg:'+res.err_msg); 76 //alert(res.err_code+res.err_desc+res.err_msg); 77 //alert(res); 78 if(res.err_msg == "get_brand_wcpay_request:ok"){ 79 alert("支付成功!"); 80 window.location.href="http://m.sxcrcm.com"; 81 }else if(res.err_msg == "get_brand_wcpay_request:cancel"){ 82 alert("用户取消支付!"); 83 }else{ 84 alert("支付失败!"); 85 } 86 } 87 ); 88 } 89 90function callpay() 91 { 92 if (typeof WeixinJSBridge == "undefined"){ 93 if( document.addEventListener ){ 94 document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); 95 }else if (document.attachEvent){ 96 document.attachEvent('WeixinJSBridgeReady', jsApiCall); 97 document.attachEvent('onWeixinJSBridgeReady', jsApiCall); 98 } 99 }else{ 100 jsApiCall(); 101 } 102 } 103 104 </script> 105</body>
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )