ThinkPHP6對接實(shí)現(xiàn)微信H5支付

微信h5支付是移動端電商網(wǎng)頁必不可少的功能,今天我們就帶領(lǐng)大家來實(shí)現(xiàn)thinkphp6對接實(shí)現(xiàn)微信h5支付。

一、準(zhǔn)備工作

微信支付同樣需要企業(yè)資質(zhì),需要擁有一個(gè)已經(jīng)認(rèn)證的微信服務(wù)號,當(dāng)然這個(gè)是需要繳納300元給微信的。

具體申請的資質(zhì)后,我們打開微信支付平臺,在導(dǎo)航上點(diǎn)擊“產(chǎn)品中心”-》點(diǎn)擊‘H5支付’,在打開的頁面中,填寫并配置相關(guān)域名信息,填寫好之后就可以等待微信官方審核通過了。如果申請不通過,微信會告知原因,直到H5支付通過開通成功。

二、對接微信H5支付

立即學(xué)習(xí)PHP免費(fèi)學(xué)習(xí)筆記(深入)”;

我們首先打開微信H5支付的官方文檔,很遺憾,微信H5支付并沒有像Native掃碼支付那樣給我們準(zhǔn)備官方SDK&DEMO,沒有官方SDK&DEMO,我們就需要自己集成了。

微信H5支付并不難,我們完全閱讀統(tǒng)一下單章節(jié)。

1、準(zhǔn)備參數(shù)。

微信官方已經(jīng)給我們詳細(xì)的列舉了參數(shù),這些參數(shù)獲取并不難,我們需要注意兩個(gè)參數(shù):一個(gè)是簽名sign,一個(gè)是終端IPspbill_create_ip。

簽名sign官方已經(jīng)給出了詳細(xì)的說明,我們按key1=value1&key2=value2形式根據(jù)ASCII碼從小到大排序。排序后得到StringA,然后再用得到的StringA和key拼接,最后都轉(zhuǎn)成大寫。

我們來看詳細(xì)代碼:

