微信支付的坑(思路)
生活随笔
收集整理的這篇文章主要介紹了
微信支付的坑(思路)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
獲取openid頁面刷新:https://bbs.csdn.net/topics/391115929
異步通知驗(yàn)證簽名:微信返回xml數(shù)據(jù)中的sign使用的是HMAC-SHA256加密方法,所以不能使用md5進(jìn)行驗(yàn)簽
<?php namespace Service\Controller;use Base\Webbase; use Service\Controller\WechatPayBankController; class PayController extends Webbase {public function _initialize(){parent::_initialize(); // TODO: Change the autogenerated stubVendor('Wxpay.example.WxPay#JsApiPay');Vendor('Wxpay.example.log');//初始化日志$logHandler= new \CLogFileHandler("../logs/".date('Y-m-d').'.log');$log = \Log::Init($logHandler, 15);}public function wxpay(){$orderid = $_POST['orderid']?$_POST['orderid']: session("orderid");session("orderid",$orderid);if(!$orderid){$this->websuccess(self::START_ALIPAY_OR_WX,'訂單號(hào)為空');}$body = $ordertype = substr(session('orderid'),0,1); //訂單類型//獲取用戶openid$tools = new \JsApiPay();$openId = $tools->GetOpenid();//②、統(tǒng)一下單$input = new \WxPayUnifiedOrder();$input->SetBody($body); //商品描述//$input->SetAttach("test"); //附加數(shù)據(jù)暫未使用到可以注釋掉$input->SetOut_trade_no(session('orderid'));//商戶訂單號(hào),此處訂單號(hào)根據(jù)實(shí)際項(xiàng)目中訂單號(hào)進(jìn)行賦值,要求32個(gè)字符內(nèi),只能是數(shù)字、大小寫字母_-|* 且在同一個(gè)商戶號(hào)下唯一$input->SetTotal_fee(1); //訂單總金額,單位為分$input->SetTime_start(date("YmdHis"));//訂單生成時(shí)間,格式為yyyyMMddHHmmss,如2009年12月25日9點(diǎn)10分10秒表示為20091225091010$input->SetTime_expire(date("YmdHis", time() + 600));//訂單失效時(shí)間,格式為yyyyMMddHHmmss,如2009年12月27日9點(diǎn)10分10秒表示為20091227091010。訂單失效時(shí)間是針對(duì)訂單號(hào)而言的,由于在請(qǐng)求支付的時(shí)候有一個(gè)必傳參數(shù)prepay_id只有兩小時(shí)的有效期,所以在重入時(shí)間超過2小時(shí)的時(shí)候需要重新請(qǐng)求下單接口獲取新的prepay_id//$input->SetGoods_tag("test");//訂單優(yōu)惠標(biāo)記,使用代金券或立減優(yōu)惠功能時(shí)需要的參數(shù),項(xiàng)目暫未使用到,因此注釋掉$input->SetNotify_url("http://www.**.com/index.php/**/pay/jsapi_notify");//異步接收微信支付結(jié)果通知的回調(diào)地址,通知url必須為外網(wǎng)可訪問的url,不能攜帶參數(shù)。$input->SetTrade_type("JSAPI");//交易類型JSAPI 公眾號(hào)支付;NATIVE 掃碼支付;APP APP支付;$input->SetOpenid($openId);$config = new \WxPayConfig();$order = \WxPayApi::unifiedOrder($config, $input);// var_dump($order);//echo '<font color="#f00"><b>統(tǒng)一下單支付單信息</b></font><br/>';// $this->printf_info($order);$jsApiParameters = $tools->GetJsApiParameters($order);// var_dump($jsApiParameters);// return $jsApiParameters;// var_dump($jsApiParameters);//die();// return $jsApiParameters;file_put_contents('./wxtest.log',$jsApiParameters);//獲取共享收貨地址js函數(shù)參數(shù)// $editAddress = $tools->GetEditAddressParameters();//將數(shù)據(jù)渲染到模板中或前端頁面中$assign=array('data'=>$jsApiParameters,'amount'=>1/100,'channel'=>$body);$this->assign($assign);$this->display();}public function printf_info($data){foreach($data as $key=>$value){echo "<font color='#00ff55;'>$key</font> : ".htmlspecialchars($value, ENT_QUOTES)." <br/>";}}public function h5pay(){header("Content-type:text/html;Charset=utf-8");$headers = array('REFERER: '."http://www.**.com",'USER-AGENT:'.$_SERVER["HTTP_USER_AGENT"]);//獲取配置信息$wxconfig = new \WxPayConfig();$orderid = $_POST['orderid'];if(!$orderid){$this->websuccess(self::START_ALIPAY_OR_WX,'訂單號(hào)為空');}if($uac['created_state'] == 1){$this->websuccess(self::START_ALIPAY_OR_WX,'訂單號(hào)已支付,無需重新支付');}$body = $ordertype = substr($orderid,0,1); //訂單類型$money= $uac['amount'];//充值金額$userip = $this->get_client_ip(); //獲得用戶設(shè)備IP$appid = $wxconfig->GetAppId();//微信給的$mch_id = $wxconfig->GetMerchantId();//微信官方的$key = $wxconfig->GetKey();//自己設(shè)置的微信商家key$out_trade_no = $orderid;//平臺(tái)內(nèi)部訂單號(hào)$nonce_str=MD5($out_trade_no);//隨機(jī)字符串$body = $body;//內(nèi)容$total_fee = $money; //金額$spbill_create_ip = $userip; //IP$notify_url = "http://www.**.com/index.php/**/pay/wap_notify"; //回調(diào)地址(支付完成之后微信會(huì)將結(jié)果參數(shù)帶入這個(gè)方法) 這個(gè)根據(jù)自己邏輯需求填寫$trade_type = 'MWEB';//交易類型 具體看API 里面有詳細(xì)介紹$scene_info ='{"h5_info": {"type":"Android","app_name": "**","package_name": "com.**.www.**"}}';//場景信息 必要參數(shù)// $scene_info ='{"h5_info": {"type":"Wap","wap_url": "http://www.**.com","wap_name": "**"}}';//場景信息 必要參數(shù)$signA ="appid=$appid&body=$body&mch_id=$mch_id&nonce_str=$nonce_str¬ify_url=$notify_url&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type";$strSignTmp = $signA."&key=$key"; //拼接字符串 注意順序微信有個(gè)測(cè)試網(wǎng)址 順序按照他的來 直接點(diǎn)下面的校正測(cè)試 包括下面XML 是否正確$sign = strtoupper(MD5($strSignTmp)); // MD5 后轉(zhuǎn)換成大寫$post_data="<xml><appid>$appid</appid><body>$body</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><scene_info>$scene_info</scene_info><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>";//拼接成XML格式 *XML格式文件要求非常嚴(yán)謹(jǐn)不能有空格這點(diǎn)一定要注意//這里是官方給的微信支付接口簽名校驗(yàn)工具可以對(duì)你拼接的xml數(shù)據(jù)進(jìn)行校驗(yàn)對(duì)比重點(diǎn)是對(duì)比簽名sign是否正確//https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=20_1$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信下單接口連接不用更改$dataxml = $this->http_post($url,$post_data,$headers);//傳參調(diào)用curl請(qǐng)求$objectxml = (array)simplexml_load_string($dataxml,'SimpleXMLElement',LIBXML_NOCDATA); //將微信返回的XML 轉(zhuǎn)換成數(shù)組$objectxml['mweb_url'] = $objectxml['mweb_url']."&redirect_url=".urlencode("http://www.yixianglife.com/yxlife_new/ty/ty.html");file_put_contents('h5pay.log',json_encode($objectxml));$this->websuccess(self::OUTPUT_SUCCESS,'成功',$objectxml);}/*** 微信wap支付異步通知*/public function wap_notify(){//獲取商戶key$wxconfig = new \WxPayConfig();$key = $wxconfig->GetKey();//獲取微信發(fā)送的數(shù)據(jù)$notifuedData = file_get_contents("php://input");file_put_contents("./wxxml.log","信息:".$notifuedData."\n",FILE_APPEND);//將XML數(shù)據(jù)轉(zhuǎn)換成數(shù)組$xmlObj = simplexml_load_string($notifuedData,'SimpleXMLElement',LIBXML_NOCDATA);$xmlObj = json_decode(json_encode($xmlObj),true);file_put_contents("./wxwapnotify.log","信息:".json_encode($xmlObj)."\n",FILE_APPEND);//發(fā)送成功進(jìn)行驗(yàn)簽if ($xmlObj['return_code'] == "SUCCESS" && $xmlObj['result_code'] == "SUCCESS"){file_put_contents("./orderdata.log","訂單號(hào)1:".$xmlObj['out_trade_no'],FILE_APPEND);ksort($xmlObj);$buff = "";foreach ($xmlObj as $k=>$v){if ($k!='sign'){$buff .= $k.'='.$v.'&';}}$stringSignTemp = $buff .'key='.$key;$sign =strtoupper(md5($stringSignTemp));//簽名步驟四:所有字符轉(zhuǎn)為大寫$sign = strtoupper($sign);file_put_contents("./sign.log","sign:".$sign."|".$xmlObj['sign']."\n",FILE_APPEND);if ( $sign == $xmlObj['sign']) {// 邏輯出來//通知微信成功獲取到$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';echo $str;exit;}}}public function http_post($url='',$post_data=array(),$header=array(),$timeout=30) {$ch = curl_init();curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳過證書檢查curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 從證書中檢查SSL加密算法是否存在curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HTTPHEADER, $header);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);$response = curl_exec($ch);curl_close($ch);return $response;}/*** jaapi支付異步通知*/public function jsapi_notify(){$wxconfig = new \WxPayConfig();$key = $wxconfig->GetKey();//echo $key."<br>";// 獲取微信回調(diào)的數(shù)據(jù)$notifiedData = file_get_contents('php://input');//XML格式轉(zhuǎn)換$xmlObj = simplexml_load_string($notifiedData, 'SimpleXMLElement', LIBXML_NOCDATA);$xmlObj = json_decode(json_encode($xmlObj),true);file_put_contents("./wxnotifyinfoaccept.log","信息:".json_encode($xmlObj)."\n",FILE_APPEND);// 當(dāng)支付通知返回支付成功時(shí)if ($xmlObj['return_code'] == "SUCCESS" && $xmlObj['result_code'] == "SUCCESS") {file_put_contents("./orderdata.log","訂單號(hào)1:".$xmlObj['out_trade_no'],FILE_APPEND);//獲取返回的所以參數(shù)//這里是要把微信返給我們的所有值,先刪除sign的值,其他值 按ASCII從小到大排序,md5加密+‘key’;ksort($xmlObj);$buff = '';foreach ($xmlObj as $k => $v){if($k != 'sign'){$buff .= $k . '=' . $v . '&';}}$stringSignTemp = $buff . 'key='.$key;//key為證書密鑰//md5處理$sign = strtoupper(hash_hmac('sha256', $stringSignTemp, $key));file_put_contents("./sign.log","sign:".$sign."|".$xmlObj['sign'],FILE_APPEND);//驗(yàn)簽名,默認(rèn)支持MD5 if ( $sign == $xmlObj['sign']) {//做處理//通知微信成功獲取到$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';echo $str;exit;}}}/*** 獲取用戶真實(shí)ip* @return string*/public function get_client_ip() {if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {$ip = getenv('HTTP_CLIENT_IP');} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {$ip = getenv('HTTP_X_FORWARDED_FOR');} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {$ip = getenv('REMOTE_ADDR');} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {$ip = $_SERVER['REMOTE_ADDR'];}return preg_match('/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';}}總結(jié)
以上是生活随笔為你收集整理的微信支付的坑(思路)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHPUnit测试框架学习(1)
- 下一篇: 必须掌握的Cookie知识点在这里