微信支付官方demo下載地址 https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1
我修改后的demo http://download.csdn.net/detail/lhat_7/9821931
官方demo的目錄結構如下:
我在本地環境下使用微信支付官方demo過程中遇到的問題有:
問題1
將 /lib/WxPay.Api.php 函數 postXmlCurl 中的兩行代碼
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//嚴格校驗
改為
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
問題2
訪問 http://localhost/weixin/WxpayAPI_php_v3/example/native.php 時的錯誤提示
根據錯誤提示知道:"未定義的索引" 錯誤出在 /exaple/native.php 的 42 行,
顯而易見,是變量 $result 中沒有定義 code_url。打印變量 $result: echo "<pre>";print_r($result);exit();
Array ( [return_code] => FAIL [return_msg] => invalid spbill_create_ip )
參數 spbill_create_ip 在 /lib/WxPay.Api.php 的53行
打印出變量 $_SERVER['REMOTE_ADDR'] ,發現是 ::1 ,這明顯是一個無效的ip地址
//獲取請求地址

1 //獲取瀏覽器ip地址 2 public static function real_ip() 3 { 4 static $realip; 5 6 if ($realip !== NULL) { 7 return $realip; 8 } 9 10 if (isset($_SERVER)) { 11 if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 12 $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); 13 14 foreach ($arr as $ip) { 15 $ip = trim($ip); 16 17 if ($ip != 'unknown') { 18 $realip = $ip; 19 break; 20 } 21 } 22 } 23 else if (isset($_SERVER['HTTP_CLIENT_IP'])) { 24 $realip = $_SERVER['HTTP_CLIENT_IP']; 25 } 26 else if (isset($_SERVER['REMOTE_ADDR'])) { 27 $realip = $_SERVER['REMOTE_ADDR']; 28 } 29 else { 30 $realip = '0.0.0.0'; 31 } 32 } 33 else if (getenv('HTTP_X_FORWARDED_FOR')) { 34 $realip = getenv('HTTP_X_FORWARDED_FOR'); 35 } 36 else if (getenv('HTTP_CLIENT_IP')) { 37 $realip = getenv('HTTP_CLIENT_IP'); 38 } 39 else { 40 $realip = getenv('REMOTE_ADDR'); 41 } 42 43 preg_match('/[\\d\\.]{7,15}/', $realip, $onlineip); 44 $realip = (!empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0'); 45 return $realip; 46 }
將上面的函數添加到類WxPayApi后,修改如下
$inputObj->SetSpbill_create_ip(self::real_ip());//終端ip //$inputObj->SetSpbill_create_ip("1.1.1.1");
再次訪問 http://localhost/weixin/WxpayAPI_php_v3/example/native.php ,出現在眼前的頁面如下
手機微信掃支付模式二的二維碼,支付1分錢,好的,大功告成,^_^!
問題3
且慢,還有回調地址沒處理呢?對,對,對。差點忘記了最重要的 notify_url,它是專門來告訴我們支付結果的。
參數notify_url是在 /example/native.php 中設置的
設置好正確的回調地址,所謂正確的地址必須在微信公眾號設置的支付授權目錄(或測試授權目錄)下,且域名要和微信公眾號綁定的服務器地址域名相同。
如果此處的 notify_url 地址填寫為 http://localhost/weixin/WxpayAPI_php_v3/example/notify.php ,你覺得微信服務器會向這個回調地址發送消息嗎?(不巧的是,我就犯過這個愚蠢的錯誤,還滿心歡喜的以為本地環境下也可以微信掃碼支付,又滿腔憤懣的說微信支付成功后無法回調)
雖然微信絕不可能向本地地址發送消息,但微信還提供了另一個接口,可以讓我們在本地環境下得知微信掃碼支付的結果。
既然微信不主動告知我們支付成功,那我們還不能主動去問嗎?問誰,當然是微信了。
訪問 http://localhost/WxpayAPI_php_v3/example/orderquery.php ,輸入 商戶訂單號(即out_trade_no),點擊查詢
思路:掃碼頁面用js定時ajax去獲取支付結果,當檢測到支付成功后,跳轉到回調頁面notify_url進行業務處理。
在 /example/native.php 的html里添加這樣一段代碼
<input type="hidden" name="out_trade_no" id="out_trade_no" value="<?php echo $out_trade_no;?>" /> <script src="assets/js/jquery-1.9.1.min.js"></script> <script> $(function(){ setInterval(function(){check()}, 5000); //5秒查詢一次支付是否成功 }) function check(){ var url = "http://localhost/WxpayAPI_php_v3/example/orderquery2.php"; //新建 var out_trade_no = $("#out_trade_no").val(); var param = {'out_trade_no':out_trade_no}; $.post(url, param, function(data){ data = JSON.parse(data); if(data['trade_state'] == "SUCCESS"){ alert(JSON.stringify(data)); alert("訂單支付成功,即將跳轉..."); window.location.href = "http://localhost/WxpayAPI_php_v3/index.php"; }else{ console.log(data); } }); } </script>
新建一個 /example/orderquery2.php ,用來查詢支付結果,代碼如下
1 <?php 2 ini_set('date.timezone','Asia/Shanghai'); 3 error_reporting(E_ERROR); 4 require_once "../lib/WxPay.Api.php"; 5 require_once 'log.php'; 6 7 //初始化日志 8 $logHandler= new CLogFileHandler("./logs/".date('Y-m-d').'.log'); 9 $log = Log::Init($logHandler, 15); 10 11 if(isset($_REQUEST["transaction_id"]) && $_REQUEST["transaction_id"] != ""){ 12 $transaction_id = $_REQUEST["transaction_id"]; 13 $input = new WxPayOrderQuery(); 14 $input->SetTransaction_id($transaction_id); 15 echo json_encode(WxPayApi::orderQuery($input)); 16 exit(); 17 } 18 19 if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){ 20 $out_trade_no = $_REQUEST["out_trade_no"]; 21 $input = new WxPayOrderQuery(); 22 $input->SetOut_trade_no($out_trade_no); 23 echo json_encode(WxPayApi::orderQuery($input)); 24 exit(); 25 } 26 ?>