最近搞了個公衆號,因爲是新手,微信支付那一塊其中就遇到了很多的坑,爲此商家由於個人失誤就丟了差很少1000塊。。下面總結一下遇到的坑php
圖爲微信支付的官方文檔前端
圖爲實際文檔的代碼mysql
若是你用過微信支付的sdk,就會發現支付的設置是在jsapi.php這個文件下面,其中上面的那段代碼是微信支付js api的調用,若是有支付行爲就會調用function裏面的函數,若是是返回的信息是"get_brand_wcpay_request:ok",就會執行if裏面你的寫的代碼,按道理來講if裏面通常放置支付成功後的操做,可是這個是前端頁面。。使用者能夠去修改前端的頁面,包括js。。這個是問題關鍵,我一開始覺得是微信網頁,在電腦打不開,就比較安全了,就沒深思那麼多,沒想到上線以後仍是有人能夠修改前端頁面,看來我仍是太年輕了,直接跳過判斷。。執行下一步操做,爲此商家損失了幾百塊。因爲那時候微信支付那一塊我不懂,是找別人作這一塊,我作另外一塊的,因此果斷掉坑了,而那我的又不太負責任,聽說那我的如今還去一個相似於慕課網的授課網站寫微信支付的教程,我tm也是呵呵了,最後那我的想了一下給我建議,就是用微信的查詢訂單api功能去查詢有沒有該訂單,若是沒有該訂單號,則證實他是跳過支付來執行下一段代碼的。至於訂單號,我是經過js的獲取微秒級別的函數獲取的時間戳做爲商家的訂單號的。ajax
我想了一下大概可能出現的狀況,作了個微信支付判斷,若是有不法分子留意,有如下幾種狀況:sql
1.沒有該微信訂單號存在(經過修改前端支付判斷的代碼跳過支付直接進行下一步)數據庫
2.該訂單號沒有支付成功api
3.該微信訂單號爲空數組
4.傳過來的訂單號是已經使用過的(舊的訂單號,這樣就可能會形成支付成功一次,之後買一樣商品不用錢了)安全
5.傳過來的訂單支付的金額和你的商品價格不對(若是有人有心,買了個便宜商品,再把前端js代碼改了一下,不把時間戳的微信單號傳過來,下次買個貴的商品再把該單號傳過來,你也gg了)微信
下面是個人判斷代碼
// 訂單號不空, if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != "") { $out_trade_no = $_REQUEST["out_trade_no"]; $input = new WxPayOrderQuery(); $input->SetOut_trade_no($out_trade_no); $message =WxPayApi::orderQuery($input); /** 這裏是一個數組 */ // 存在該微信訂單號 if(!empty($message)) { // 該訂單號支付成功 if($message['trade_state'] =="SUCCESS") { /** 支付成功 */ // 判斷價格是否和商品對應 $a = $nowPrice*100; if($message['total_fee']!=$a) {// } } // 訂單號沒有不成功支付 else { echo "訂單不存在."; mysql_query($sql); exit(0); /** 錯誤碼 0*/ } } // 該訂單號不存在 else { exit(-1); } } // 沒有存過來單號 else { echo "呵呵,玩你妹"; exit(0); } // 記錄微信單號 $sql = "select tradeid from OddNumber where tradeid = {$out_trade_no};"; $res = mysql_query($sql); $arr = mysql_fetch_assoc($res); //不空證實訂單存在,就是已經用過了 if(!empty($arr) ){ echo "訂單存在"; exit(-1); } // 下面是支付成功後的代碼
好了。。這就是微信支付的坑。。我感受還有更多的坑面對着我,昨晚又遇到一個坑。。微信支付文檔原本寫着$message['total_fee']是int,可是到了php又是string型,和數據庫數據判斷又出錯了.
最後實驗證實,仍是用回調處理支付成功操做比較好...根據前端ajax發送來後臺去判斷,總會出現漏單,並且你須要去寫邏輯去處理..