热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ThinkPHP实现支付宝接口功能

最近做系统,需要实现在线支付功能,毫不犹豫,选择的是支付宝的接口支付功能,这里我用的是即时到帐的接口,具体实现的步骤如下:一、下载支付宝接口包,下载地址:https://b.alipay.com/order/produc

最近做系统,需要实现在线支付功能,毫不犹豫,选择的是支付宝的接口支付功能,这里我用的是即时到帐的接口,具体实现的步骤如下:

一、下载支付宝接口包

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

具体如何下载,我就不在罗嗦了~~

二、重新整理接口包文件,这一步应该算是比较关键的(个人认为),下载下来的接口包文件有很多语言的源码

\

我们选择 create_direct_pay_by_user-PHP-UTF-8 这个名称的接口文件,里面包括如下文件:

\

images文件里是支付宝相关的一些标志的图片,我们暂不管他,lib文件很重要,是整个接口的核心类文件;

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

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

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

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

在ThinkPHP的框架文件下,找到Extend 进入,再进入Vendor,在Vendor文件夹下,新建文件夹Alipay,把支付宝作为第三方类库引入,然后,复制支付宝接口文件包中lib文件里的所有文件,一共4个文件,如下:

\

现在对以上文件进行重命名.

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");为什么要去掉以上两个文件中的这两段代码,因为在项目中调用接口文件的时候,我把所有4个核心文件都通过vendor来进行引入。所以,这不再需要导入。

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

三、在项目中调用支付宝接口

调用分两步:

1、在配置文件中Conf/Config.php文件中对支付宝相关参数进行配置

  1. //支付宝配置参数 
  2.  
  3. 'alipay_config'=>array
  4.        'partner' =>'20********50',   //这里是你在成功申请支付宝接口后获取到的PID; 
  5.     'key'=>'9t***********ie',//这里是你在成功申请支付宝接口后获取到的Key 
  6.     'sign_type'=>strtoupper('MD5'), 
  7.     'input_charset'=> strtolower('utf-8'), 
  8.     'cacert'=> getcwd().'\\cacert.pem'
  9.     'transport'=> 'http'
  10.       ), 
  11.      //以上配置项,是从接口包中alipay.config.php 文件中复制过来,进行配置; 
  12.      
  13. 'alipay'   =>array
  14.  //这里是卖家的支付宝账号,也就是你申请接口时注册的支付宝账号 
  15. 'seller_email'=>'pay@xxx.com'
  16.  
  17. //这里是异步通知页面url,提交到项目的Pay控制器的notifyurl方法; 
  18. 'notify_url'=>'http://www.xxx.com/Pay/notifyurl',  
  19.  
  20. //这里是页面跳转通知url,提交到项目的Pay控制器的returnurl方法; 
  21. 'return_url'=>'http://www.xxx.com/Pay/returnurl'
  22.  
  23. //支付成功跳转到的页面,我这里跳转到项目的User控制器,myorder方法,并传参payed(已支付列表) 
  24. 'successpage'=>'User/myorder?ordtype=payed',    
  25.  
  26. //支付失败跳转到的页面,我这里跳转到项目的User控制器,myorder方法,并传参unpay(未支付列表) 
  27. 'errorpage'=>'User/myorder?ordtype=unpay',  
  28. ), 

