zoukankan      html  css  js  c++  java
  • thinkphp3.2.3 成功对接支付宝接口

    一、首先下载支付宝官方接口,下载地址:

    https://b.alipay.com/order/productDetail.htm?productId=2012111200373124&tabId=4#ps-tabinfo-hash

    二、重新整理接口包文件,这一步应该算是比较关键的:

    我们需要的是这个 create_direct_pay_by_user-PHP-UTF-8 解压下来

    lib文件夹很重要,是整个接口的核心类文件;
    alipay.config.php是相关参数的配置文件
    alipayapi.php 是支付宝接口入口文件
    notify_url.php 是服务器异步通知页面文件;
    return_url.php 是页面跳转同步通知文件;
    在ThinkPHP的框架文件下,找到Extend 进入,再进入Vendor,在Vendor文件夹下,新建文件夹Alipay,把支付宝作为第三方类库引入。然后,复制支付宝接口文件包中lib文件里的所有文件。一共4个文件,如下:
    alipay_core.function.php 
    alipay_md5.function.php 
    alipay_notify.class.php 
    alipay_submit.class.php
    然后,重新命名,方便tp调用(注意你可以随便命名)

    alipay_core.function.php重命名为:Corefunction.php;

    alipay_md5.function.php重命名为:Md5function.php;

    alipay_notify.class.php重命名为:Notify.php;

    alipay_submit.class.php重命名为:Submit.php;

    然后,打开Submit.PHP文件,把以下代码去掉;

    require_once("alipay_core.function.php");
    require_once("alipay_md5.function.php");

    同样,打开Notify.php文件,把以下两段代码去掉

    require_once("alipay_core.function.php");
    require_once("alipay_md5.function.php");

    到此,支付宝接口包相关核心类库的整理基本完成。现在开始在项目中调用
    三、在项目中调用支付宝接口

    调用分两步:

    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(
     //这里是卖家的支付宝账号,也就是你申请接口时注册的支付宝账号
     '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、新建一个PayController代码如下:

    <?php
    namespace HomeController;
    use ThinkController;
    class PayController extends Controller{
           //在类初始化方法中,引入相关类库    
           public function _initialize() {
            vendor('Alipay.Corefunction');
            vendor('Alipay.Md5function');
            vendor('Alipay.Notify');
            vendor('Alipay.Submit');    
        }
         
        //doalipay方法
            /*该方法其实就是将接口文件包下alipayapi.php的内容复制过来
              然后进行相关处理
            */
        public function doalipay(){
                /*********************************************************
                把alipayapi.php中复制过来的如下两段代码去掉,
                第一段是引入配置项,
                第二段是引入submit.class.php这个类。
               为什么要去掉??
                第一,配置项的内容已经在项目的Config.php文件中进行了配置,我们只需用C函数进行调用即可;
                第二,这里调用的submit.class.php类库我们已经在PayAction的_initialize()中已经引入;所以这里不再需要;
                *****************************************************/
           // 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地址  */
             
            $out_trade_no = '11111';//商户订单号 通过支付页面的表单进行传递,注意要唯一!
            $subject = '我靠我测试测试';  //订单名称 //必填 通过支付页面的表单进行传递
            $total_fee ='100';   //付款金额  //必填 通过支付页面的表单进行传递
            $body = '缪果';  //订单描述 通过支付页面的表单进行传递
            $show_url = '11';  //商品展示地址 通过支付页面的表单进行传递
            $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;
        }
         
         
            /******************************
            服务器异步通知页面方法
            其实这里就是将notify_url.php文件中的代码复制过来进行处理
             
            *******************************/
        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";
            }    
        }
         
        /*
            页面跳转处理方法;
            这里其实就是将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)){
                 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中,这样不用手动调用,即可直接使用这些函数,代码如下:

    //在线交易订单支付处理函数

    //函数功能:根据支付接口传回的数据判断该订单是否已经支付成功;

    //返回值:如果订单已经成功支付,返回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);
     } 
      
      
      
     /*-----------------------------------
    2013.8.13更正
    下面这个函数,其实不需要,大家可以把他删掉,
    具体看我下面的修正补充部分的说明
    ------------------------------------*/
      
     //获取一个随机且唯一的订单号;
     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;
        }
     }

    好了,在tp页面调用<&:U('Pay/doalipay')&>即可成功出现付款页面

  • 相关阅读:
    JPA实体
    JPA简介
    Spring_boot_pom.xml和启动方式
    Hibernate中的Query
    Spring_Hibernate整合准备
    redis 常见问题
    python 操作redis
    大数据平台的搭建思路
    LEFT SEMI JOIN
    HDFS小文件问题及解决方案
  • 原文地址:https://www.cnblogs.com/nuanxin/p/6211741.html
Copyright © 2011-2022 走看看