《PHP教程:ThinkPHP實現支付寶接口功能實例》要點:
本文介紹了PHP教程:ThinkPHP實現支付寶接口功能實例,希望對您有用。如果有疑問,可以聯系我們。
本文實例講述了ThinkPHP實現支付寶接口功能的辦法.分享給大家供大家參考.具體分析如下:PHP教程
最近做系統,需要實現在線支付功能,毫不猶豫,選擇的是支付寶的接口支付功能,這里我用的是即時到帳的接口,具體實現的步驟如下:PHP教程
一、下載支付寶接口包PHP教程
下載地址:https://b.alipay.com/order/productDetail.htm?productId=2012111200373124&tabId=4#ps-tabinfo-hashPHP教程
具體如何下載,我就不在羅嗦了~~PHP教程
二、重新整理接口包文件,這一步應該算是比較關鍵的(個人認為),下載下來的接口包文件有很多語言的源碼PHP教程
PHP教程
我們選擇 create_direct_pay_by_user-PHP-UTF-8 這個名稱的接口文件,里面包括如下文件:PHP教程
PHP教程
images文件里是支付寶相關的一些標志的圖片,我們暫不管他,lib文件很重要,是整個接口的核心類文件;PHP教程
alipay.config.php是相關參數的配置文件PHP教程
alipayapi.php 是支付寶接口入口文件PHP教程
notify_url.php 是服務器異步通知頁面文件;PHP教程
return_url.php 是頁面跳轉同步通知文件;PHP教程
在ThinkPHP的框架文件下,找到Extend 進入,再進入Vendor,在Vendor文件夾下,新建文件夾Alipay,把支付寶作為第三方類庫引入,然后,復制支付寶接口文件包中lib文件里的所有文件,一共4個文件,如下:PHP教程
PHP教程
現在對以上文件進行重命名.PHP教程
alipay_core.function.php重命名為:Corefunction.php;PHP教程
alipay_md5.function.php重命名為:Md5function.php;PHP教程
alipay_notify.class.php重命名為:Notify.php;PHP教程
alipay_submit.class.php重命名為:Submit.php;PHP教程
然后,打開Submit.php文件,把以下代碼去掉;PHP教程
require_once("alipay_core.function.php");PHP教程
require_once("alipay_md5.function.php");同樣,打開Notify.php文件,把以下兩段代碼去掉require_once("alipay_core.function.php");PHP教程
require_once("alipay_md5.function.php");為什么要去掉以上兩個文件中的這兩段代碼,因為在項目中調用接口文件的時候,我把所有4個核心文件都通過vendor來進行引入.所以,這不再需要導入.PHP教程
到此,支付寶接口包相關核心類庫的整理基本完成.現在開始在項目中調用;PHP教程
三、在項目中調用支付寶接口PHP教程
調用分兩步:PHP教程
1、在配置文件中Conf/Config.php文件中對支付寶相關參數進行配置
PHP教程
代碼如下:
//支付寶配置參數?
?
'alipay_config'=>array(?
?????? 'partner' =>'20********50',?? //這里是你在成功申請支付寶接口后獲取到的PID;?
??? 'key'=>'9t***********ie',//這里是你在成功申請支付寶接口后獲取到的Key?
??? 'sign_type'=>strtoupper('MD5'),?
??? 'input_charset'=> strtolower('utf-8'),?
??? 'cacert'=> getcwd().'\\cacert.pem',?
??? 'transport'=> 'http',?
????? ),?
???? //以上配置項,是從接口包中alipay.config.php 文件中復制過來,進行配置;?
?????
'alipay'?? =>array(?
?//這里是賣家的支付寶賬號,也就是你申請接口時注冊的支付寶賬號?
'seller_email'=>'pay@xxx.com',?
?
//這里是異步通知頁面url,提交到項目的Pay控制器的notifyurl方法;?
'notify_url'=>'http://www.xxx.com/Pay/notifyurl',??
?
//這里是頁面跳轉通知url,提交到項目的Pay控制器的returnurl方法;?
'return_url'=>'http://www.xxx.com/Pay/returnurl',?
?
//支付成功跳轉到的頁面,我這里跳轉到項目的User控制器,myorder方法,并傳參payed(已支付列表)?
'successpage'=>'User/myorder?ordtype=payed',????
?
//支付失敗跳轉到的頁面,我這里跳轉到項目的User控制器,myorder方法,并傳參unpay(未支付列表)?
'errorpage'=>'User/myorder?ordtype=unpay',??
),
2、新建一個PayAction控制器代碼如下
代碼如下:
<?php?
class PayAction extends Action{?
?????? //在類初始化方法中,引入相關類庫?????
?????? public function _initialize() {?
??????? vendor('Alipay.Corefunction');?
??????? vendor('Alipay.Md5function');?
??????? vendor('Alipay.Notify');?
??????? vendor('Alipay.Submit');?????
??? }?
?????
??? //doalipay方法?
?????????
??? public function doalipay(){?
?????????????
?????? // require_once("alipay.config.php");?
?????? // require_once("lib/alipay_submit.class.php");?
????????
?????? //這里我們通過TP的C函數把配置項參數讀出,賦給$alipay_config;?
?????? $alipay_config=C('alipay_config');???
?
?????????
?
??????? $payment_type = "1"; //支付類型 //必填,不能修改?
??????? $notify_url = C('alipay.notify_url'); //服務器異步通知頁面路徑?
??????? $return_url = C('alipay.return_url'); //頁面跳轉同步通知頁面路徑?
??????? $seller_email = C('alipay.seller_email');//賣家支付寶帳戶必填?
??????? $out_trade_no = $_POST['trade_no'];//商戶訂單號 通過支付頁面的表單進行傳遞,注意要唯一!?
??????? $subject = $_POST['ordsubject'];? //訂單名稱 //必填 通過支付頁面的表單進行傳遞?
??????? $total_fee = $_POST['ordtotal_fee'];?? //付款金額? //必填 通過支付頁面的表單進行傳遞?
??????? $body = $_POST['ordbody'];? //訂單描述 通過支付頁面的表單進行傳遞?
??????? $show_url = $_POST['ordshow_url'];? //商品展示地址 通過支付頁面的表單進行傳遞?
??????? $anti_phishing_key = "";//防釣魚時間戳 //若要使用請調用類文件submit中的query_timestamp函數?
??????? $exter_invoke_ip = get_client_ip(); //客戶端的IP地址??
?????
??????? //構造要哀求的參數數組,無需改動?
??? $parameter = array(?
??????? "service" => "create_direct_pay_by_user",?
??????? "partner" => trim($alipay_config['partner']),?
??????? "payment_type"??? => $payment_type,?
??????? "notify_url"??? => $notify_url,?
??????? "return_url"??? => $return_url,?
??????? "seller_email"??? => $seller_email,?
??????? "out_trade_no"??? => $out_trade_no,?
??????? "subject"??? => $subject,?
??????? "total_fee"??? => $total_fee,?
??????? "body"??????????? => $body,?
??????? "show_url"??? => $show_url,?
??????? "anti_phishing_key"??? => $anti_phishing_key,?
??????? "exter_invoke_ip"??? => $exter_invoke_ip,?
??????? "_input_charset"??? => trim(strtolower($alipay_config['input_charset']))?
??????? );?
??????? //建立哀求?
??????? $alipaySubmit = new AlipaySubmit($alipay_config);?
??????? $html_text = $alipaySubmit->buildRequestForm($parameter,"post", "確認");?
??????? echo $html_text;?
??? }?
?????????
??? function notifyurl(){?
??????????????????
??????????????? //require_once("alipay.config.php");?
??????????????? //require_once("lib/alipay_notify.class.php");?
?????????????????
??????????????? //這里還是通過C函數來讀取配置項,賦值給$alipay_config?
??????? $alipay_config=C('alipay_config');?
?
??????? //計算得出通知驗證結果?
??????? $alipayNotify = new AlipayNotify($alipay_config);?
??????? $verify_result = $alipayNotify->verifyNotify();?
?
??????? if($verify_result) {?
?????????????? //驗證成功?
?????????????????? //獲取支付寶的通知返回參數,可參考技術文檔中服務器異步通知參數列表?
?????????? $out_trade_no?? = $_POST['out_trade_no'];????? //商戶訂單號?
?????????? $trade_no?????? = $_POST['trade_no'];????????? //支付寶交易號?
?????????? $trade_status?? = $_POST['trade_status'];????? //交易狀態?
?????????? $total_fee????? = $_POST['total_fee'];???????? //交易金額?
?????????? $notify_id????? = $_POST['notify_id'];???????? //通知校驗ID.?
?????????? $notify_time??? = $_POST['notify_time'];?????? //通知的發送時間.格式為yyyy-MM-dd HH:mm:ss.?
?????????? $buyer_email??? = $_POST['buyer_email'];?????? //買家支付寶帳號;?
?????????????????? $parameter = array(?
???????????? "out_trade_no"???? => $out_trade_no, //商戶訂單編號;?
???????????? "trade_no"???? => $trade_no,???? //支付寶交易號;?
???????????? "total_fee"???? => $total_fee,??? //交易金額;?
???????????? "trade_status"???? => $trade_status, //交易狀態?
???????????? "notify_id"???? => $notify_id,??? //通知校驗ID.?
???????????? "notify_time"?? => $notify_time,? //通知的發送時間.?
???????????? "buyer_email"?? => $buyer_email,? //買家支付寶帳號;?
?????????? );?
?????????? if($_POST['trade_status'] == 'TRADE_FINISHED') {?
?????????????????????? //?
?????????? }else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {?????????????????????????? if(!checkorderstatus($out_trade_no)){?
?????????????? orderhandle($parameter);??
?????????????????????????? //進行訂單處理,并傳送從支付寶返回的參數;?
?????????????? }?
??????????? }?
??????????????? echo "success";??????? //請不要修改或刪除?
???????? }else {?
??????????????? //驗證失敗?
??????????????? echo "fail";?
??????? }?????
??? }?
?????
??? function returnurl(){?
??????????????? //頭部的處理跟上面兩個方法一樣,這里不羅嗦了!?
??????? $alipay_config=C('alipay_config');?
??????? $alipayNotify = new AlipayNotify($alipay_config);//計算得出通知驗證結果?
??????? $verify_result = $alipayNotify->verifyReturn();?
??????? if($verify_result) {?
??????????? //驗證成功?
??????????? //獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表?
??????? $out_trade_no?? = $_GET['out_trade_no'];????? //商戶訂單號?
??????? $trade_no?????? = $_GET['trade_no'];????????? //支付寶交易號?
??????? $trade_status?? = $_GET['trade_status'];????? //交易狀態?
??????? $total_fee????? = $_GET['total_fee'];???????? //交易金額?
??????? $notify_id????? = $_GET['notify_id'];???????? //通知校驗ID.?
??????? $notify_time??? = $_GET['notify_time'];?????? //通知的發送時間.?
??????? $buyer_email??? = $_GET['buyer_email'];?????? //買家支付寶帳號;
?????????????
??????? $parameter = array(?
??????????? "out_trade_no"???? => $out_trade_no,????? //商戶訂單編號;?
??????????? "trade_no"???? => $trade_no,????????? //支付寶交易號;?
??????????? "total_fee"????? => $total_fee,???????? //交易金額;?
??????????? "trade_status"???? => $trade_status,????? //交易狀態?
??????????? "notify_id"????? => $notify_id,???????? //通知校驗ID.?
??????????? "notify_time"??? => $notify_time,?????? //通知的發送時間.?
??????????? "buyer_email"??? => $buyer_email,?????? //買家支付寶帳號?
??????? );?
?????????
if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') {?
??????? if(!checkorderstatus($out_trade_no)){?
???????????? orderhandle($parameter);? //進行訂單處理,并傳送從支付寶返回的參數;?
??? }?
??????? $this->redirect(C('alipay.successpage'));//跳轉到配置項中配置的支付成功頁面;?
??? }else {?
??????? echo "trade_status=".$_GET['trade_status'];?
??????? $this->redirect(C('alipay.errorpage'));//跳轉到配置項中配置的支付失敗頁面;?
??? }?
}else {?
??? //驗證失敗?
??? //如要調試,請看alipay_notify.php頁面的verifyReturn函數?
??? echo "支付失敗!";?
??? }?
}?
}?
?>
3、這里有幾個支付處理過程中需要用到的函數,我把這些函數寫到了項目的Common/common.php中,這樣不用手動調用,即可直接使用這些函數,代碼如下:
代碼如下:
//Orderlist數據表,用于保存用戶的購買訂單記錄;?
?
//在線交易訂單支付處理函數?
//函數功能:根據支付接口傳回的數據判斷該訂單是否已經支付成功;?
//返回值:如果訂單已經成功支付,返回true,否則返回false;?
function checkorderstatus($ordid){?
??? $Ord=M('Orderlist');?
??? $ordstatus=$Ord->where('ordid='.$ordid)->getField('ordstatus');?
??? if($ordstatus==1){?
??????? return true;?
??? }else{?
??????? return false;?????
??? }?
}?
?
//處理訂單函數?
//更新訂單狀態,寫入訂單支付后返回的數據?
function orderhandle($parameter){?
??? $ordid=$parameter['out_trade_no'];?
??? $data['payment_trade_no']????? =$parameter['trade_no'];?
??? $data['payment_trade_status']? =$parameter['trade_status'];?
??? $data['payment_notify_id']???? =$parameter['notify_id'];?
??? $data['payment_notify_time']?? =$parameter['notify_time'];?
??? $data['payment_buyer_email']?? =$parameter['buyer_email'];?
??? $data['ordstatus']???????????? =1;?
??? $Ord=M('Orderlist');?
??? $Ord->where('ordid='.$ordid)->save($data);?
}??
?
//獲取一個隨機且唯一的訂單號;?
function getordcode(){?
??? $Ord=M('Orderlist');?
??? $numbers = range (10,99);?
??? shuffle ($numbers);??
??? $code=array_slice($numbers,0,4);??
??? $ordcode=$code[0].$code[1].$code[2].$code[3];?
??? $oldcode=$Ord->where("ordcode='".$ordcode."'")->getField('ordcode');?
??? if($oldcode){?
??????? getordcode();?
??? }else{?
??????? return $ordcode;?
??? }?
}
四、總結幾點
1、接口包中lib文件中的文件復制到Vendor后,重命名為TP規范的命名規則,為的是調用方便,當然你要改成其他名稱也可以;PHP教程
2、把執行支付操作(doalipay),處理異步返回結果(notifyurl),處理跳轉返回結果(returnurl)三個支付接口的核心頁面寫到一個PayAction控制器中.PHP教程
3、提交支付的頁面中,可以在提交之前先把一些參數要傳遞的內容先通過暗藏域的方法組合好,比如金額先計算好,訂單名稱,訂單描述等先用字符串組合好.然后提交表單,這樣,在doalipay方法中只要直接構造傳遞參數,直接進行提交就行過了.PHP教程
4、支付返回后的處理因為要在異步和跳轉兩個辦法中都要進行相應的判斷和處理,所以,把這些判斷和處理寫到一個自定義函數中,這樣只要調用函數即可,使得代碼更加清晰明了.PHP教程
5、notify_url和return_url兩種模式的返回url必須使用http://xxxxxxx這樣的絕對路徑,因為里是從支付寶平臺返回到你的項目頁面,不能使用相對路徑.PHP教程
以上代碼在ThinkPHP3.0中正常使用!!PHP教程
更多關于thinkPHP相關內容感興趣的讀者可查看本站專題:《ThinkPHP入門教程》及《ThinkPHP常用辦法總結》PHP教程
希望本文所述對大家的ThinkPHP框架程序設計有所贊助.PHP教程
歡迎參與《PHP教程:ThinkPHP實現支付寶接口功能實例》討論,分享您的想法,維易PHP學院為您提供專業教程。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/13502.html