2、新建一个PayAction控制器代码如下

  1.  
  2. class PayAction extends Action{ 
  3.        //在类初始化方法中,引入相关类库     
  4.        public function _initialize() { 
  5.         vendor('Alipay.Corefunction'); 
  6.         vendor('Alipay.Md5function'); 
  7.         vendor('Alipay.Notify'); 
  8.         vendor('Alipay.Submit');     
  9.     } 
  10.      
  11.     //doalipay方法 
  12.          
  13.     public function doalipay(){ 
  14.              
  15.        // require_once("alipay.config.php"); 
  16.        // require_once("lib/alipay_submit.class.php"); 
  17.         
  18.        //这里我们通过TP的C函数把配置项参数读出,赋给$alipay_config; 
  19.        $alipay_config=C('alipay_config');   
  20.  
  21.          
  22.  
  23.         $payment_type = "1"//支付类型 //必填,不能修改 
  24.         $notify_url = C('alipay.notify_url'); //服务器异步通知页面路径 
  25.         $return_url = C('alipay.return_url'); //页面跳转同步通知页面路径 
  26.         $seller_email = C('alipay.seller_email');//卖家支付宝帐户必填 
  27.         $out_trade_no = $_POST['trade_no'];//商户订单号 通过支付页面的表单进行传递,注意要唯一! 
  28.         $subject = $_POST['ordsubject'];  //订单名称 //必填 通过支付页面的表单进行传递 
  29.         $total_fee = $_POST['ordtotal_fee'];   //付款金额  //必填 通过支付页面的表单进行传递 
  30.         $body = $_POST['ordbody'];  //订单描述 通过支付页面的表单进行传递 
  31.         $show_url = $_POST['ordshow_url'];  //商品展示地址 通过支付页面的表单进行传递 
  32.         $anti_phishing_key = "";//防钓鱼时间戳 //若要使用请调用类文件submit中的query_timestamp函数 
  33.         $exter_invoke_ip = get_client_ip(); //客户端的IP地址  
  34.          
  35.      
  36.         //构造要请求的参数数组,无需改动 
  37.     $parameter = array
  38.         "service" => "create_direct_pay_by_user"
  39.         "partner" => trim($alipay_config['partner']), 
  40.         "payment_type"    => $payment_type
  41.         "notify_url"    => $notify_url
  42.         "return_url"    => $return_url
  43.         "seller_email"    => $seller_email
  44.         "out_trade_no"    => $out_trade_no
  45.         "subject"    => $subject
  46.         "total_fee"    => $total_fee
  47.         "body"            => $body
  48.         "show_url"    => $show_url
  49.         "anti_phishing_key"    => $anti_phishing_key
  50.         "exter_invoke_ip"    => $exter_invoke_ip
  51.         "_input_charset"    => trim(strtolower($alipay_config['input_charset'])) 
  52.         ); 
  53.         //建立请求 
  54.         $alipaySubmit = new AlipaySubmit($alipay_config); 
  55.         $html_text = $alipaySubmit->buildRequestForm($parameter,"post""确认"); 
  56.         echo $html_text
  57.     } 
  58.      
  59.  
  60.          
  61.     function notifyurl(){ 
  62.                   
  63.                 //require_once("alipay.config.php"); 
  64.                 //require_once("lib/alipay_notify.class.php"); 
  65.                  
  66.                 //这里还是通过C函数来读取配置项,赋值给$alipay_config 
  67.         $alipay_config=C('alipay_config'); 
  68.  
  69.         //计算得出通知验证结果 
  70.         $alipayNotify = new AlipayNotify($alipay_config); 
  71.         $verify_result = $alipayNotify->verifyNotify(); 
  72.  
  73.         if($verify_result) { 
  74.                //验证成功 
  75.                    //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表 
  76.            $out_trade_no   = $_POST['out_trade_no'];      //商户订单号 
  77.            $trade_no       = $_POST['trade_no'];          //支付宝交易号 
  78.            $trade_status   = $_POST['trade_status'];      //交易状态 
  79.            $total_fee      = $_POST['total_fee'];         //交易金额 
  80.            $notify_id      = $_POST['notify_id'];         //通知校验ID。 
  81.            $notify_time    = $_POST['notify_time'];       //通知的发送时间。格式为yyyy-MM-dd HH:mm:ss。 
  82.            $buyer_email    = $_POST['buyer_email'];       //买家支付宝帐号; 
  83.                    $parameter = array
  84.              "out_trade_no"     => $out_trade_no//商户订单编号; 
  85.              "trade_no"     => $trade_no,     //支付宝交易号; 
  86.              "total_fee"     => $total_fee,    //交易金额; 
  87.              "trade_status"     => $trade_status//交易状态 
  88.              "notify_id"     => $notify_id,    //通知校验ID。 
  89.              "notify_time"   => $notify_time,  //通知的发送时间。 
  90.              "buyer_email"   => $buyer_email,  //买家支付宝帐号; 
  91.            ); 
  92.            if($_POST['trade_status'] == 'TRADE_FINISHED') { 
  93.                        // 
  94.            }else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {                           if(!checkorderstatus($out_trade_no)){ 
  95.                orderhandle($parameter);  
  96.                            //进行订单处理,并传送从支付宝返回的参数; 
  97.                } 
  98.             } 
  99.                 echo "success";        //请不要修改或删除 
  100.          }else { 
  101.                 //验证失败 
  102.                 echo "fail"
  103.         }     
  104.     } 
  105.      
  106.      
  107.     function returnurl(){ 
  108.                 //头部的处理跟上面两个方法一样,这里不罗嗦了! 
  109.         $alipay_config=C('alipay_config'); 
  110.         $alipayNotify = new AlipayNotify($alipay_config);//计算得出通知验证结果 
  111.         $verify_result = $alipayNotify->verifyReturn(); 
  112.         if($verify_result) { 
  113.             //验证成功 
  114.             //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表 
  115.         $out_trade_no   = $_GET['out_trade_no'];      //商户订单号 
  116.         $trade_no       = $_GET['trade_no'];          //支付宝交易号 
  117.         $trade_status   = $_GET['trade_status'];      //交易状态 
  118.         $total_fee      = $_GET['total_fee'];         //交易金额 
  119.         $notify_id      = $_GET['notify_id'];         //通知校验ID。 
  120.         $notify_time    = $_GET['notify_time'];       //通知的发送时间。 
  121.         $buyer_email    = $_GET['buyer_email'];       //买家支付宝帐号; 
  122.              
  123.         $parameter = array
  124.             "out_trade_no"     => $out_trade_no,      //商户订单编号; 
  125.             "trade_no"     => $trade_no,          //支付宝交易号; 
  126.             "total_fee"      => $total_fee,         //交易金额; 
  127.             "trade_status"     => $trade_status,      //交易状态 
  128.             "notify_id"      => $notify_id,         //通知校验ID。 
  129.             "notify_time"    => $notify_time,       //通知的发送时间。 
  130.             "buyer_email"    => $buyer_email,       //买家支付宝帐号 
  131.         ); 
  132.          
  133. if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') { 
  134.         if(!checkorderstatus($out_trade_no)){ 
  135.              orderhandle($parameter);  //进行订单处理,并传送从支付宝返回的参数; 
  136.     } 
  137.         $this->redirect(C('alipay.successpage'));//跳转到配置项中配置的支付成功页面; 
  138.     }else { 
  139.         echo "trade_status=".$_GET['trade_status']; 
  140.         $this->redirect(C('alipay.errorpage'));//跳转到配置项中配置的支付失败页面; 
  141.     } 
  142. }else { 
  143.     //验证失败 
  144.     //如要调试,请看alipay_notify.php页面的verifyReturn函数 
  145.     echo "支付失败!"
  146.     } 
  147. ?> 

