本文來自做者原創投稿;
博客:http://www.jianshu.com/users/21716b19302d/latest_articlesphp
.html
簡單介紹了微信移動支付的申請、接入、使用、確認支付結果等相關流程git
申請步驟直接參考官方文檔-http://kf.qq.com/faq/120911VrYVrA150906F3qqY3.htmlgithub
主要2個大塊:json
開放平臺建立的應用惟一標識。 登陸微信開放平臺,進入應用詳情可查看AppID和AppSecret。api
微信支付申請完成以後,微信商戶平臺會給你的郵箱發通知郵件,裏面包含開通支付的商戶信息數組
即商戶支付祕鑰,主要負責處理通訊相關參數加密。登錄微信商戶平臺(帳號密碼在微信商戶平臺發來的郵件裏) 點擊左側的「帳戶設置 - API 安全」(第一次登錄會讓你安裝操做證書,請先安裝操做證書)。點擊設置密鑰,設置本身的密鑰。安全
用於退款等一些須要證書驗證的接口使用。在微信商戶平臺點擊「帳戶中心 - API 安全」,點擊「下載證書」微信
證書下載後,打開壓縮包會看到「apiclientcert.pem」和「apiclientkey.pem」和rootca.pem證書。網絡
參考接入文檔-https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1
主要幾個步驟:
$appid = ""; //你的appid $mch_id = ""; //商戶id $wx_api_key = ""; //商戶api祕鑰 $out_trade_no = ""; //本身業務系統生成的交易no,能夠惟一標識 $client_ip = ""; //客戶端ip $notify_url = ""; //接收支付結果通知url $UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //統一下單地址 $data = array(); $data['appid'] = $appid; $data['mch_id'] =$mch_id; $data['nonce_str'] = randomStr(20); //隨機20位字符串 $data['body'] = "微信移動支付測試"; $data['detail'] = "微信移動支付測試"; $data['out_trade_no'] = $out_trade_no; $data['total_fee'] = 1; //注意 單位是分 $data['spbill_create_ip'] = $client_ip; $data['notify_url'] = $notify_url; $data['trade_type'] = "APP"; //交易類型 $data['sign'] =sign($data, $wx_api_key); //簽名 //轉爲xml格式 $xml_str = arrayToXmlStr($data); //發送請求 使用封裝好的curl_post $result = curl_post($UNIFIED_ORDER_URL, $xml_str); //解析獲得的值 $get_data = simplexml_load_string($raw_data, 'SimpleXMLElement', LIBXML_NOCDATA); $get_para = array(); $get_sign = ""; foreach ($get_data->children() as $child) { if($child->getName() == 'sign') { $get_sign = strval($child); } else { $get_para[strval($child->getName())] = strval($child); } } if($get_para['return_code'] !== "SUCCESS") { //return code fail } //驗證簽名 if(!verifySign($get_sign, $get_para, $wx_api_key)) { //驗證簽名非法 } //能夠自行處理解析得到的參數 //todo...
一些函數:
/** * array轉成xml str * @param $arr */ public static function arrayToXmlStr($arr) { $xml_data = new \SimpleXMLElement("<xml></xml>"); Func::arrayToXml($arr, $xml_data); return $xml_data->asXML(); } /** * 生成指定長度的隨機字符串(包含大寫英文字母, 小寫英文字母, 數字) * @param $length int 須要生成的字符串的長度 * @return string 包含 大小寫英文字母 和 數字 的隨機字符串 */ public static function randomStr($length){ //生成一個包含 大寫英文字母, 小寫英文字母, 數字 的數組 $arr = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z')); $str = ''; $arr_len = count($arr); for ($i = 0; $i < $length; $i++) { $rand = mt_rand(0, $arr_len-1); $str.=$arr[$rand]; } return $str; } /** * 微信簽名 * @param $para mixed 帶簽名參數數組 * @param $wx_key string wxkey */ public static function sign($para, $wx_key) { $unsign_str = Func::createLinkString(Func::argSort($para)) . "&key=" . $wx_key; $sign = strtoupper(md5($unsign_str)); return $sign; } /** * 微信簽名驗證 * @param $sign * @param $para * @param $wx_key * @return false-驗證失敗 true-驗證成功 */ public static function verifySign($sign, $para, $wx_key) { $unsign_str = Func::createLinkString(Func::argSort($para)) . "&key=" . $wx_key; $sign_str = strtoupper(md5($unsign_str)); if($sign === $sign_str) { return true; } return false; }
2.2 生成支付參數
客戶端須要的支付參數是帶簽名的,因此最好支付參數也在服務端生成後,jsondecode後傳入客戶端便可直接調用
//生成支付參數 $data = array(); $data['appid'] = $appid; $data['mch_id'] =$mch_id; $data['prepayid'] = $prepayid; //剛纔統一下單生成的prepayid $data['package'] = "Sign=WXPay"; $data['noncestr'] = randomStr(20); $data['timestamp'] = time(); $data['sign'] =sign($data, $wx_api_key); $pay_param = json_encode($data);
注:微信支付在開放平臺中填入應用對應的包名和簽名,而且測試時要簽名打包,否則支付失敗
能夠直接參考調用我二次封裝過的Android SDK。 Github地址:https://github.com/tsy12321/PayAndroid
二次封裝過的iOS SDK。 Github地址:https://github.com/tsy12321/PayiOS
注:尤爲要注意通知結果驗證成功後要能正確處理重複通知,放置屢次發貨形成資金損失
$raw_data = $GLOBALS["HTTP_RAW_POST_DATA"]; $get_data = simplexml_load_string($raw_data, 'SimpleXMLElement', LIBXML_NOCDATA); $get_para = array(); $get_sign = ""; foreach ($get_data->children() as $child) { if($child->getName() == 'sign') { $get_sign = strval($child); } else { $get_para[strval($child->getName())] = strval($child); } } if($get_para['return_code'] !== "SUCCESS") { //return code fail die("<xml><return_code><![CDATA[FAIL]]></return_code></xml>"); } //驗證簽名 if(!verifySign($get_sign, $get_para, $wx_api_key)) { //驗證簽名非法 //todo die("<xml><return_code><![CDATA[FAIL]]></return_code></xml>"); } //在這其實通知已經接受成功 能夠返回成功告訴微信不用再次通知了 echo("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>"); //業務狀態碼判斷 if ($get_para['result_code'] !== 'SUCCESS') { //狀態碼錯誤 //支付錯誤 更改訂單狀態 記錄log等 //... } //支付成功 更改訂單狀態 記錄log等 //todo
客戶端收到同步支付結果後建議一段時間內輪詢檢查服務端,獲取服務端的結果,支付最終狀態以服務端爲準
版權申明:內容來源網絡,版權歸原創者全部。除非沒法確認,咱們都會標明做者及出處,若有侵權煩請告知,咱們會當即刪除並表示歉意。謝謝。
-END-
架構文摘
ID:ArchDigest
互聯網應用架構丨架構技術丨大型網站丨大數據丨機器學習
更多精彩文章,請點擊下方:閱讀原文