整個接口核心類文件
alipay.config.php是相關(guān)參數(shù)的配置文件
alipayapi.php 是支付寶接口入口文件
notify_url.php 是服務(wù)器異步通知頁面文件;
return_url.php 是頁面跳轉(zhuǎn)同步通知文件;
第一步:
把接口包放到項目中 在ThinkPHP的框架文件下,找到Library進入,再進入Vendor,在Vendor文件夾下,新建文件夾Alipay,把支付寶作為第三方類庫引入。然后,復(fù)制支付寶接口文件包中上面4個文件。一共4個文件放入項目Alipay中
打開Submit.php和Notify.php把以下兩段代碼注釋掉;
require_once("alipay_core.function.php"); require_once("alipay_md5.function.php");
因為在項目中會通過vendor來引入4個核心文件,所以,這里不再需要導(dǎo)入。
第二步:
1、在配置文件中Conf/Config.php文件中對支付寶相關(guān)參數(shù)進行配置:
'alipay_config'=>array( 'partner' => '*****', //這里是你在成功申請支付寶接口后獲取到的PID; //收款支付寶賬號,一般情況下收款賬號就是簽約賬號 'seller_id' => '*****', //安全檢驗碼,以數(shù)字和字母組成的32位字符 'key' => '***', //這里是你在成功申請支付寶接口后獲取到的Key //簽名方式 不需修改 //這里是異步通知頁面url,提交到項目的Pay控制器的notifyurl方法; 'notify_url'=>'http://update.my/index.php/Home/Pay/notifyurl.html', //這里是頁面跳轉(zhuǎn)通知url,提交到項目的Pay控制器的returnurl方法; 'return_url'=>'http://update.my/index.php/Home/Pay/returnurl.html', 'sign_type' => strtoupper('MD5'), //字符編碼格式 目前支持 gbk 或 utf-8 'input_charset'=> strtolower('utf-8'), //ca證書路徑地址,用于curl中ssl校驗 //請保證cacert.pem文件在當(dāng)前文件夾目錄中 'cacert' => VENDOR_PATH.'Alipay/cacert.pem', //訪問模式,根據(jù)自己的服務(wù)器是否支持ssl訪問,若支持請選擇https;若不支持請選擇http 'transport' => 'http', // 支付類型 ,無需修改 'payment_type' => "1", // 產(chǎn)品類型,無需修改 'service' => "create_direct_pay_by_user", //↑↑↑↑↑↑↑↑↑↑請在這里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ // 防釣魚時間戳 若要使用請調(diào)用類文件submit中的query_timestamp函數(shù) 'anti_phishing_key' => "", 'exter_invoke_ip' => "", ), //以上配置項,是從接口包中alipay.config.php 文件中復(fù)制過來,進行配置; 'alipay' =>array( //支付成功跳轉(zhuǎn)到的頁面,我這里跳轉(zhuǎn)到項目的User控制器,myorder方法,并傳參payed(已支付列表) 'successpage'=>'/index.php/', //支付失敗跳轉(zhuǎn)到的頁面,我這里跳轉(zhuǎn)到項目的User控制器,myorder方法,并傳參unpay(未支付列表) 'errorpage'=>'/index.php/Home/Test', ),
2、新建一個PayController控制器代碼如下:
<?php namespace Home\Controller; use Think\Controller; class PayController extends Controller{ //在類初始化方法中,引入相關(guān)類庫 public function _initialize() { vendor('Alipay.Corefunction'); vendor('Alipay.Md5function'); vendor('Alipay.Notify'); vendor('Alipay.Submit'); } /*該方法其實就是將接口文件包下alipayapi.php的內(nèi)容復(fù)制過來 然后進行相關(guān)處理 */ public function doalipay(){ $alipay_config=C('alipay_config'); $order_sn = filter_var(I('get.order_sn'),FILTER_SANITIZE_NUMBER_INT); if(empty($order_sn)) { //$this->redirect('Myorder/index',3,'您提交的訂單號無效,請?zhí)峤徽_的訂單'); echo "<script>alert('您提交的訂單號無效,請?zhí)峤徽_的訂單!');window.location.href='".U('/Home/Pay/index')."';</script>"; exit(); } else { $order = M()->table('[meeting_order]')->where(array('trade_no'=>$order_sn))->find(); if(empty($order)) { //$this->redirect('Myorder/index',3,'您提交的訂單號未知,請?zhí)峤徽_的訂單'); echo "<script>alert('您提交的訂單號未找到,請?zhí)峤徽_的訂單!');window.location.href='".U('/Home/Pay/index')."';</script>"; exit(); } if($order['paystatus'] >0) { //$this->redirect('Myorder/index',3,'請不要重復(fù)提交訂單'); echo "<script>alert('請不要重復(fù)提交訂單!');window.location.href='".U('/Home/Pay/index')."';</script>"; exit(); } } /**************************請求參數(shù)**************************/ //商戶訂單號,商戶網(wǎng)站訂單系統(tǒng)中唯一訂單號,必填 $out_trade_no = $order_sn; //訂單名稱,必填 $subject ='訂單'.$order_sn; //付款金額,必填 $total_fee =$order['money']; //商品描述,可空 $body = $order['name']; //構(gòu)造要請求的參數(shù)數(shù)組,無需改動 $parameter = array( "service" => $alipay_config['service'], "partner" => $alipay_config['partner'], "seller_id" => $alipay_config['seller_id'], "payment_type" => $alipay_config['payment_type'], "notify_url" => $alipay_config['notify_url'], "return_url" => $alipay_config['return_url'], "anti_phishing_key"=>$alipay_config['anti_phishing_key'], "exter_invoke_ip"=>$alipay_config['exter_invoke_ip'], "out_trade_no" => $out_trade_no,//訂單號 "subject" => $subject, "total_fee" => $total_fee, "body" => $body, "_input_charset" => trim(strtolower($alipay_config['input_charset'])) //其他業(yè)務(wù)參數(shù)根據(jù)在線開發(fā)文檔,添加參數(shù).文檔地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.kiX33I&treeId=62&articleId=103740&docType=1 //如"參數(shù)名"=>"參數(shù)值" ); //var_dump($parameter);exit(); //建立請求 $alipaySubmit = new \AlipaySubmit($alipay_config); $html_text = $alipaySubmit->buildRequestForm($parameter,"post", "確認"); echo $html_text; } /****************************** 服務(wù)器異步通知頁面方法 其實這里就是將notify_url.php文件中的代碼復(fù)制過來進行處理 *******************************/ function notifyurl(){ $alipay_config=C('alipay_config'); //計算得出通知驗證結(jié)果 $alipayNotify = new \AlipayNotify($alipay_config); $verify_result = $alipayNotify->verifyNotify(); if($verify_result) { //驗證成功 //獲取支付寶的通知返回參數(shù),可參考技術(shù)文檔中服務(wù)器異步通知參數(shù)列表 $out_trade_no = $_POST['out_trade_no']; //商戶訂單號 $trade_no = $_POST['trade_no']; //支付寶交易號 $trade_status = $_POST['trade_status']; //交易狀態(tài) $total_fee = $_POST['total_fee']; //交易金額 $notify_id = $_POST['notify_id']; //通知校驗ID。 $notify_time = $_POST['notify_time']; //通知的發(fā)送時間。格式為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, //交易狀態(tài) "notify_id" => $notify_id, //通知校驗ID。 "notify_time" => $notify_time, //通知的發(fā)送時間。 "buyer_email" => $buyer_email, //買家支付寶帳號; ); if($_POST['trade_status'] == 'TRADE_FINISHED') { // }else if ($_POST['trade_status'] == 'TRADE_SUCCESS') { //checkorderstatus($out_trade_no,$total_fee,$parameter); } echo "success"; //請不要修改或刪除 }else { //驗證失敗 echo "fail"; } } /* 頁面跳轉(zhuǎn)處理方法; 這里其實就是將return_url.php這個文件中的代碼復(fù)制過來,進行處理; */ function returnurl(){ //頭部的處理跟上面兩個方法一樣,這里不羅嗦了! $alipay_config = C('alipay_config'); $alipayNotify = new \AlipayNotify( $alipay_config );//計算得出通知驗證結(jié)果 $verify_result = $alipayNotify->verifyReturn(); if($verify_result) { //驗證成功 //獲取支付寶的通知返回參數(shù),可參考技術(shù)文檔中頁面跳轉(zhuǎn)同步通知參數(shù)列表 $out_trade_no = $_GET['out_trade_no']; //商戶訂單號 $trade_no = $_GET['trade_no']; //支付寶交易號 $trade_status = $_GET['trade_status']; //交易狀態(tài) $total_fee = $_GET['total_fee']; //交易金額 $notify_id = $_GET['notify_id']; //通知校驗ID。 $notify_time = $_GET['notify_time']; //通知的發(fā)送時間。 $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, //交易狀態(tài) "notify_id" => $notify_id, //通知校驗ID。 "notify_time" => $notify_time, //通知的發(fā)送時間。 "buyer_email" => $buyer_email, //買家支付寶帳號 ); if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') { if(checkorderstatus($out_trade_no,$total_fee,$parameter)){ $this->redirect(C('alipay.successpage'));//跳轉(zhuǎn)到配置項中配置的支付成功頁面; } }else { echo "trade_status=".$_GET['trade_status']; $this->redirect(C('alipay.errorpage'));//跳轉(zhuǎn)到配置項中配置的支付失敗頁面; } }else { //驗證失敗 //如要調(diào)試,請看alipay_notify.php頁面的verifyReturn函數(shù) echo "支付失敗!"; } } } ?>
3、上面有函數(shù)調(diào)用checkorderstatus函數(shù)判斷訂單是否支付,把這個函數(shù)寫到了項目的Common/functions.php
//在線交易訂單支付處理函數(shù) //函數(shù)功能:根據(jù)支付接口傳回的數(shù)據(jù)判斷該訂單是否已經(jīng)支付成功; //返回值:如果訂單已經(jīng)成功支付,返回true,否則返回false; function checkorderstatus($ordid,$total_fee,$parameter){ $order = M()->table('[meeting_order]')->where(array('trade_no'=>$ordid))->find(); if($order['cost']==$total_fee){ if($order['paystatus']==0){ $rs=M()->table('[meeting_order]')->where(array('trade_no'=>$ordid))->save(array('paystatus'=>1)); if($rs){ if($order['status']==1){ $data['status']=2; $data['addtime']=time(); $ordstatus=M()->table('[meeting_order]')->where(array('trade_no'=>$ordid))->save($data); if($ordstatus){ return true; } else{ return false; } } else{ return false; } } else{ return false; } } else{ return false; } } }
以上就是pc支付寶接口所有代碼,其他業(yè)務(wù)邏輯根據(jù)自己需求進行修改!
四、總結(jié)幾點
1、接口包中的文件復(fù)制到Vendor后,要符合TP規(guī)范的命名規(guī)則,為的是調(diào)用方便,當(dāng)然你要改成其他名稱也可以;
2、把執(zhí)行支付操作(doalipay),處理異步返回結(jié)果(notifyurl),處理跳轉(zhuǎn)返回結(jié)果(returnurl)三個支付接口的核心頁面寫到一個PayAction控制器中。
3、提交支付的頁面中,可以在提交之前先把一些參數(shù)要傳遞的內(nèi)容先通過隱藏域的方法組合好,比如金額先計算好,訂單名稱,訂單描述等先用字符串組合好。然后提交表單,這樣,在doalipay方法中只要直接構(gòu)造傳遞參數(shù),直接進行提交就行過了。
4、支付返回后的處理因為要在異步和跳轉(zhuǎn)兩個方法中都要進行相應(yīng)的判斷和處理,所以,把這些判斷和處理寫到一個自定義函數(shù)中,這樣只要調(diào)用函數(shù)即可,使得代碼更加清晰明了。
5、notify_url和return_url兩種模式的返回url必須使用http://xxxxxxx這樣的絕對路徑,因為里是從支付寶平臺返回到你的項目頁面。不能使用相對路徑。本地可以自己配置站點域名
附件下載