產品開會提出了這樣的需求:一個二維碼能夠微信支付也能夠支付寶支付javascript
通過本身的鑽研以及詢問技術高人(本人代碼通常般)和網上搜索 最終實現其功能 我用微信jsapi 和 支付寶網頁支付php
其實並不怎麼難:css
1.微信jsapi支付流程(微信官方文檔:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1)html
2.支付寶支付流程java
好了廢話很少說 開始開發 代碼上(Tp5開發)jquery
首先 須要生成一個二維碼這個想必你們都會吧!!! phpqrcode(下載地址:https://sourceforge.net/projects/phpqrcode/ )ajax
1 require_once ROOT_PATH.'/phpqrcode/phpqrcode.php'; 2 $value='http://'.$_SERVER['HTTP_HOST'].'/admin.php/pay/wx_zfb; //二維碼連接 (這個是重中之重!!!) 3 $errorCorrectionLevel = 'H';//容錯級別 4 $matrixPointSize = 6;//生成圖片大小 5 //生成二維碼圖片 6 QRcode::png($value, 'code/1.png', $errorCorrectionLevel, $matrixPointSize, 2); 7 $logo = 'code/kunchuan.png';//準備好的logo圖片 8 $QR = 'code/1.png';//已經生成的原始二維碼圖 9 if ($logo !== FALSE) { 10 $QR = imagecreatefromstring(file_get_contents($QR)); 11 $logo = imagecreatefromstring(file_get_contents($logo)); 12 /* $QR = imagecreatefrompng($QR); 13 $logo = imagecreatefrompng($logo);*/ 14 if (imageistruecolor($logo)) 15 { 16 imagetruecolortopalette($logo, false, 65535);//添加這行代碼來解決顏色失真問題 17 } 18 19 $QR_width = imagesx($QR);//二維碼圖片寬度 20 $QR_height = imagesy($QR);//二維碼圖片高度 21 $logo_width = imagesx($logo);//logo圖片寬度 22 $logo_height = imagesy($logo);//logo圖片高度 23 $logo_qr_width = $QR_width / 5; 24 $scale = $logo_width/$logo_qr_width; 25 $logo_qr_height = $logo_height/$scale; 26 $from_width = ($QR_width - $logo_qr_width) / 2; 27 //從新組合圖片並調整大小 28 imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, 29 $logo_qr_height, $logo_width, $logo_height); 30 } 31 32 $lujing = 'code/merge1'.png'; 33 34 //輸出圖片 35 imagepng($QR,$lujing); 36 return '<img src="http://'.$_SERVER['HTTP_HOST'].'/'.$lujing.'" alt="使用微信或者支付寶掃描支付">';
ok咱們就生成一個二維碼 由於我的隱私 我就生成了一個百度的二維碼 sql
經過掃描二維碼 咱們跳轉到 wx_zfb方法:數據庫
public function wx_zfb() { //根據本身的需求 連接上邊有參數就接值 沒有就不作判斷 // if($this->request->isGet()) // { //在PHP中HTTP_USER_AGENT是用來獲取用戶的相關信息的,包括用戶使用的瀏覽器,操做系統等信息, $http_user_agent = $_SERVER['HTTP_USER_AGENT']; if (strpos($http_user_agent, 'MicroMessenger'))
{
$url="code」;//處理微信支付的方法 header("location:{$url}"); exit; }elseif (strpos($http_user_agent, 'AlipayClient')) { //支付寶連接
$url="aliyun」;//處理微信支付的方法
header("location:{$url}"); exit
}else{ $this->assign('error_data','請使用微信或者支付寶掃碼哦!'); return $this->view->fetch('pay/error'); } // }else{ // $this->assign('error_data','暫時沒有哦'); // return $this->view->fetch('pay/error'); //} }
接下來精彩的代碼即將上線(微信jsapi支付)json
damo下載:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
首先咱們要了解微信jsapi的開發流程
好了這些大家就瞭解一下就能夠了
public function code() { $appid = '*******';//微信的appid $appKey = '******';//APPSECRET:公衆賬號secert(僅JSAPI支付的時候須要配置, 登陸公衆平臺,進入開發者中心可設置), 請妥善保管, 避免密鑰泄露獲取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN $mchid='*******';//商戶平臺的id $apiKey='*******';//KEY:商戶支付密鑰,參考開戶郵件設置(必須配置,登陸商戶平臺自行設置), 請妥善保管, 避免密鑰泄露設置地址:https://pay.weixin.qq.com/index.php/account/api_cert $wxPay = new WxpayService($mchid,$appid,$appKey,$apiKey); $openid = $wxPay->GetOpenid(); if($openid){ Session::set("openid", $openid); }else{ $openid=session('openid'); } //公衆號中的話能夠受權-獲取用戶信息 // $wxPays=new WxPayUser($appid,$appKey); // $data = $wxPays->GetOpenid(); // $user = $WxPayUser->getUserInfo($data['openid'],$data['access_token']); $this->assign('openid',$openid); $this->assign('ip_user',$ip_user); return $this->view->fetch(); }
WxpayService.php
<?php namespace addons\epay\library; use fast\Http; class WxpayService { protected $mchid; protected $appid; protected $appKey; protected $apiKey; public $data = null; public function __construct($mchid, $appid, $appKey,$key) { $this->mchid = $mchid; //https://pay.weixin.qq.com 產品中心-開發配置-商戶號 $this->appid = $appid; //微信支付申請對應的公衆號的APPID $this->appKey = $appKey; //微信支付申請對應的公衆號的APP Key $this->apiKey = $key; //https://pay.weixin.qq.com 賬戶設置-安全設置-API安全-API密鑰-設置API密鑰 } /** * 經過跳轉獲取用戶的openid,跳轉流程以下: * 一、設置本身須要調回的url及其其餘參數,跳轉到微信服務器https://open.weixin.qq.com/connect/oauth2/authorize * 二、微信服務處理完成以後會跳轉回用戶redirect_uri地址,此時會帶上一些參數,如:code * @return 用戶的openid */ public function GetOpenid() { //經過code得到openid if (!isset($_GET['code'])){ //觸發微信返回code碼 $_SERVER['HTTPS']=isset($_SERVER['HTTPS'])?$_SERVER['HTTPS']:''; $scheme = $_SERVER['HTTPS']=='on' ? 'https://' : 'http://'; $uri = $_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING']; if($_SERVER['REQUEST_URI']) $uri = $_SERVER['REQUEST_URI']; $baseUrl = urlencode($scheme.$_SERVER['HTTP_HOST'].$uri); $url = $this->__CreateOauthUrlForCode($baseUrl); Header("Location: $url"); exit(); } else { //獲取code碼,以獲取openid $code = $_GET['code']; $openid = $this->getOpenidFromMp($code); return $openid; } } /** * 經過code從工做平臺獲取openid機器access_token * @param string $code 微信跳轉回來帶上的code * @return openid */ public function GetOpenidFromMp($code) { $url = $this->__CreateOauthUrlForOpenid($code); $res = self::curlGet($url); //取出openid $data = json_decode($res,true); $this->data = $data; $data['openid']=isset($data['openid'])?$data['openid']:''; $openid = $data['openid']; return $openid; } /** * 構造獲取open和access_toke的url地址 * @param string $code,微信跳轉帶回的code * @return 請求的url */ private function __CreateOauthUrlForOpenid($code) { $urlObj["appid"] = $this->appid; $urlObj["secret"] = $this->appKey; $urlObj["code"] = $code; $urlObj["grant_type"] = "authorization_code"; $bizString = $this->ToUrlParams($urlObj); return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString; } /** * 構造獲取code的url鏈接 * @param string $redirectUrl 微信服務器回跳的url,須要url編碼 * @return 返回構造好的url */ private function __CreateOauthUrlForCode($redirectUrl) { $urlObj["appid"] = $this->appid; $urlObj["redirect_uri"] = "$redirectUrl"; $urlObj["response_type"] = "code"; $urlObj["scope"] = "snsapi_base"; $urlObj["state"] = "STATE"."#wechat_redirect"; $bizString = $this->ToUrlParams($urlObj); return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString; } /** * 拼接簽名字符串 * @param array $urlObj * @return 返回已經拼接好的字符串 */ private function ToUrlParams($urlObj) { $buff = ""; foreach ($urlObj as $k => $v) { if($k != "sign") $buff .= $k . "=" . $v . "&"; } $buff = trim($buff, "&"); return $buff; } /** * 統一下單 * @param string $openid 調用【網頁受權獲取用戶信息】接口獲取到用戶在該公衆號下的Openid * @param float $totalFee 收款總費用 單位元 * @param string $outTradeNo 惟一的訂單號 * @param string $orderName 訂單名稱 * @param string $notifyUrl 支付結果通知url 不要有問號 * @param string $timestamp 支付時間 * @return string */ public function createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp) { $config = array( 'mch_id' => $this->mchid, 'appid' => $this->appid, 'key' => $this->apiKey, ); // $orderName = iconv('GBK','UTF-8',$orderName); $unified = array( 'appid' => $config['appid'], 'attach' => 'pay', //商家數據包,原樣返回,若是填寫中文,請注意轉換爲utf-8 'body' => $orderName, 'mch_id' => $config['mch_id'], 'nonce_str' => self::createNonceStr(), 'notify_url' => $notifyUrl, 'openid' => $openid, //rade_type=JSAPI,此參數必傳 'out_trade_no' => $outTradeNo, 'spbill_create_ip' => '127.0.0.1', 'total_fee' => floatval($totalFee) * 100, //單位 轉爲分 'trade_type' => 'JSAPI', ); $unified['sign'] = self::getSign($unified, $config['key']); $responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified)); //禁止引用外部xml實體 libxml_disable_entity_loader(true); $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA); if ($unifiedOrder === false) { die('parse xml error'); } if ($unifiedOrder->return_code != 'SUCCESS') { die($unifiedOrder->return_msg); } if ($unifiedOrder->result_code != 'SUCCESS') { die($unifiedOrder->err_code); } $arr = array( "appId" => $config['appid'], "timeStamp" => "$timestamp", //這裏是字符串的時間戳,不是int,因此需加引號 "nonceStr" => self::createNonceStr(), "package" => "prepay_id=" . $unifiedOrder->prepay_id, "signType" => 'MD5', ); $arr['paySign'] = self::getSign($arr, $config['key']); return $arr; } public static function curlGet($url = '', $options = array()) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); if (!empty($options)) { curl_setopt_array($ch, $options); } //https請求 不驗證證書和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function curlPost($url = '', $postData = '', $options = array()) { if (is_array($postData)) { $postData = http_build_query($postData); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //設置cURL容許執行的最長秒數 if (!empty($options)) { curl_setopt_array($ch, $options); } //https請求 不驗證證書和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function createNonceStr($length = 16) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } public static function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; } else $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"; } $xml .= "</xml>"; return $xml; } public function notify() { $config = array( 'mch_id' => $this->mchid, 'appid' => $this->appid, 'key' => $this->apiKey, ); $postStr = file_get_contents('php://input'); //禁止引用外部xml實體 libxml_disable_entity_loader(true); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $result_1 = json_encode(simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA)); file_put_contents("1.txt",$result_1, FILE_APPEND); $arr = (array)$postObj; return $arr; } public static function getSign($params, $key) { ksort($params, SORT_STRING); $unSignParaString = self::formatQueryParaMap($params, false); $signStr = strtoupper(md5($unSignParaString . "&key=" . $key)); return $signStr; } protected static function formatQueryParaMap($paraMap, $urlEncode = false) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if (null != $v && "null" != $v) { if ($urlEncode) { $v = urlencode($v); } $buff .= $k . "=" . $v . "&"; } } $reqPar = ''; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff) - 1); } return $reqPar; } }
code.html
<html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <title>微信支付</title> <style> * {margin:0;padding:0;} body {font-size:12px;font-family:"Microsoft YaHei","微軟雅黑",sans-serif;color:#333;background-color:#f7f7f7;width:100%;} .clearfix:after { content: "."; display: block; font-size: 0; height: 0; clear: both; visibility: hidden; } .clearfix { display: inline-table;} *html .clearfix { height: 1%; } .clearfix { display: block; } *+html .clearfix { min-height: 1%; } ul,li{ list-style:none;border:0; box-sizing:border-box; } .main {margin:0 auto;width:100%;max-width:750px;min-width:320px;background-color:#f7f7f7;} .btnpay {margin:0.8rem auto 0;width:100%;} .btnpay span {display:block;margin:0 auto;width:6.74rem;height:0.8rem;line-height:0.8rem;background-color:#80D983;border-radius:0.1rem;color:#fff;font-size:0.34rem;letter-spacing:0.06rem;text-align:center;} .xinxi{ margin:0 auto; width: 90%; line-height: 46px; display: flex; flex-direction: row; font-size: 0.32rem; border-bottom: #ccc solid 1px; color: #333;} .moneychose{ margin:0 auto; width: 90%;} .moneychose p {font-size:16px;color:#8D8D8F; line-height: 42px;} .moneychose .list{ display: flex; } .moneychose .list li{ width: 45%; margin-right:5%; border: #ccc solid 1px; background-color: #fff; border-radius:3px; text-align: center; padding:10px 0;} .moneychose .list li span{ font-size: 0.32rem;display: block;} .moneychose .list li.active{border: #e56d33 solid 1px; color:#e56d33;} .tipbox{ margin:10px auto 0; width: 90%;} .tipbox a{ text-decoration:none; color: #999; font-size:0.28rem;} .tkbox .mask,.tkknowbox .mask{margin:0 auto;width:100%;height:100%;position:fixed;left:0px;top:0px;opacity:0.85;z-index:9998;background-color:rgb(0,0,0);} .tkbox .mymodel,.tkknowbox .mytk{width:6.2rem; padding: 0.25rem 0 0.25rem 0; position:fixed;z-index:10000;display:block;border-radius:5px;background-color:#FFFFFF;} .mymodel .inputblock{ margin:0 auto 0.3rem; width:5.6rem;} .mymodel .inputs {width:100%;height:0.8rem;line-height:0.8rem;font-size:0.32rem;border:1px solid #CFCFCF;text-indent:0.2rem;outline:none;white-space:pre;overflow-x:scroll;} .frminput {margin:0.3rem auto 0;display:flex;flex-direction:row;} .frminput input {margin-left:0.3rem;width:2.4rem;height:0.8rem;line-height:0.8rem;font-size:0.30rem;padding-left:0.2rem;border:1px solid #CFCFCF; outline:none; } .frminput .sendCodeBtn {margin-left:0.3rem;width:2rem;height:0.8rem;line-height:0.8rem;background-color:#e56d33;border-radius:5upx;color:#fff;text-align:center;font-size:0.26rem;} .btnconfrm {margin:0.5rem auto 0;width:5rem;} .btnconfrm span {display:block;margin:0 auto;width:100%;height:0.8rem;line-height:0.8rem;background-color:#80D983;border-radius:0.1rem;color:#fff;font-size:0.34rem;letter-spacing:0.06rem;text-align:center;} .topcar{ width: 100%; display: flex; flex-direction: row; margin-bottom: 0.15rem;} .topcar .cartip{ font-size: 0.32rem;width:1.1rem;height:0.6rem; line-height:0.6rem; padding-left: 0.3rem;} .che_tit{ text-align:center; padding:20px;} .ul_pro{ background-color:#CED3D9; text-align:center; padding:4px 2px; font-size:0.32rem;} .ul_pro li{ float:left; width:11.11%; padding:2px;box-sizing: border-box;} .ul_pro .li_close{ float:right; width:22.22%;} .ul_pro .li_close span{ background-color:#ACB3BB;} .ul_pro .li_clean{ float:right; width:22.22%;} .ul_pro li span{ display:block; background-color:#fff; border-radius:4px;line-height:32px; padding-top:2px; } .ul_pro li span:active{ background-color:#4DA9F2; color:#fff;} .ul_input{ width:4.6rem; margin:0 auto; } .ul_input li{ float:left; width:14%; padding:0.02rem;text-align:center; } .ul_input li span{ display:block; background-color:#fff; border:1px solid #ccc; border-radius:4px; width:0.5rem; margin:0 auto; height:0.5rem; line-height:0.5rem;font-size: 0.36rem;} .ul_keybord{ background-color:#CED3D9; text-align:center; padding:4px 2px; font-size:14px;} .ul_keybord li{ float:left; width:10%; padding:2px;box-sizing: border-box;} .ul_keybord .ikey20{ margin-left:5%;} .ul_keybord .li_w{ width:11.11%; } .ul_keybord .li_close{ float:right; width:22.22%;} .ul_keybord .li_close span{ background-color:#ACB3BB;} .ul_keybord .li_clean{ float:right; width:22.22%;} .ul_keybord li span{ display:block; background-color:#fff; border-radius:4px; box-shadow: 2px 2px 2px #888888;line-height:32px; padding-top:2px; } .ul_keybord li span:active{ background-color:#4DA9F2; color:#fff;} .tkknowbox .closetk{ width: 0.58rem; height: 0.58rem; position: absolute; top:-39px;right:-9px;z-index: 10001;} .tkknowbox .closetk .icon{width: 0.58rem; height: 0.58rem;} .tkknowbox .knowmain{ padding:5px 5% 0; font-size: 0.28rem; color: #666; line-height:24px;} .tkknowbox .knowmain .tit{ font-size: 0.30rem;} </style> <script type="text/javascript"> //調用微信JS api 支付 function jsApiCall(msg) { WeixinJSBridge.invoke( 'getBrandWCPayRequest', msg, function (res) { WeixinJSBridge.log(res.err_msg); if (res.err_msg == 'get_brand_wcpay_request:ok') { window.location.href="www.baidu.com"; // alert('支付成功!'); } else if(res.err_msg=='get_brand_wcpay_request:cancel') { layer.msg('支付取消'); }else{ layer.msg('支付失敗'); // alert('支付失敗:' + res.err_code + res.err_desc + res.err_msg); } } ); } function callpay(msg) { if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } } else { jsApiCall(msg); } } </script> </head> <body> <section class="main"> <section class="xinxi"> <span>手機號:</span> <span id="phones"></span> </section> <section class="moneychose"> <p>選擇套餐</p> <ul class="list"> <li class="active" data-type='1'><span>12次洗車次卡</span><span>300元</span></li> <li data-type='2'><span>25次洗車次卡</span><span>588元</span></li> </ul> <input type="hidden" name="openid" id='openid' value="<?php echo $openid;?>"> <input type="hidden" name="car_num_id" id='car_num_id' value=""> </section> <section class="tipbox" id="tipbox"><span>《支付須知》</span></section> <div class="btnpay" onclick="telypay()"><span>當即支付</span></div> </section> <!-- 彈框開始 --> <section class="tkbox" > <section class="mask"></section> <section class="mymodel"> <section class="tipinput"> <section class="topcar"> <div class="cartip">車牌號:</div> <div class="car_input"> <ul class="clearfix ul_input"> <li class="input_pro"><span></span></li> <li class="input_pp input_zim"><span></span></li> <li class="input_pp"><span></span></li> <li class="input_pp"><span></span></li> <li class="input_pp"><span></span></li> <li class="input_pp"><span></span></li> <li class="input_pp"><span></span></li> </ul> </div> </section> <div class="inputblock"><input id="phone" type="number" maxlength="11" autocomplete="off" class="inputs" placeholder="請輸入手機號" onfocus="closePro()" ></div> <section class="frminput"> <input type="number" id="code" class="inputcode" onfocus="closePro()" placeholder="請輸入驗證碼" /> <section class="sendCodeBtn" datamark="0" id="sendCodeBtn">發送驗證碼</section> </section> </section> <section class="btnconfrm" id="btnconfrm"><span>肯定</span></section> </section> </section> <!-- 須知彈窗 --> <section class="tkknowbox" style="display:none;"> <section class="mask"></section> <section class="mytk"> <section class="closetk" onclick="$('.tkknowbox').hide();" ><img src="/code/iconclose.png" alt="關閉須知彈框" class="icon" /></section> <section class="knowmain"> <p><span class="tit" >1)次卡:</span><br> <span style="font-weight: bold;">轎車</span>:300元套餐(內含12次洗車服務);588元套餐(內含25次洗車服務且贈送一次打蠟)<br> <span style="font-weight: bold;">SUV</span>: 350元套餐(內含12次洗車服務);688元套餐(內含25次洗車服務且贈送一次打蠟)<br> </p> <p><span class="tit" >2)次卡升級爲年卡:</span><br>將剩餘次卡數摺合爲錢數,並支付所差金額;便可升級爲年卡且次卡剩餘次數清空;<br></p> <p>3)其餘問題,請聯繫客服熱線 ********** 諮詢</p> </section> </section> </section> <!-- 彈框結束 --> <script type="text/javascript" src="/assets/js/jquery.min.js"></script> <script src="/assets/js/shop.js" ></script> <script type="text/javascript"> var isClick = true; function telypay() { if(!isClick){ return false; } // 這裏能夠寫你onclick事件須要獲取傳到後臺的值 var openid = $('#openid').val(); var price; $(".list li").each(function(){ if($(this).hasClass('active')){ console.log($(this).attr("data-type")); price = $(this).attr("data-type"); } }); $.ajax({ type: 'post', url: "/admin.php/pay/sub_pay", data: { 'price': price, 'openid': openid}, dataType: 'json', success: function (msg) { isClick = true; callpay(msg); } }); } $(function () { //隱藏彈框 var is_user=<?php echo $is_user;?>; var car_num_id=<?php echo $car_num_id;?>; var phone=<?php echo $phone;?>; if(is_user - 1 == 0){ $("#car_num_id").val(car_num_id); $('#phones').text(phone); $(".tkbox").hide(); } var W = $('.mymodel').width(); var H = $('.mymodel').height(); var winWid = $(window).width() / 2 - W / 2; var winHig = $(window).height() / 2 - H / 2; $(".mymodel").css({ 'left': winWid, 'top': winHig }); $(".list li").click(function(){ $(".list li").removeClass('active'); $(this).addClass('active'); console.log($(this).attr("data-type")); }); //發送驗證碼 $("#sendCodeBtn").click(function(){ var datamark = $(this).attr('datamark'); //console.log(datamark); if(datamark - 1 == 0){ return false; } var phone = $("#phone").val(); if(!phone){ layer.msg('請填寫您的手機號'); return false; } var myreg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/; if (!myreg.test(phone)) { layer.msg('請填寫正確的手機號'); return false; } $.ajax({ type: 'post', url: "/admin.php/pay/send_code", data: { 'phone': phone}, dataType: 'json', success: function (msg) { if(msg.code < 0){ layer.msg(msg.msg); }else if(msg.code > 0){ settime($("#sendCodeBtn")); layer.msg('發送驗證碼成功'); } return false; } }); //settime($("#sendCodeBtn")); //此處請求接口,成功後下面 }); var countdown = 60; function settime(obj) { if (countdown == 0) { $(obj).attr("datamark", "0"); $(obj).html("獲取驗證碼"); countdown = 60; return; } else { $(obj).attr("datamark", "1"); $(obj).html(countdown + "s後從新獲取"); countdown--; } setTimeout(function () { settime(obj) }, 1000); } //肯定按鈕點擊 $("#btnconfrm").click(function () { var carnum = $(".car_input").attr("data-pai"); if(carnum == undefined){ layer.msg('請填寫您的車牌號'); return false; } carnum = carnum.replace(/[\r\n]/g,"").replace(/\s*/g,""); // console.log(carnum); if(carnum.length - 7 < 0){ layer.msg('請填寫您的車牌號'); return false; } var phone = $("#phone").val(); var code = $("#code").val(); if(!phone){ layer.msg('請填寫您的手機號'); return false; } var myreg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/; if (!myreg.test(phone)) { layer.msg('請填寫正確的手機號'); return false; } if(!code){ layer.msg('請填寫您的驗證碼'); return false; } $('#pro').remove(); $.ajax({ type: 'post', url: "/admin.php/pay/car_num", data: { 'carnum': carnum, 'phone': phone, 'code': code}, dataType: 'json', success: function (message) { msgs=JSON.parse(message); if(msgs.status=='0'){ layer.msg(msgs.msg); return false; }else{ $("#car_num_id").val(msgs.id); $('#phones').text(msgs.phone); $(".tkbox").hide(); layer.msg('提交成功'); // console.log(msg.id +"手機號"+"驗證碼"+msg.phone); return true; } } }); //console.log(carnum +"手機號"+phone+"驗證碼"+code); return false; }); $("#tipbox").click(function(){ $(".tkknowbox").show(); var W1 = $('.mytk').width(); var H1 = $('.mytk').height(); var winWid1 = $(window).width() / 2 - W1 / 2; var winHig1 = $(window).height() / 2 - H1 / 2; $(".mytk").css({ 'left': winWid1, 'top': winHig1 }); }); }); (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function () { var clientWidth = docEl.clientWidth; if (!clientWidth) return; if (clientWidth >= 750) { docEl.style.fontSize = '100px'; } else { docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'; } }; if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener('DOMContentLoaded', recalc, false); })(document, window); </script> </body> </html>
(我的的需求 大家能夠刪除手機短信的驗證 send_code 和car_num 的入庫)
大家只用sub_pay方法
public function sub_pay() { $openid=$this->request->post('openid'); $price=$this->request->post('price'); $price=0.01;//測試金額 // $outTradeNo = uniqid(); //你本身的商品訂單號 //今日日期+時間戳後五位+毫秒從第三位到第八位+ $outTradeNo = date('Ymd').substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(1000, 9999)); $orderName = '支付測試'; //訂單標題 $notifyUrl = 'http://'.$_SERVER['HTTP_HOST'].'/admin.php/Pay/callback'; //付款成功後的回調地址(不要有問號) $payTime = time(); //提交時間 $order_price=$price*100; //測試 $sql="INSERT INTO order(`pay_type`,`order_status`,`order_num`,`shop_id`,`pay_status`,`order_price`,`create_time`) VALUES('2','0','$outTradeNo','$ip_user','0','$order_price','$payTime')"; Db::execute($sql); //處理一下數據
$conf = $this->payconfig($orderName,$openid,$outTradeNo,$order_price,$orderName,$notifyUrl); $jsApiObj["appId"] =$conf['appid']; $timeStamp = time(); $jsApiObj["timeStamp"] = "$timeStamp"; $jsApiObj["nonceStr"] = $this->createNoncestr(); $jsApiObj["package"] ="prepay_id=".$conf['prepay_id']; $jsApiObj["signType"] = "MD5"; $jsApiObj["paySign"] = $this->MakeSign($jsApiObj,'KunLunqifuWangRUIHua162588080619'); echo json_encode($jsApiObj); }
payconfig方法
#微信JS支付參數獲取-注意下面是支付方法能夠不須要管!!!# protected function payconfig($title,$openid,$no, $fee, $body,$notifyUrl) { $config = array( 'mch_id' => '********', 'appid' => '*******', 'key' => '**************', ); $url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; $data['appid'] =$config['appid']; $data['mch_id'] =$config['mch_id']; //商戶號 $data['device_info'] ='WEB'; $data['body'] = $body; $data['out_trade_no'] =$no; //訂單號 $data['total_fee'] = $fee; //金額 $data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"]; $data['notify_url'] =$notifyUrl; $data['trade_type'] = 'JSAPI'; $data['openid'] = $openid; //獲取openid $data['nonce_str'] = $this->createNoncestr(); $data['sign'] = $this->MakeSign($data,$config['key']); //print_r($data); $xml = $this->ToXml($data); $curl = curl_init(); // 啓動一個CURL會話 curl_setopt($curl, CURLOPT_URL, $url); // 要訪問的地址 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); //設置header // curl_setopt($curl, CURLOPT_HEADER, FALSE); //要求結果爲字符串且輸出到屏幕上 curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($curl, CURLOPT_POST, TRUE); //發送一個常規的Post請求 curl_setopt($curl, CURLOPT_POSTFIELDS, $xml); // Post提交的數據包 curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 設置超時限制防止死循環 $tmpInfo = curl_exec($curl); // 執行操做 curl_close($curl); //關閉CURL會話 $arr = $this->FromXml($tmpInfo); return $arr; }
/**
* 異步回調通知
* 說明:須要在支付文件中(如native.php或者jsapi.php)的填寫回調地址。例如:http://www.xxx.com/wx/notify.php
* 付款成功後,微信服務器會將付款結果通知到該頁面 個人是 callback方法
*/
public function callback() { $xml = file_get_contents("php://input"); $log = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); $log_1=json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)); file_put_contents('1.txt',$log_1,FILE_APPEND);//只有返回參數寫進文件中才能夠打印 切記切記切記
3.1根據返回的信息在生成簽名防止數據泄漏致使出現「假通知」,形成資金損失。
$apiKey="*******";
$newSign = $this->verifySign($log,$apiKey);
//判斷數據庫金額和支付金額是否一致 判斷簽名是否一致
if (($yorder_data['order_price']) == (int)$trade['total_fee']&& $newSign == $trade["sign"] ) //
{
直接寫你的操做數據庫邏輯就ok了
}
//必須加這個!!!!
$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
echo $str; } /* $log=array ( 'appid' => 'wx3c3f93ddce1e7845', 'bank_type' => 'OTHERS', 'cash_fee' => '1', 'device_info' => 'WEB', 'fee_type' => 'CNY', 'is_subscribe' => 'Y', 'mch_id' => '1602777325', 'nonce_str' => 'oz5dzyotw0qyz2a8x2elenbki268cyt5', 'openid' => 'os2J15vmqW1KXHLZAL4IwBtP7hL8', 'out_trade_no' => '2021070824865563665180', 'result_code' => 'SUCCESS', 'return_code' => 'SUCCESS', 'sign' => '02B66C17D8A31D0F943448979357DDEB', 'time_end' => '20210708141109', 'total_fee' => '1', 'trade_type' => 'JSAPI', 'transaction_id' => '4200001181202107085997485076', );*/
相關的方法
/** * 做用:產生隨機字符串,不長於32位 */ public function createNoncestr($length = 32) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } /** * 做用:產生隨機字符串,不長於32位 */ public function randomkeys($length) { $pattern = '1234567890123456789012345678905678901234'; $key = null; for ($i = 0; $i < $length; $i++) { $key .= $pattern{mt_rand(0, 30)}; //生成php隨機數 } return $key; } /** * 將xml轉爲array * @param string $xml * @throws WxPayException */ public function FromXml($xml) { //將XML轉爲array return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)),true); } /** * 輸出xml字符 * @throws WxPayException **/ public function ToXml($arr) { $xml = "<xml>"; foreach ($arr as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; } else { $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"; } } $xml .= "</xml>"; return $xml; } /** * 生成簽名 * @return 簽名,本函數不覆蓋sign成員變量,如要設置簽名須要調用SetSign方法賦值 */ protected function MakeSign($arr,$key) { ksort($arr); $string = $this->ToUrlParams($arr); //簽名步驟二:在string後加入KEY $string = $string."&key=$key"; //key祕鑰 //簽名步驟三:MD5加密 $string = md5($string); //簽名步驟四:全部字符轉爲大寫 $result = strtoupper($string); return $result; } /** * 格式化參數格式化成url參數 */ protected function ToUrlParams($arr) { $buff = ""; foreach ($arr as $k => $v){ if ($k != "sign" && $v != "" && !is_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } // 判斷返回的簽名和根據數據生成的數據判斷是否相同,防止數據泄漏致使出現「假通知」,形成資金損失。 function verifySign($params, $apikey) { ksort($params); $string = ""; foreach ($params as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) { $string .= $k . "=" . $v . "&"; } } $string = $string . "key=" . $apikey; $string = md5($string); $result = strtoupper($string); return $result; }
到這裏 微信jsapi就結束了 下一篇講支付寶的流程以及代碼操做