public?function?index(){  ????????$url?=?"https://api.mch.weixin.qq.com/pay/unifiedorder";//微信傳參地址  ????????//1.獲取調(diào)用統(tǒng)一下單接口所需必備參數(shù) ????????$appid?=?'wxff5b6b241a4fb11';//微信公眾號appid ????????$mch_id?=?'152223331';//微信支付商戶號 ????????$key?=?'b304911d6a9f7728d264dfd695ebae1';//自己設(shè)置的微信商家key ????????$out_trade_no?=?time();//平臺內(nèi)部訂單號 ????????$nonce_str=MD5(time());//隨機(jī)字符串 ????????$body?=?'商品購買';//付款內(nèi)容 ????????$total_fee?=?1;//訂單總金額,單位為分 ????????$spbill_create_ip?=?$this?-&gt;?get_client_ip();?//獲得用戶設(shè)備IP ????????$attach?=?'weixinh5';//附加數(shù)據(jù)(自定義,在支付通知中原樣返回)???????? ????????$notify_url?=?"http://www.xxx.cn/mobile/WechatPay/notify";//通知地址 ????????$trade_type?=?'MWEB';//交易類型,微信H5支付時(shí)固定為MWEB  ????????//2.將參數(shù)按照key=value的格式,并按照參數(shù)名ASCII字典序排序生成字符串 ????????$signA?="appid=$appid&amp;attach=$attach&amp;body=$body&amp;mch_id=$mch_id&amp;nonce_str=$nonce_str&amp;notify_url=$notify_url&amp;out_trade_no=$out_trade_no&amp;spbill_create_ip=$spbill_create_ip&amp;total_fee=$total_fee&amp;trade_type=$trade_type"; ???????? ????????//3.拼接字符串 ????????$strSignTmp?=?$signA."&amp;key=$key";  ????????//4.MD5加密后轉(zhuǎn)換成大寫 ????????$sign?=?strtoupper(MD5($strSignTmp));  ????????//5.拼接成所需XML格式 ????????$post_data?=?"<xml>? ????????????????<appid>$appid</appid>? ????????????????<attach>$attach</attach>? ????????????????$body? ????????????????<mch_id>$mch_id</mch_id>? ????????????????<nonce_str>$nonce_str</nonce_str>? ????????????????<notify_url>$notify_url</notify_url>? ????????????????<out_trade_no>$out_trade_no</out_trade_no>? ????????????????<spbill_create_ip>$spbill_create_ip</spbill_create_ip>? ????????????????<total_fee>$total_fee</total_fee>? ????????????????<trade_type>$trade_type</trade_type> ????????????????<sign>$sign</sign>? ????????????????</xml>";  ????}

在這里用到一個(gè)$this -> get_client_ip()獲取ip地址,我們看該方法的代碼:

public?function?get_client_ip()?{ ????????if(getenv('HTTP_CLIENT_IP')?&amp;&amp;?strcasecmp(getenv('HTTP_CLIENT_IP'),?'unknown'))?{ ????????????$ip?=?getenv('HTTP_CLIENT_IP'); ????????}?elseif(getenv('HTTP_X_FORWARDED_FOR')?&amp;&amp;?strcasecmp(getenv('HTTP_X_FORWARDED_FOR'),?'unknown'))?{ ????????????$ip?=?getenv('HTTP_X_FORWARDED_FOR'); ????????}?elseif(getenv('REMOTE_ADDR')?&amp;&amp;?strcasecmp(getenv('REMOTE_ADDR'),?'unknown'))?{ ????????????$ip?=?getenv('REMOTE_ADDR'); ????????}?elseif(isset($_SERVER['REMOTE_ADDR'])?&amp;&amp;?$_SERVER['REMOTE_ADDR']?&amp;&amp;?strcasecmp($_SERVER['REMOTE_ADDR'],?'unknown'))?{ ????????????$ip?=?$_SERVER['REMOTE_ADDR']; ????????} ????????return?preg_match?(?'/[d.]{7,15}/',?$ip,?$matches?)???$matches?[0]?:?''; ????}

2、將參數(shù)post到官方地址。

官方的地址是URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder,這個(gè)地址是不允許更改的。我們把準(zhǔn)備好的xml參數(shù)post過去。

$dataxml?=?$this?->?httpRequest($url,’POST’,$post_data);

這里的httpRequest方法是用來發(fā)送post數(shù)據(jù)的:

public?function?httpRequest($url,?$method,?$postfields?=?null,?$headers?=?array(),?$debug?=?false)?{ ????????$method?=?strtoupper($method); ????????$ci?=?curl_init(); ????????/*?Curl?settings?*/ ????????curl_setopt($ci,?CURLOPT_HTTP_VERSION,?CURL_HTTP_VERSION_1_0); ????????curl_setopt($ci,?CURLOPT_USERAGENT,?"Mozilla/5.0?(Windows?NT?6.2;?WOW64;?rv:34.0)?Gecko/20100101?Firefox/34.0"); ????????curl_setopt($ci,?CURLOPT_CONNECTTIMEOUT,?60);?/*?在發(fā)起連接前等待的時(shí)間,如果設(shè)置為0,則無限等待?*/ ????????curl_setopt($ci,?CURLOPT_TIMEOUT,?7);?/*?設(shè)置cURL允許執(zhí)行的最長秒數(shù)?*/ ????????curl_setopt($ci,?CURLOPT_RETURNTRANSFER,?true); ????????switch?($method)?{ ????????case?"POST": ????????????curl_setopt($ci,?CURLOPT_POST,?true); ????????????if?(!empty($postfields))?{ ????????????$tmpdatastr?=?is_array($postfields)???http_build_query($postfields)?:?$postfields; ????????????curl_setopt($ci,?CURLOPT_POSTFIELDS,?$tmpdatastr); ????????????} ????????????break; ????????default: ????????????curl_setopt($ci,?CURLOPT_CUSTOMREQUEST,?$method);?/*?//設(shè)置請求方式?*/ ????????????break; ????????} ????????$ssl?=?preg_match('/^https:///i',$url)???TRUE?:?FALSE; ????????curl_setopt($ci,?CURLOPT_URL,?$url); ????????if($ssl){ ????????curl_setopt($ci,?CURLOPT_SSL_VERIFYPEER,?FALSE);?//?https請求?不驗(yàn)證證書和hosts ????????curl_setopt($ci,?CURLOPT_SSL_VERIFYHOST,?FALSE);?//?不從證書中檢查SSL加密算法是否存在 ????????} ????????curl_setopt($ci,?CURLOPT_FOLLOWLOCATION,?1); ????????curl_setopt($ci,?CURLOPT_MAXREDIRS,?2);/*指定最多的HTTP重定向的數(shù)量,這個(gè)選項(xiàng)是和CURLOPT_FOLLOWLOCATION一起使用的*/ ????????curl_setopt($ci,?CURLOPT_HTTPHEADER,?$headers); ????????curl_setopt($ci,?CURLINFO_HEADER_OUT,?true); ????????$response?=?curl_exec($ci); ????????$requestinfo?=?curl_getinfo($ci); ????????if?($debug)?{ ????????????echo?"=====post?data======rn"; ????????????var_dump($postfields); ????????????echo?"=====info=====?rn"; ????????????print_r($requestinfo); ????????????echo?"=====response=====rn"; ????????????print_r($response); ????????} ????????curl_close($ci); ????????return?$response; ????}

來看下完整代碼:

public?function?index(){  ????????$url?=?"https://api.mch.weixin.qq.com/pay/unifiedorder";//微信傳參地址  ????????//1.獲取調(diào)用統(tǒng)一下單接口所需必備參數(shù) ????????$appid?=?'wxff5b68b241a4fb11';//微信公眾號appid ????????$mch_id?=?'1522223331';//微信支付商戶號 ????????$key?=?'b304911d6a19f7728d264dfd695ebae1';//自己設(shè)置的微信商家key ????????$out_trade_no?=?time();//平臺內(nèi)部訂單號 ????????$nonce_str=MD5(time());//隨機(jī)字符串 ????????$body?=?'商品購買';//付款內(nèi)容 ????????$total_fee?=?1;//訂單總金額,單位為分 ????????$spbill_create_ip?=?$this?-&gt;?get_client_ip();?//獲得用戶設(shè)備IP ????????$attach?=?'weixinh5';//附加數(shù)據(jù)(自定義,在支付通知中原樣返回)???????? ????????$notify_url?=?"http://www.dongpaiweb.cn/mobile/WechatPay/notify";//通知地址 ????????$trade_type?=?'MWEB';//交易類型,微信H5支付時(shí)固定為MWEB  ????????//2.將參數(shù)按照key=value的格式,并按照參數(shù)名ASCII字典序排序生成字符串 ????????$signA?="appid=$appid&amp;attach=$attach&amp;body=$body&amp;mch_id=$mch_id&amp;nonce_str=$nonce_str&amp;notify_url=$notify_url&amp;out_trade_no=$out_trade_no&amp;spbill_create_ip=$spbill_create_ip&amp;total_fee=$total_fee&amp;trade_type=$trade_type"; ???????? ????????//3.拼接字符串 ????????$strSignTmp?=?$signA."&amp;key=$key";  ????????//4.MD5加密后轉(zhuǎn)換成大寫 ????????$sign?=?strtoupper(MD5($strSignTmp));  ????????//5.拼接成所需XML格式 ????????$post_data?=?"<xml>? ????????????????<appid>$appid</appid>? ????????????????<attach>$attach</attach>? ????????????????$body? ????????????????<mch_id>$mch_id</mch_id>? ????????????????<nonce_str>$nonce_str</nonce_str>? ????????????????<notify_url>$notify_url</notify_url>? ????????????????<out_trade_no>$out_trade_no</out_trade_no>? ????????????????<spbill_create_ip>$spbill_create_ip</spbill_create_ip>? ????????????????<total_fee>$total_fee</total_fee>? ????????????????<trade_type>$trade_type</trade_type> ????????????????<sign>$sign</sign>? ????????????????</xml>";  ????????//6.以POST方式向微信傳參,并取得微信返回的支付參數(shù) ????????$dataxml?=?$this?-&gt;?httpRequest($url,'POST',$post_data); ????????$objectxml?=?(array)simplexml_load_string($dataxml,?'SimpleXMLElement',?LIBXML_NOCDATA);?//將微信返回的XML轉(zhuǎn)換成數(shù)組 ????????if($objectxml['return_code']?==?'SUCCESS'){ ????????????if($objectxml['result_code']?==?'SUCCESS')//如果這兩個(gè)都為此狀態(tài)則返回mweb_url,詳情看‘統(tǒng)一下單’接口文檔 ????????????????$return_url?=?"http://www.dongpaiweb.cn/mobile/WechatPay/return";//支付后跳轉(zhuǎn)地址 ????????????????$urls?=?$objectxml['mweb_url']?.?'&amp;redirect_url='?.?urlencode($return_url); ???????????????? ????????????????//訪問這個(gè)url??但是在用下面的方法訪問是?報(bào)錯(cuò)商家信息有誤?所以我把url?放到視圖中?跳轉(zhuǎn) ????????????????//?header("Location:$urls"); ????????????????return?view('mobile_pay',[ ????????????????????'url'=&gt;$urls ????????????????]); ????????????????//mweb_url是微信返回的支付連接要把這個(gè)連接分配到前臺 ????????????if($objectxml['result_code']?==?'FAIL'){ ????????????????return?$err_code_des?=?$objectxml['err_code_des']; ????????????} ???????????????? ????????}  ????}

需要注意,微信返回參數(shù)return_code和result_code,return_code僅代表通信成功,不能代表交易成功。只有當(dāng)return_code和result_code都為SUCCESS的時(shí)候才為交易成功。

最后還要區(qū)分notify地址和return地址,notify地址是微信給商戶的支付通知,和Native支付相同,以數(shù)據(jù)流形式發(fā)送過來。return地址是用戶支付后的跳轉(zhuǎn)頁面,是給用戶看的。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊13 分享