TP5.0 web微信二維碼付款,包括查詢是否支付成功。
阿新 • • 發佈:2018-12-11
首先呢,需要公司去註冊微信平臺上的東西,拿到資質,拿到配置資訊才可以進行測試。
我們程式猿這裡直接從程式碼開始,不管前面亂七八糟的程式。
下載好文件後把文件放在 exends 目錄下
![這裡我改名為 wechatpay](https://img-blog.csdnimg.cn/20181211104758376.png)
現在說一下整體的開發流程
1.寫配置檔案(APPID,MCHID 等資料) 文件在資料夾下的example->Wx'pa'y.Config.php
2.**配置好後開始更改每個檔案上的 require_once 路徑 防止開發時出沒有必要的錯誤**
//require_once "../lib/WxPay.Config.Interface.php"; require_once EXTEND_PATH.'wechatpay/lib/WxPay.Config.Interface.php';
3.開始在自己的支付模組裡寫邏輯,我在下面會附上我的測試程式碼片段
4.獲取到引數後請求二維碼並返回到網頁上生成(很關鍵的一步)
5.檢測是否支付成功
直接從第3步開始說起
每個公司的邏輯都不同 但需要獲取到二維碼傳入的引數大致相同,請仔細閱讀下面的程式碼。在此之前,可以閱讀一下騰訊給的開發文件。
//掃碼支付 public function wechat_pay($user_id,$number,$pice) { //掃二維碼進行支付 require_once EXTEND_PATH.'wechatpay/lib/WxPay.Api.php'; //載入微信支付相關檔案 require_once EXTEND_PATH.'wechatpay/example/WxPay.NativePay.php'; //載入微信支付相關檔案 require_once EXTEND_PATH.'wechatpay/example/log.php';//載入微信支付相關檔案 require_once EXTEND_PATH.'wechatpay/lib/WxPay.Data.php'; //載入微信支付相關檔案 //模式二 /** * 流程: * 1、呼叫統一下單,取得code_url,生成二維碼 * 2、使用者掃描二維碼,進行支付 * 3、支付完成之後,微信伺服器會通知支付成功 * 4、在支付成功通知中需要查單確認是否真正支付成功(見:notify.php) */ //初始化日誌 $logHandler= new \CLogFileHandler(EXTEND_PATH.'wechatpay/example/log.php'.date('Y-m-d').'.log'); $log = \Log::Init($logHandler, 15); // $notify = new \NativePay(); $input = new \WxPayUnifiedOrder(); $input->SetBody("充值使我快樂"); //設定商品或支付單簡要描述 $input->SetAttach($user_id); //設定附加資料,在查詢API和支付通知中原樣返回,該欄位主要用於商戶攜帶訂單的自定義資料 我這裡設定成使用者ID? $input->SetOut_trade_no($number); //設定商戶系統內部的訂單號,32個字元內、可包含字母, 其他說明見商戶訂單號 $input->SetTotal_fee($pice*100); //設定訂單總金額,只能為整數,詳見支付金額 $input->SetTime_start(date("YmdHi")); //設定訂單生成時間,格式為yyyyMMddHHmmss,如2009年12月25日9點10分10秒錶示為20091225091010。其他詳見時間規則 $input->SetTime_expire(date("YmdHis", time() + 180)); //設定訂單失效時間,格式為yyyyMMddHHmmss,如2009年12月27日9點10分10秒錶示為20091227091010。其他詳見時間規則 //$input->SetGoods_tag("test"); //設定商品標記,代金券或立減優惠功能的引數,說明詳見代金券或立減優惠 $input->SetNotify_url("http://localhost/huoniao/extends/wechatpay/example/native_notify.php");//設定接收微信支付非同步通知回撥地址 $input->SetTrade_type("NATIVE"); //設定取值如下:JSAPI,NATIVE,APP,詳細說明見引數規定 $input->SetProduct_id("0"); //設定trade_type=NATIVE,此引數必傳。此id為二維碼中包含的商品ID,商戶自行定義。 ///var_dump($input);die; $result = $notify->GetPayUrl($input); //var_dump($result);die; return urlencode($result['code_url']); //需要生成變數的值 //1.充值的使用者ID $user_id 使用者表的唯一標識 //2.訂單號 $number //3.金額(微信是以分為單位1的) $pice //4.商品ID 不傳 預設為0 有業務邏輯需要的朋友可以寫進來 }
接下來在控制器裡呼叫上述的這個方法,並傳參。這裡把訂單號先寫入session,查詢是否支付成功時用。
//訂單號 $data['number'] = time().str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT); //將訂單號存入session 做查詢跳轉使用 $_SESSION['user']['user_info']['order_number'] = $data['number']; $code = $this->wechat_pay($user_id,$data['number'],$data['price']); if($code) { //這裡你們可以在判斷的時候做一些$code的驗證規則 json(['code' => 1 , msg => '$code']); }else{ json(['code' => 2 , msg => '二維碼獲取失敗,錯誤碼002']); }
因為是測試程式碼,所以前端請求過來的是死值,你們在開發的時候千萬不要這樣寫,因為極不安全,容易被他人篡改資訊,可能會造成難以挽回的損失。
接下來看前端請求控制器返回生成二維碼與查詢是否交易成功的片段。
寫一下簡單的流程
在使用者輸入金額點選提交按鈕後,獲取提交資料走Ajax去 wechatpay 成功獲取到二維碼並先顯示後,js不停的請求一個查詢的方法是否支付成功,沒成功就一直停留,成功後提示並跳轉頁面 。
這裡需要在騰訊文件裡改一個東西,因為會一直獲取失敗,我找了好久最終發現是他們寫的CURL有點問題 檔案應該是wechatpay->lib->WxPay.Api.php 557行 我直接把這個方法複製下來給你們看
private static function postXmlCurl($config, $xml, $url, $useCert = false, $second = 30)
{
$ch = curl_init();
$curlVersion = curl_version();
$ua = "WXPaySDK/3.0.9 (".PHP_OS.") PHP/".PHP_VERSION." CURL/".$curlVersion['version']." "
.$config->GetMerchantId();
//設定超時
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
$proxyHost = "0.0.0.0";
$proxyPort = 0;
$config->GetProxy($proxyHost, $proxyPort);
//如果有配置代理這裡就設定代理
if($proxyHost != "0.0.0.0" && $proxyPort != 0){
curl_setopt($ch,CURLOPT_PROXY, $proxyHost);
curl_setopt($ch,CURLOPT_PROXYPORT, $proxyPort);
}
curl_setopt($ch,CURLOPT_URL, $url);
//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
curl_setopt($ch,CURLOPT_USERAGENT, $ua);
//設定header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求結果為字串且輸出到螢幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//var_dump($ch);die;
if($useCert == true){
//設定證書
//使用證書:cert 與 key 分別屬於兩個.pem檔案
//證書檔案請放入伺服器的非web目錄下
$sslCertPath = "";
$sslKeyPath = "";
$config->GetSSLCertPath($sslCertPath, $sslKeyPath);
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $sslCertPath);
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $sslKeyPath);
}
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//執行curl
//var_dump(curl_exec($ch));
$data = curl_exec($ch);
//返回結果
if($data){
curl_close($ch);
//var_dump($data);die;
return $data;
}else{
$error = curl_errno($ch);
curl_close($ch);
throw new WxPayException("curl出錯,錯誤碼:$error");
}
}
改完成之後獲取二維碼應該是沒問題了,接下來看HTML程式碼。你要是連這都看不懂,那我真的沒脾氣,請出門右拐。
<div class="weui-cell" style="margin-top:300px;">
<div class="weui-cell__hd">
<label class="weui-label">金額:</label>
</div>
<div class="weui-cell__bd">
<input class="weui-input" name="money" id = "money" type="number"placeholder="金額">
</div>
</div>
<img src="" style="widht:200px;height:200px;" class="zhifu" >
<div class="weui-btn-area">
<button class="weui-btn weui-btn_primary" id="chargebtn" type="button">確定</button>
</div>
<script>
$(function(){
$('.weui-btn').on('click',function(){
var money = $('#money').val();
alert(money)
$.post("{:url('Pay/wechatpay')}",{'money':money},function(data){
//這個str
if(data.code == 1){
//這個str 是解析二維碼的路徑,因為我懶所以偷了百度網盤解析的路徑。你們如果要是不想用,微信文件裡有寫方法,可以自己呼叫自己的
var str = 'https://www.baifubao.com/o2o/0/qrcode?size=10&text='
str += data
$('.zhifu').attr('src',str)
function query(){
//這個就是查詢是否支付成功的請求,每2秒請求查詢次,在下面會詳述控制器裡的程式碼是怎麼寫的
$.post("{:url('Pay/query')}",{},function(data){
if(data.daw == 123){
alert('支付成功')
window.location.reload()
}
},'json')
}
setInterval(query,2000);
}else if(data.code == 2){
alert(data.msg)
}
},'json')
})
})
</script>
接下來看我是怎麼寫這個查詢的方法的,其實很簡單,微信支付文件已經寫好了,我們直接用就好。主要還是在於session裡的訂單號。
記得一定要在控制器裡寫上這句話,因為這個檔案就是查詢檔案
require_once EXTEND_PATH.'wechatpay/example/WxPay.MicroPay.php';//載入微信支付相關檔案
public function query()
{
//查詢訂單狀態
$qurey = new \MicroPay();
$order = $_SESSION['user']['user_info']['order_number'];
$num ='';
$data = $qurey->query($order,$num);
//var_dump($data);
//var_dump($_SESSION['user']['user_info']['order_number']);
return json(['code' => 1,'msg'=>'支付成功']);
}
如此大功告成。這裡我在查詢完成之後沒有清楚session資料,你們記得清除一哈。
上面的東西都是我半年前寫過的專案裡的東西了,今天心血來潮,寫了個部落格。還望各位大佬們多多指教。