ThinkPHP3.2接入支付宝支付接口(PC端)

2018-12-07 15:50:46      站长图库      1105     

整个接口核心类文件

alipay.config.php是相关参数的配置文件

alipayapi.php 是支付宝接口入口文件

notify_url.php 是服务器异步通知页面文件;

return_url.php 是页面跳转同步通知文件;


第一步:

把接口包放到项目中  在ThinkPHP的框架文件下,找到Library进入,再进入Vendor,在Vendor文件夹下,新建文件夹Alipay,把支付宝作为第三方类库引入。然后,复制支付宝接口文件包中上面4个文件。一共4个文件放入项目Alipay中


ThinkPHP3.2接入支付宝支付接口(PC端)


打开Submit.phpNotify.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这样的绝对路径,因为里是从支付宝平台返回到你的项目页面。不能使用相对路径。本地可以自己配置站点域名


附件下载


TAGThinkPHP支付宝支付接口