最近项目里面需要做公众号和H5支付的功能,根据自己的体验,整理了一下,做个记录。
首先我解释一下,为什么有公众号支付还要做H5支付?因为不确定每个用户在公众号上打开网站,所以另外做了H5支付。
以下是官方的解释:
H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付。
主要用于触屏版的手机浏览器请求微信支付的场景。可以方便的从外部浏览器唤起微信支付。
提醒:H5支付不建议在APP端使用,如需要在APP中使用微信支付,请接APP支付,文档详见微信支付开发文档。
既然是公众号支付,准备工作要做好(下载的SDK是V3版本):
必须是认证的服务号才能支付,详细接口权限见官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433401084。
1.登陆公众号:
2.
3.登陆商户平台(pay.weixin.qq.com)
在开发配中设置如下:
H5支付直接填写服务器的域名即可。
JSAPI授权目录这里需要注意,如果支付授权目录没有设置正确,在请求JSAPI时,会提示“-1当前页面的url未注册”的错误。”
首先要看你支付的当前页面URL,
比如是:http://www.xxx.com/wxpay/jsapi.php
你就必须填写:http://www.xxx.com/wxpay/
假如是:http://www.xxx.com/wxpay/order/id/56.html
你就必须写: http://www.xxx.com/wxpay/order/id/
假如是:http://www.xxx.com/wxpay/order?id=56
你就必须写:http://www.xxx.com/wxpay/order/
下面是代码部分(没有自己封装代码,直接用官方的示例代码进行修改):
下载好官方的sdk,我是放到网站的根目录,看网上有把SDK进行集成封装好的,大家可自行搜索。
1.在lib----->下的Wxpay.Config.php文件中,填好APPID、MCHID、KEY(操作密码)、APPSECRET(公众帐号secert)
设置证书:
在配置文件的最后最好加上回调地址(当时我没有设置报错了,想不起来是什么错误了,没及时记录……)
2.写一个验证token的方法(代码是网上找的,顺便找了一下有关token的登陆介绍:http://blog.csdn.net/resilient/article/details/72673222)
1 <?php 2 /** 3 * wechat php test 4 */ 5 //define your token 6 define("TOKEN", "shendai"); 7 $wechatObj = new wechatCallbackapiTest(); 8 $wechatObj->valid(); 9 10 class wechatCallbackapiTest 11 { 12 public function valid() 13 { 14 $echoStr = $_GET["echostr"]; 15 //valid signature , option 16 if ($this->checkSignature()) 17 { 18 echo $echoStr; 19 exit; 20 } 21 } 22 public function responseMsg() 23 { 24 //get post data, May be due to the different environments 25 $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 26 //extract post data 27 if (!empty($postStr)) 28 { 29 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 30 $fromUsername = $postObj->FromUserName; 31 $toUsername = $postObj->ToUserName; 32 $keyword = trim($postObj->Content); 33 $time = time(); 34 $textTpl = "<xml> 35 <ToUserName><![CDATA[%s]]></ToUserName> 36 <FromUserName><![CDATA[%s]]></FromUserName> 37 <CreateTime>%s</CreateTime> 38 <MsgType><![CDATA[%s]]></MsgType> 39 <Content><![CDATA[%s]]></Content> 40 <FuncFlag>0</FuncFlag> 41 </xml>"; 42 if (!empty($keyword)) 43 { 44 $msgType = "text"; 45 $contentStr = "Welcome to wechat world!"; 46 $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); 47 echo $resultStr; 48 } 49 else 50 { 51 echo "Input something..."; 52 } 53 } 54 else 55 { 56 echo ""; 57 exit; 58 } 59 } 60 private function checkSignature() 61 { 62 $signature = $_GET["signature"]; 63 $timestamp = $_GET["timestamp"]; 64 $nonce = $_GET["nonce"]; 65 $token = TOKEN; 66 $tmpArr = array($token, $timestamp, $nonce); 67 sort($tmpArr); 68 $tmpStr = implode($tmpArr); 69 $tmpStr = sha1($tmpStr); 70 if ($tmpStr == $signature) 71 { 72 return true; 73 } 74 else 75 { 76 return false; 77 } 78 } 79 80 81 } 82 83 ?>
3.公众号支付文件jsapi.php,只用示例代码进行了修改
1 <?php 2 ini_set('date.timezone','Asia/Shanghai'); 3 //error_reporting(E_ERROR); 4 require_once "$wx_root/lib/WxPay.Api.php"; 5 require_once "WxPay.JsApiPay.php"; 6 require_once 'log.php'; 7 8 //初始化日志 9 $logHandler= new CLogFileHandler("$wx_root/logs/".date('Y-m-d').'.log'); 10 $log = Log::Init($logHandler, 15); 11 12 //打印输出数组信息 13 function printf_info($data) 14 { 15 foreach($data as $key=>$value){ 16 echo "<font color='#00ff55;'>$key</font> : $value <br/>"; 17 } 18 } 19 20 //①、获取用户openid 21 $tools = new JsApiPay(); 22 $openId = $tools->GetOpenid(); 23 24 //②、统一下单 25 $input = new WxPayUnifiedOrder(); 26 $input->SetBody("xxx充值"); 27 $input->SetAttach("xxx"); 28 $input->SetOut_trade_no($orderNo); //订单号 29 $input->SetTotal_fee($trade['fee']); //充值的金额 30 $input->SetTime_start(date("YmdHis")); 31 $input->SetTime_expire(date("YmdHis", time() + 600)); 32 $input->SetGoods_tag("xxx充值"); 33 $input->SetNotify_url("http://xxx.xxx.com/xxx/notify");//支付成功的回调地址 34 $input->SetTrade_type("JSAPI"); //支付类型 35 $input->SetOpenid($openId); 36 $order = WxPayApi::unifiedOrder($input); 37 // echo '<font color="#f00"><b>xxx支付页面</b></font><br/>'; 38 // printf_info($order); 39 $jsApiParameters = $tools->GetJsApiParameters($order); 40 41 //获取共享收货地址js函数参数 42 $editAddress = $tools->GetEditAddressParameters(); 43 44 //③、在支持成功回调通知中处理成功之后的事宜,见 notify.php 45 /** 46 * 注意: 47 * 1、当你的回调地址不可访问的时候,回调通知会失败,可以通过查询订单来确认支付是否成功 48 * 2、jsapi支付时需要填入用户openid,WxPay.JsApiPay.php中有获取openid流程 (文档可以参考微信公众平台“网页授权接口”, 49 * 参考http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html) 50 */ 51 ?> 52 53 <html> 54 <head> 55 <meta http-equiv="content-type" content="text/html;charset=utf-8"/> 56 <meta name="viewport" content="width=device-width, initial-scale=1"/> 57 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 58 <title>xxx-支付</title> 59 <style> 60 html, body { 61 margin: 0; 62 100%; 63 height: 100%; 64 } 65 .modal { 66 position: relative; 67 100%; 68 height: 100%; 69 background-color: rgba(0, 0, 0, .6); 70 } 71 .dialog { 72 position: absolute; 73 top: 50%; 74 left: 50%; 75 210px; 76 transform: translate(-50%, -50%); 77 background-color: #fff; 78 border-radius: 4px; 79 } 80 .dialog .head { 81 height: 36px; 82 line-height: 36px; 83 border-bottom: 1px solid #1aad19; 84 text-align: center; 85 font-size: 14px; 86 } 87 88 .dialog .paymoney { 89 padding: 14px; 90 91 } 92 .dialog .paymoney span { 93 display: block; 94 font-size: 14px; 95 text-align: center; 96 } 97 .dialog .paymoney b { 98 display: block; 99 font-size: 28px; 100 text-align: center; 101 } 102 .dialog .paymoney a { 103 background: #1aad19; 104 padding: 8px 0; 105 margin-top:5px; 106 display: block; 107 border-radius: 4px; 108 text-decoration: none; 109 text-align: center; 110 font-size: 18px; 111 color: #fff; 112 } 113 .dialog .btn-pay { 114 115 } 116 </style> 117 <script type="text/javascript"> 118 //调用微信JS api 支付 119 function jsApiCall() 120 { 121 WeixinJSBridge.invoke( 122 'getBrandWCPayRequest', 123 <?php echo $jsApiParameters; ?>, 124 function(res){ 125 if(res.err_msg == 'get_brand_wcpay_request:ok') 126 { 127 window.location.href = '支付成功后跳转地址'; 128 } 129 } 130 ); 131 } 132 133 function callpay() 134 { 135 if (typeof WeixinJSBridge == "undefined"){ 136 if( document.addEventListener ){ 137 document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); 138 }else if (document.attachEvent){ 139 document.attachEvent('WeixinJSBridgeReady', jsApiCall); 140 document.attachEvent('onWeixinJSBridgeReady', jsApiCall); 141 } 142 }else{ 143 jsApiCall(); 144 } 145 } 146 </script> 147 <script type="text/javascript"> 148 //获取共享地址 149 // function editAddress() 150 // { 151 // WeixinJSBridge.invoke( 152 // 'editAddress', 153 // <?php //echo $editAddress; ?>//, 154 // function(res){ 155 // var value1 = res.proviceFirstStageName; 156 // var value2 = res.addressCitySecondStageName; 157 // var value3 = res.addressCountiesThirdStageName; 158 // var value4 = res.addressDetailInfo; 159 // var tel = res.telNumber; 160 // 161 // alert(value1 + value2 + value3 + value4 + ":" + tel); 162 // } 163 // ); 164 // } 165 // 166 // window.onload = function(){ 167 // if (typeof WeixinJSBridge == "undefined"){ 168 // if( document.addEventListener ){ 169 // document.addEventListener('WeixinJSBridgeReady', editAddress, false); 170 // }else if (document.attachEvent){ 171 // document.attachEvent('WeixinJSBridgeReady', editAddress); 172 // document.attachEvent('onWeixinJSBridgeReady', editAddress); 173 // } 174 // }else{ 175 // editAddress(); 176 // } 177 // }; 178 179 </script> 180 </head> 181 <body> 182 <div class="modal"> 183 <div class="dialog"> 184 <div class="head"> 185 支付 186 </div> 187 <div class="paymoney"> 188 <span>xxx有限公司</span> 189 <b>¥<?php echo $trade['fee']; ?></b> 190 191 <a type="button" onclick="callpay()" >立即支付</a> 192 </div> 193 194 </div> 195 </div> 196 <br/> 197 </body> 198 </html>
4.在notify.php文件中写成功支付后的业务代码
1 //重写回调处理函数 2 public function NotifyProcess($data, &$msg) 3 { 4 Log::DEBUG("call back:" . json_encode($data)); 5 $notfiyOutput = array(); 6 7 if(!array_key_exists("transaction_id", $data)){ 8 $msg = "输入参数不正确"; 9 return false; 10 } 11 //查询订单,判断订单真实性 12 if(!$this->Queryorder($data["transaction_id"])){ 13 $msg = "订单查询失败"; 14 return false; 15 } 16 17 $out_trade_no = $data["out_trade_no"]; //订单号 18 19 //判断该笔订单是否在商户网站中已经做过处理 20 $trade = db('订单表')->where('orderNo',$out_trade_no)->find(); 21 //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 22 if ($data['mch_id'] == '商户号' && $data['total_fee'] == $trade['fee']) 23 { 24 db('订单表')->where('id',$trade['id'])->update(['feeStatus'=>1]); 25 26 } 27 else 28 { 29 return false; 30 } 31 32 return true; 33 }
5.编写支付接口和回调接口(有重复代码,懒得去改了)
1 /*微信客户端支付*/ 2 public function pay() 3 { 4 if(input('param.total') > 0) 5 { 6 //添加一个订单 7 当用户点击支付按钮时添加一条订单记录 8 ... 9 10 $wx_root = './Wxpay'; 11 $file = './Wxpay/example/jsapi.php'; 12 require_once $file; 13 } 14 } 15 /*H5支付*/ 16 public function h5Pay() 17 { 18 if(input('param.total') > 0) 19 { 20 //添加一个订单 21 当用户点击支付按钮时添加一条订单记录 22 ... 23 24 $wx_root = './Wxpay'; 25 $file = './Wxpay/example/mweb.php'; 26 require_once $file; 27 } 28 29 } 30 /*微信支付回调*/ 31 public function notify() 32 { 33 $wx_root = './Wxpay'; 34 $file = './Wxpay/example/notify.php'; 35 require_once $file; 36 }
页面测试出现的问题:
1.文件加载错误,所以支付接口里面已写成了绝对路径。(在控制器里面,include文件是相对于网站的根目录的);
2.出现’-1页面未注册‘的报错,查各种资料,说是支付授权目录的问题,填写规则上面已有说明;
3.Notice: Use of undefined constant CURLOP_TIMEOUT - assumed 'CURLOP_TIMEOUT 报错 ,解决如下:
(在example的JsApi.php的大概99行,修改如下:)
// curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout); curl_setopt($ch, CURLOPT_TIMEOUT, 60);
4.H5支付出现curl出错,错误码60,解决如下:
在lib--->wxpay.api.php大概538行处,修改如下代码
1 // curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE); 2 // curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验 3 if(stripos($url,"https://")!==FALSE){ 4 curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); 5 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 6 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 7 } 8 else 9 { 10 curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE); 11 curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验 12 }
把H5支付集成到SDK里面:
1.在lib---->Wxpay.data.php大概753行中,添加代码
1 /** 2 * 设置trade_type=MWEB,此参数必传。该字段用于上报支付的场景信息,针对H5支付有三种场景,请根据对应场景上报 3 * @param string $value 4 **/ 5 6 public function SetScene_info($value) 7 { 8 $this->values['scene_info'] = $value; 9 } 10 /** 11 * 判断trade_type=MWEB,此参数必传。该字段用于上报支付的场景信息,针对H5支付有三种场景,请根据对应场景上报 12 * @return true 或 false 13 **/ 14 public function IsScene_info() 15 { 16 return array_key_exists('scene_info', $this->values); 17 }
2.在example--->NativePay.php中添加代码:
1 /** 2 * 3 * 生成H5支付url,支付url有效期为2小时 4 * @param UnifiedOrderInput $input 5 */ 6 public function GetH5PayUrl($input) 7 { 8 if($input->GetTrade_type() == "MWEB") 9 { 10 $result = WxPayApi::unifiedOrder($input); 11 return $result; 12 } 13 }
3.在example中添加一个mweb.php文件:
1 <?php 2 ini_set('date.timezone','Asia/Shanghai'); 3 //error_reporting(E_ERROR); 4 require_once "$wx_root/lib/WxPay.Api.php"; 5 require_once "WxPay.NativePay.php"; 6 require_once 'log.php'; 7 /** 8 * 流程: 9 * 1、调用统一下单,取得mweb_url,通过mweb_url调起微信支付中间页 10 * 2、用户在微信支付收银台完成支付或取消支付 11 * 3、支付完成之后,微信服务器会通知支付成功 12 * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php) 13 */ 14 $input = new WxPayUnifiedOrder(); 15 $input->SetBody("xxx充值"); 16 $input->SetAttach("xxx"); 17 $input->SetOut_trade_no($orderNo); 18 $input->SetTotal_fee($trade['fee']); 19 $input->SetTime_start(date("YmdHis")); 20 $input->SetTime_expire(date("YmdHis", time() + 600)); 21 $input->SetGoods_tag("xxx充值"); 22 $input->SetNotify_url("http://xxx.com/notify"); //支付完成之后,微信服务器通知的回调地址 23 $input->SetTrade_type("MWEB"); //特别注意这里的类型 24 $input->SetScene_info('{"h5_info": {"type":"Wap","wap_url": "服务器的域名","wap_name": "xxx充值"}}'); H5支付的特定格式 25 $url = new NativePay(); 26 $result = $url->GetH5PayUrl($input); 27 $url = $result["mweb_url"].'&redirect_url=http%3A%2F%2Fxxx.com'; //后面加的&redirect_url=http%3A%2F%2Fxxx.com是支付成功后的跳转页面,$url为生成的支付链接url 28 ?> 29 <html> 30 <head> 31 <meta http-equiv="content-type" content="text/html;charset=utf-8"/> 32 <meta name="viewport" content="width=device-width, initial-scale=1"/> 33 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 34 <title>xxx-支付</title> 35 <style> 36 html, body { 37 margin: 0; 38 100%; 39 height: 100%; 40 } 41 .modal { 42 position: relative; 43 100%; 44 height: 100%; 45 background-color: rgba(0, 0, 0, .6); 46 } 47 .dialog { 48 position: absolute; 49 top: 50%; 50 left: 50%; 51 210px; 52 transform: translate(-50%, -50%); 53 background-color: #fff; 54 border-radius: 4px; 55 } 56 .dialog .head { 57 height: 36px; 58 line-height: 36px; 59 border-bottom: 1px solid #1aad19; 60 text-align: center; 61 font-size: 14px; 62 } 63 64 .dialog .paymoney { 65 padding: 14px; 66 67 } 68 .dialog .paymoney span { 69 display: block; 70 font-size: 14px; 71 text-align: center; 72 } 73 .dialog .paymoney b { 74 display: block; 75 font-size: 28px; 76 text-align: center; 77 } 78 .dialog .paymoney a { 79 background: #1aad19; 80 padding: 8px 0; 81 margin-top:5px; 82 display: block; 83 border-radius: 4px; 84 text-decoration: none; 85 text-align: center; 86 font-size: 18px; 87 color: #fff; 88 } 89 .dialog .btn-pay { 90 91 } 92 </style> 93 </head> 94 <body> 95 <div class="modal"> 96 <div class="dialog"> 97 <div class="head"> 98 支付 99 </div> 100 <div class="paymoney"> 101 <span>xxx有限公司</span> 102 <b>¥<?php echo $trade['fee']; ?></b> 103 <a type="button" href="<?php echo $url; ?>">立即支付</a> 104 </div> 105 106 </div> 107 </div> 108 </body> 109 </html>
关于H5支付的一个坑,生成的支付链接不能在控制器中直接跳转,试过好多次都报‘参数格式错误,请联系商家的字样’,后来把链接写到页面的A标签就好了。
顺便在网上找到的H5报错的资料,http://blog.csdn.net/paymm/article/details/73188596。
ps:在网上看到了一个封装好的H5支付的方法,亲测有用:
1 <?php 2 /** 3 *非微信浏览器 调用微信h5支付 4 */ 5 6 namespace wstmartwapcontroller; 7 8 use thinkController; 9 use thinkLoader; 10 use thinkRequest; 11 use thinkUrl; 12 use thinkConfig; 13 use thinkPage; 14 15 class Cc extends Base 16 { 17 /** 18 * @return array 下单方法 19 */ 20 public function wxpaymoney(Request $request) 21 { 22 $param = $request->param(); 23 if (!empty($param)) 24 { 25 $param = json_decode(json_encode(simplexml_load_string($param, 'SimpleXMLElement', LIBXML_NOCDATA)), true); 26 echo '-------'; 27 p($param); 28 echo '*******'; 29 } 30 31 $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; //下单地址 32 $appid = 'xxx';//公众号appid 33 $appsecret = 'xxx'; 34 $mch_id = 'xxx';//商户平台id 35 $nonce_str = 'qyzf' . rand(100000, 999999);//随机数 36 $out_trade_no = 'wap' . date('YmdHis') . rand(100000, 999999); 37 $ip = $this->getClientIp(); 38 $scene_info = '{"h5_info": {"type":"Wap","app_name": "project info","package_name": "wap订单微信支付"}}'; 39 // $appidInfo=$this->getTokens($appid,$appsecret); 40 // echo '======='; 41 // p($appidInfo); 42 // echo '*******';die; 43 // $openid=$appidInfo['openid']; 44 $total_fee = 1; 45 $trade_type = 'MWEB'; 46 $attach = 'wap支付测试'; 47 $body = 'H5支付测试'; 48 $notify_url = 'http://paysdk.weixin.qq.com/example/notify.php'; 49 $arr = [ 50 'appid' => $appid, 'mch_id' => $mch_id, 'nonce_str' => $nonce_str, 'out_trade_no' => $out_trade_no, 'spbill_create_ip' => $ip, 'scene_info' => $scene_info, // 'openid'=>$openid, 51 'total_fee' => $total_fee, 'trade_type' => $trade_type, 'attach' => $attach, 'body' => $body, 'notify_url' => $notify_url 52 ]; 53 $sign = $this->getSign($arr); 54 //<openid>'.$openid.'</openid> 55 $data = '<xml> 56 <appid>' . $appid . '</appid> 57 <attach>' . $attach . '</attach> 58 <body>' . $body . '</body> 59 <mch_id>' . $mch_id . '</mch_id> 60 <nonce_str>' . $nonce_str . '</nonce_str> 61 <notify_url>' . $notify_url . '</notify_url> 62 <out_trade_no>' . $out_trade_no . '</out_trade_no> 63 <spbill_create_ip>' . $ip . '</spbill_create_ip> 64 <total_fee>' . $total_fee . '</total_fee> 65 <trade_type>' . $trade_type . '</trade_type> 66 <scene_info>' . $scene_info . '</scene_info> 67 <sign>' . $sign . '</sign> 68 </xml>'; 69 $result = $this->https_request($url, $data); 70 echo '===================='; 71 var_dump($result); 72 echo '*******************'; 73 //禁止引用外部xml实体 74 libxml_disable_entity_loader(true); 75 $result_info = json_decode(json_encode(simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA)), true); 76 p($result_info); 77 echo '<a href="' . $result_info['mweb_url'] . '">测试微信支付</a>'; 78 die; 79 } 80 81 /** 82 *curl请求 83 */ 84 private function https_request($url, $data = null) 85 { 86 p($data); 87 $curl = curl_init(); 88 curl_setopt($curl, CURLOPT_URL, $url); 89 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 90 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 91 if (!empty ($data)) 92 { 93 curl_setopt($curl, CURLOPT_POST, 1); 94 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); 95 } 96 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 97 $output = curl_exec($curl); 98 curl_close($curl); 99 100 return $output; 101 } 102 103 /** 104 * @return 获取ip 105 */ 106 private function getClientIp() 107 { 108 $cip = 'unknown'; 109 if ($_SERVER['REMOTE_ADDR']) 110 { 111 $cip = $_SERVER['REMOTE_ADDR']; 112 } 113 elseif (getenv($_SERVER['REMOTE_ADDR'])) 114 { 115 $cip = getenv($_SERVER['REMOTE_ADDR']); 116 } 117 118 return $cip; 119 } 120 121 /** 122 * @return 异步通知 123 */ 124 public function wxnotify(Request $request) 125 { 126 Loader::import('payment.wxwap.PayNotifyCallBacks'); 127 $notify = new PayNotifyCallBacks(); 128 $notify->Handle(false); 129 die; 130 } 131 132 /** 133 * @param Request 134 */ 135 public function wxcallback(Request $request) 136 { 137 $data = $request->param(); 138 file_put_contents('./testwx1.txt', '888888888888888' . $data['orderid'] . '-----' . $data['transaction_id'] . '******'); 139 140 } 141 142 /** 143 * 作用:格式化参数,签名过程需要使用 144 */ 145 public function formatBizQueryParaMap($paraMap, $urlencode) 146 { 147 // var_dump($paraMap);//die; 148 $buff = ""; 149 ksort($paraMap); 150 foreach ($paraMap as $k => $v) 151 { 152 if ($urlencode) 153 { 154 $v = urlencode($v); 155 } 156 //$buff .= strtolower($k) . "=" . $v . "&"; 157 $buff .= $k . "=" . $v . "&"; 158 } 159 $reqPar = ''; 160 if (strlen($buff) > 0) 161 { 162 $reqPar = substr($buff, 0, strlen($buff) - 1); 163 } 164 p($reqPar);//die; 165 166 return $reqPar; 167 } 168 169 /** 170 * 作用:生成签名 171 */ 172 public function getSign($Obj) 173 { 174 p($Obj);//die; 175 foreach ($Obj as $k => $v) 176 { 177 $Parameters[$k] = $v; 178 } 179 //签名步骤一:按字典序排序参数 180 ksort($Parameters); 181 $String = $this->formatBizQueryParaMap($Parameters, false); 182 //echo '【string1】'.$String.'</br>'; 183 //签名步骤二:在string后加入KEY 5a02bd8ecxxxxxxxxxxxxc1aae7d199 这里的秘钥是 商户平台设置的一定要改不然报签名错误 184 $String = $String . "&key=ShenDai8787com1313ShenDai027SDWL"; 185 //echo "【string2】".$String."</br>"; 186 //签名步骤三:MD5加密 187 $String = md5($String); 188 //echo "【string3】 ".$String."</br>"; 189 //签名步骤四:所有字符转为大写 190 $result_ = strtoupper($String); 191 192 //echo "【result】 ".$result_."</br>"; 193 return $result_; 194 } 195 196 197 private function httpGet($url) 198 { 199 $curl = curl_init(); 200 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 201 curl_setopt($curl, CURLOPT_TIMEOUT, 500); 202 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 203 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); 204 curl_setopt($curl, CURLOPT_URL, $url); 205 206 $res = curl_exec($curl); 207 curl_close($curl); 208 209 return $res; 210 } 211 }