3、这里有几个支付处理过程中需要用到的函数,我把这些函数写到了项目的Common/common.php中,这样不用手动调用,即可直接使用这些函数,代码如下:

  1. //Orderlist数据表,用于保存用户的购买订单记录; 
  2.  
  3. //在线交易订单支付处理函数 
  4. //函数功能:根据支付接口传回的数据判断该订单是否已经支付成功; 
  5. //返回值:如果订单已经成功支付,返回true,否则返回false; 
  6. function checkorderstatus($ordid){ 
  7.     $Ord=M('Orderlist'); 
  8.     $ordstatus=$Ord->where('ordid='.$ordid)->getField('ordstatus'); 
  9.     if($ordstatus==1){ 
  10.         return true; 
  11.     }else
  12.         return false;     
  13.     } 
  14.  
  15. //处理订单函数 
  16. //更新订单状态,写入订单支付后返回的数据 
  17. function orderhandle($parameter){ 
  18.     $ordid=$parameter['out_trade_no']; 
  19.     $data['payment_trade_no']      =$parameter['trade_no']; 
  20.     $data['payment_trade_status']  =$parameter['trade_status']; 
  21.     $data['payment_notify_id']     =$parameter['notify_id']; 
  22.     $data['payment_notify_time']   =$parameter['notify_time']; 
  23.     $data['payment_buyer_email']   =$parameter['buyer_email']; 
  24.     $data['ordstatus']             =1; 
  25.     $Ord=M('Orderlist'); 
  26.     $Ord->where('ordid='.$ordid)->save($data); 
  27. }  
  28.  
  29.  
  30. //获取一个随机且唯一的订单号; 
  31. function getordcode(){ 
  32.     $Ord=M('Orderlist'); 
  33.     $numbers = range (10,99); 
  34.     shuffle ($numbers);  
  35.     $code=array_slice($numbers,0,4);  
  36.     $ordcode=$code[0].$code[1].$code[2].$code[3]; 
  37.     $oldcode=$Ord->where("ordcode='".$ordcode."'")->getField('ordcode'); 
  38.     if($oldcode){ 
  39.         getordcode(); 
  40.     }else
  41.         return $ordcode
  42.     } 

