【2016/08/04】本篇文章內容沒有在維護了,一年前寫下來的不知道微信的接口有沒有改變,想要實際應用的能夠看下白俊遙 朋友的開源項目:http://git.oschina.net/shuaibai123/thinkphp-bjyadmin 本人暫時沒有使用過,不過看起來不錯~php
=====================================================================html
業務場景:前端
用戶在網頁上選定商品,而後生成QRcode,用戶掃後付款返回信息給server。git
用到的支付模式:thinkphp
NATIVE模式二數據庫
服務端信息:安全
PHP,Thinkphp3.2框架微信
首先把官方提供的demo下下來:app
下下來之後 把demo裏面的WxPayPubHelper整個文件夾放到Thinkphp項目裏面Vendor文件夾中,放置以後項目就能夠經過Vendor("WxPayPubHelper.文件名")來調用裏面的php文件(.php不須要加)框架
模式二主要用到的是wxpay文件夾裏面的native_dynamic_qrcode.php,notify_url.php和qrcode.js三個。
在配置文件中配置要用到的信息,包括微信號ID、微信號SECRET、商戶ID、商戶支付祕鑰、證書的url路徑、異步通知的URL
要注意的是:異步URL地址必須是PATHINFO模式,若是是參數模式的話會調用不了。同時還要在微信號上微信支付->開發配置->支付配置中填好相同的NOTIFY_URL
而後能夠開始寫本身的代碼了
建一個新的controller(或者整合到你本身的controller裏面,在這裏我創建一個新的Pay模塊裏面用IndexController)
public function index(){ Vendor("WxPayPubHelper.WxPayPubHelper"); //使用統一支付接口 $unifiedOrder = new \UnifiedOrder_pub(); //設置統一支付接口參數 //設置必填參數 //appid已填,商戶無需重複填寫 //mch_id已填,商戶無需重複填寫 //noncestr已填,商戶無需重複填寫 //spbill_create_ip已填,商戶無需重複填寫 //sign已填,商戶無需重複填寫 $unifiedOrder->setParameter("body","貢獻一分錢");//商品描述 //自定義訂單號,此處僅做舉例 $timeStamp = time(); $out_trade_no = C('wxappid')."$timeStamp"; $unifiedOrder->setParameter("out_trade_no","$out_trade_no");//商戶訂單號 $unifiedOrder->setParameter("total_fee","1");//總金額 $unifiedOrder->setParameter("notify_url",C('NOTIFY_URL'));//通知地址 //var_dump(urlencode(C('NOTIFY_URL'))); $unifiedOrder->setParameter("trade_type","NATIVE");//交易類型 //非必填參數,商戶可根據實際狀況選填 //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商戶號 //$unifiedOrder->setParameter("device_info","XXXX");//設備號 //$unifiedOrder->setParameter("attach","XXXX");//附加數據 //$unifiedOrder->setParameter("time_start","XXXX");//交易起始時間 //$unifiedOrder->setParameter("time_expire","XXXX");//交易結束時間 //$unifiedOrder->setParameter("goods_tag","XXXX");//商品標記 //$unifiedOrder->setParameter("openid","XXXX");//用戶標識 $unifiedOrder->setParameter("product_id","1101");//商品ID //獲取統一支付接口結果 $unifiedOrderResult = $unifiedOrder->getResult(); var_dump($unifiedOrderResult); //商戶根據實際狀況設置相應的處理流程 if ($unifiedOrderResult["return_code"] == "FAIL") { //商戶自行增長處理流程 echo "通訊出錯:".$unifiedOrderResult['return_msg']."<br>"; } elseif($unifiedOrderResult["result_code"] == "FAIL") { //商戶自行增長處理流程 echo "錯誤代碼:".$unifiedOrderResult['err_code']."<br>"; echo "錯誤代碼描述:".$unifiedOrderResult['err_code_des']."<br>"; } elseif($unifiedOrderResult["code_url"] != NULL) { //從統一支付接口獲取到code_url $code_url = $unifiedOrderResult["code_url"]; //商戶自行增長處理流程 //...... $this->assign('code_url',$code_url); } $this->assign("unifiedOrderResult",$unifiedOrderResult); $this->theme('default')->display('Pay/index'); }
而後加上以上的代碼,代碼直接從demo裏面抽出來的,主要就是經過Vender讀到helper, 而後是前端部分:
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>微信安全支付</title> </head> <body> <div align="center" id="qrcode"> </div> <div align="center"> <p>訂單號:<?php echo $out_trade_no; ?></p> </div> <div align="center"> <form action="./order_query.php" method="post"> <input name="out_trade_no" type='hidden' value="<?php echo $out_trade_no; ?>"> <button type="submit" >查詢訂單狀態</button> </form> </div> <br> <div align="center"> <form action="./refund.php" method="post"> <input name="out_trade_no" type='hidden' value="<?php echo $out_trade_no; ?>"> <input name="refund_fee" type='hidden' value="1"> <button type="submit" >申請退款</button> </form> </div> <br> <div align="center"> <a href="../index.php">返回首頁</a> </div> </body> <script src="<?php echo theme_url(); ?>/js/qrcode.js"></script> <script> if(<?php echo $unifiedOrderResult["code_url"] != NULL; ?>) { var url = "<?php echo $code_url;?>"; //參數1表示圖像大小,取值範圍1-10;參數2表示質量,取值範圍'L','M','Q','H' var qr = qrcode(10, 'M'); qr.addData(url); qr.make(); var wording=document.createElement('p'); wording.innerHTML = "掃我,掃我"; var code=document.createElement('DIV'); code.innerHTML = qr.createImgTag(); var element=document.getElementById("qrcode"); element.appendChild(wording); element.appendChild(code); } </script> </html>
JS生成QR部分也是用demo的代碼,主要就是督導qrcode.js而後接受到服務端返回的信息把QRcode生成出來,其餘查詢訂單和退款功能這裏不作演示了。
到這裏就能夠用http//你的網址/index.php/pay/index/index 訪問看到你的支付QRcode了
固然還沒結束,用戶支付成功後要獲取到微信服務端的異步通知信息,在IndexController中加入一個notify方法:
public function notify(){ //include_once("./log_.php"); //echo 'access'; Vendor("WxPayPubHelper.WxPayPubHelper"); //使用通用通知接口 $notify = new \Notify_pub(); //存儲微信的回調 $xml = $GLOBALS['HTTP_RAW_POST_DATA']; $notify->saveData($xml); //驗證簽名,並回應微信。 //對後臺通知交互時,若是微信收到商戶的應答不是成功或超時,微信認爲通知失敗, //微信會經過必定的策略(如30分鐘共8次)按期從新發起通知, //儘量提升通知的成功率,但微信不保證通知最終能成功。 // $this->log_result("【checkSign】:\n".$notify->checkSign()."\n"); if($notify->checkSign() == FALSE){ $notify->setReturnParameter("return_code","FAIL");//返回狀態碼 $notify->setReturnParameter("return_msg","簽名失敗");//返回信息 }else{ $notify->setReturnParameter("return_code","SUCCESS");//設置返回碼 } $returnXml = $notify->returnXml(); echo $returnXml; // $this->log_result("【返回回調信息】:\n".$returnXml."\n"); //==商戶根據實際狀況設置相應的處理流程,此處僅做舉例======= //以log文件形式記錄回調信息 $this->log_result("【接收到的notify通知】:\n".$xml."\n"); if($notify->checkSign() == TRUE) { if ($notify->data["return_code"] == "FAIL") { //此處應該更新一下訂單狀態,商戶自行增刪操做 $this->log_result("【通訊出錯】:\n".$xml."\n"); } elseif($notify->data["result_code"] == "FAIL"){ //此處應該更新一下訂單狀態,商戶自行增刪操做 $this->log_result("【業務出錯】:\n".$xml."\n"); } else{ //此處應該更新一下訂單狀態,商戶自行增刪操做 $this->log_result("【支付成功】:\n".$xml."\n"); } //商戶自行增長處理流程, //例如:更新訂單狀態 //例如:數據庫操做 //例如:推送支付完成信息 } }
確認 http://你的網址/index.php/pay/index/notify 能夠訪問到,這個地址就是前面說起到的NOTIFY_URL了,要跟微信支付配置保持一致。而後到這裏爲止就成功了,訪問index出現QRcode而後用戶掃描支付成功 微信服務端調用notify,還有一點要注意的是微信服務端異步調用notify在沒接受到SUCCESS返回前都是繼續發(目前設定是半小時8次),因此記得要返回SUCCESS喲(給出的代碼已經返回了),而後最好就作好重複notify的衝突處理,例如判斷訂單是否被處理過了,避免訂單被重複刷新。
雖然是挺簡單的東西,不過可能當中也會有些坑,爲了幫助你們因此寫下這篇小東西,謝謝哈~