Thinkphp与支付宝对接功能的实现 -- 第二步

来源:互联网 发布:科学 知乎 编辑:程序博客网 时间:2024/05/21 04:22

转自:http://www.phptalker.com/thread-564-1-1.html


三、在项目中调用支付宝接口
调用分两步:
1、在配置文件中Conf/Config.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(
'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规范的命名规则,为的是调用方便,当然你要改成其他名称也可以;
2、把执行支付操作(doalipay),处理异步返回结果(notifyurl),处理跳转返回结果(returnurl)三个支付接口的核心页面写到

一个PayAction控制器中。
3、提交支付的页面中,可以在提交之前先把一些参数要传递的内容先通过隐藏域的方法组合好,比如金额先计算好,订单名称,订单

描述等先用字符串组合好。然后提交表单,这样,在doalipay方法中只要直接构造传递参数,直接进行提交就行过了。
4、支付返回后的处理因为要在异步和跳转两个方法中都要进行相应的判断和处理,所以,把这些判断和处理写到一个自定义函数中,

这样只要调用函数即可,使得代码更加清晰明了。
5、notify_url和return_url两种模式的返回url必须使用http://xxxxxxx这样的绝对路径,因为里是从支付宝平台返回到你的项目页面

,不能使用相对路径。
以上代码在ThinkPHP3.0中正常使用!!

0 0