四、总结几点

1、接口包中lib文件中的文件复制到Vendor后,重命名为TP规范的命名规则,为的是调用方便,当然你要改成其他名称也可以;

2、把执行支付操作(doalipay),处理异步返回结果(notifyurl),处理跳转返回结果(returnurl)三个支付接口的核心页面写到一个PayAction控制器中。

3、提交支付的页面中,可以在提交之前先把一些参数要传递的内容先通过隐藏域的方法组合好,比如金额先计算好,订单名称,订单描述等先用字符串组合好。然后提交表单,这样,在doalipay方法中只要直接构造传递参数,直接进行提交就行过了。

4、支付返回后的处理因为要在异步和跳转两个方法中都要进行相应的判断和处理,所以,把这些判断和处理写到一个自定义函数中,这样只要调用函数即可,使得代码更加清晰明了。

5、notify_url和return_url两种模式的返回url必须使用http://xxxxxxx这样的绝对路径,因为里是从支付宝平台返回到你的项目页面,不能使用相对路径。

以上代码在ThinkPHP3.0中正常使用!!


推荐阅读
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 本文介绍如何解决在 IIS 环境下 PHP 页面无法找到的问题。主要步骤包括配置 Internet 信息服务管理器中的 ISAPI 扩展和 Active Server Pages 设置,确保 PHP 脚本能够正常运行。 ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文介绍了如何在具备多个IP地址的FTP服务器环境中,通过动态地址端口复用和地址转换技术优化网络配置。重点讨论了2Mb/s DDN专线连接、Cisco 2611路由器及内部网络地址规划。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 如何在PHPcms网站中添加广告
    本文详细介绍了在PHPcms网站后台添加广告的方法,涵盖多种常见的广告形式,如百度广告和Google广告,并提供了相关设置的步骤。同时,文章还探讨了优化网站流量的SEO策略。 ... [详细]
  • 解决Linux系统中pygraphviz安装问题
    本文探讨了在Linux环境下安装pygraphviz时遇到的常见问题,并提供了详细的解决方案和最佳实践。 ... [详细]
  • 如何配置Unturned服务器及其消息设置
    本文详细介绍了Unturned服务器的配置方法和消息设置技巧,帮助用户了解并优化服务器管理。同时,提供了关于云服务资源操作记录、远程登录设置以及文件传输的相关补充信息。 ... [详细]
  • 小红书提高MCN机构入驻门槛,需缴纳20万元保证金
    近期,小红书对MCN机构的入驻要求进行了调整,明确要求MCN机构在入驻时需缴纳20万元人民币的保证金。此举旨在进一步规范平台内容生态,确保社区的真实性和用户体验。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
author-avatar
我心飞翔
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有