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