上一篇PHP微信公眾號JSAPI網頁支付(上)中講到了公眾號平台的相關設置以及支付的大致流程。
這一篇重點講支付后,異步接受回調通知,以及處理后同步通知微信服務器。
首先梳理下整個jsapi支付的流程
1.網頁授權獲取用戶openid
2.使用統一下單支付接口,生成JSAPI頁面調用的支付參數並簽名。
3.使用JSAPI調起支付
4.支付后回調(包括接受異步通知以及做出同步處理)
下面講一些實際中踩到的坑,注意啦
1.官方demo中的一些需要修改的地方
1)打開lib文件夾下的WxPay.Api.PHP文件,在537行有一段curl網絡請求配置代碼:
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);//非嚴格校驗
另外說明下:
在46-49行有一段代碼:
//異步通知url未設置,則使用配置文件中的url
if(!$inputObj->IsNotify_urlSet()){
$inputObj->SetNotify_url(WxPayConfig::NOTIFY_URL);//異步通知url
}
對應的做法是在WxPay.Config.php 中加上這個配置,根據實際回調地址填寫
例如:const NOTIFY_URL="http://paysdk.weixin.qq.com/example/notify.php";
2)打開lib文件夾下的WxPay.Notify.php文件,第79行的代碼:
if($needSign == true &&
$this->GetReturn_code($return_code) == "SUCCESS")
{
$this->SetSign();
}
替換成
if($needSign == true &&
$this->GetReturn_code() == "SUCCESS")
{
$this->SetSign();
}
3)打開lib文件夾下的WxPay.JsApi.php文件,在99行有一段curl網絡請求配置代碼:
curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
替換成
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //此處可根據實際情況填寫,單位(秒)
2.支付回調驗證鏈接,必須是沒有權限驗證的
如果你填寫的回調鏈接,還需要登錄注冊驗證的,就不要嘗試了,必須要可以無障礙訪問的鏈接,而且也不要有一連串的參數傳遞。
最好就是簡單粗暴的[http://serverName/xxx.php]
以ThinkPHP舉例,比如在根目錄下,類似於index.php,重新寫了一個專門的供支付回調的入口文件payment.php,
和它對應的Application/目錄下的模塊(WexinApi)、控制器(WeixinPay)及方法(notify)
如圖:payment.php
糾正一下,上圖最后引入ThinkPHP入口文件那句應該改成: require ‘./ThinkPHP/ThinkPHP.php’
現在訪問[http://serverName/payment.php],就會直接進入到[http://serverName/payment.php/WexinApi/WeixinPay/notify],
這樣回調驗證鏈接可以寫[http://serverName/payment.php],也可以寫[http://serverName/payment.php/WexinApi/WeixinPay/notify]。
支付完成,就會進入到之前寫好的鏈接對應的方法
說明:下面那個$data截圖不完整,應該是$data=json_decode(json_encode(simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOCDATA)),true);
這里有兩個地方要注意:
1)升級完PHP7 發現微信支付回調失敗。原來是 $GLOBALS['HTTP_RAW_POST_DATA']沒有定義的問題。php7 移除了這個全局變量。
像下面這樣寫就要嚴謹一點:
$xml = $GLOBALS['HTTP_RAW_POST_DATA'];//這里在php7下不能獲取數據,使用 php://input 代替
if(!$xml){
$xml = file_get_contents("php://input");
}
或者直接寫$xml=file_get_contents("php://input");
2)此處file_put_contents(日志文件路徑,$xml,FILE_APPEND),linux下,這個地方最好寫全局路徑:/data/wwwroot/...
為了安全起見,對返回過來的簽名,要重新驗證:
參考文章:http://blog.csdn.net/sinat_35861727/article/details/72783988