ThinkPHP实现支付宝接口功能实例
《ThinkPHP实现支付宝接口功能实例》要点: 本篇章节讲解ThinkPHP实现支付宝接口功能的办法.分享给大家供大家参考.具体分析如下:PHP教程 最近做系统,需要实现在线支付功能,毫不犹豫,选择的是支付宝的接口支付功能,这里我用的是即时到帐的接口,具体实现的步骤如下:PHP教程 一、下载支付宝接口包PHP教程 下载地址:https://b.alipay.com/order/productDetail.htm?productId=2012111200373124&tabId=4#ps-tabinfo-hashPHP教程 具体如何下载,我就不在罗嗦了~~PHP教程 二、重新整理接口包文件,这一步应该算是比较关键的(个人认为),下载下来的接口包文件有很多语言的源码PHP教程
我们选择 create_direct_pay_by_user-PHP-UTF-8 这个名称的接口文件,里面包括如下文件:PHP教程
images文件里是支付宝相关的一些标志的图片,我们暂不管他,lib文件很重要,是整个接口的核心类文件;PHP教程 alipay.config.php是相关参数的配置文件PHP教程 alipayapi.php 是支付宝接口入口文件PHP教程 notify_url.php 是服务器异步通知页面文件;PHP教程 return_url.php 是页面跳转同步通知文件;PHP教程 在ThinkPHP的框架文件下,找到Extend 进入,再进入Vendor,在Vendor文件夹下,新建文件夹Alipay,把支付宝作为第三方类库引入,然后,复制支付宝接口文件包中lib文件里的所有文件,一共4个文件,如下:PHP教程
现在对以上文件进行重命名.PHP教程 alipay_core.function.php重命名为:Corefunction.php;PHP教程 alipay_md5.function.php重命名为:Md5function.php;PHP教程 alipay_notify.class.php重命名为:Notify.php;PHP教程 alipay_submit.class.php重命名为:Submit.php;PHP教程 然后,打开Submit.php文件,把以下代码去掉;PHP教程 require_once("alipay_core.function.php");PHP教程 require_once("alipay_md5.function.php");同样,打开Notify.php文件,把以下两段代码去掉require_once("alipay_core.function.php");PHP教程 require_once("alipay_md5.function.php");为什么要去掉以上两个文件中的这两段代码,因为在项目中调用接口文件的时候,我把所有4个核心文件都通过vendor来进行引入.所以,这不再需要导入.PHP教程 到此,支付宝接口包相关核心类库的整理基本完成.现在开始在项目中调用;PHP教程 三、在项目中调用支付宝接口PHP教程 调用分两步: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',???? ? //支付失败跳转到的页面,并传参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,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规范的命名规则,为的是调用方便,当然你要改成其他名称也可以;PHP教程 2、把执行支付操作(doalipay),处理异步返回结果(notifyurl),处理跳转返回结果(returnurl)三个支付接口的核心页面写到一个PayAction控制器中.PHP教程 3、提交支付的页面中,可以在提交之前先把一些参数要传递的内容先通过暗藏域的方法组合好,比如金额先计算好,订单名称,订单描述等先用字符串组合好.然后提交表单,这样,在doalipay方法中只要直接构造传递参数,直接进行提交就行过了.PHP教程 4、支付返回后的处理因为要在异步和跳转两个办法中都要进行相应的判断和处理,所以,把这些判断和处理写到一个自定义函数中,这样只要调用函数即可,使得代码更加清晰明了.PHP教程 5、notify_url和return_url两种模式的返回url必须使用http://xxxxxxx这样的绝对路径,因为里是从支付宝平台返回到你的项目页面,不能使用相对路径.PHP教程 以上代码在ThinkPHP3.0中正常使用!!PHP教程 更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》及《ThinkPHP常用办法总结》PHP教程 希望本文所述对大家的ThinkPHP框架程序设计有所赞助.PHP教程 欢迎参与《ThinkPHP实现支付宝接口功能实例》讨论,分享您的想法,编程之家 52php.cn为您提供专业教程。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |