ThinkPHP实现支付宝接口功能实例
本文实例讲述了ThinkPHP实现支付宝接口功能的方法。分享给大家供大家参考。具体分析如下:
最近做系统,需要实现在线支付功能,毫不犹豫,选择的是支付宝的接口支付功能,这里我用的是即时到帐的接口,具体实现的步骤如下:
一、下载支付宝接口包
下载地址: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文件中对支付宝相关参数进行配置
"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、新建一个PayAction控制器代码如下
classPayActionextendsAction{
//在类初始化方法中,引入相关类库
publicfunction_initialize(){
vendor("Alipay.Corefunction");
vendor("Alipay.Md5function");
vendor("Alipay.Notify");
vendor("Alipay.Submit");
}
//doalipay方法
publicfunctiondoalipay(){
//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=newAlipaySubmit($alipay_config);
$html_text=$alipaySubmit->buildRequestForm($parameter,"post","确认");
echo$html_text;
}
functionnotifyurl(){
//require_once("alipay.config.php");
//require_once("lib/alipay_notify.class.php");
//这里还是通过C函数来读取配置项,赋值给$alipay_config
$alipay_config=C("alipay_config");
//计算得出通知验证结果
$alipayNotify=newAlipayNotify($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-ddHH: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"){
//
}elseif($_POST["trade_status"]=="TRADE_SUCCESS"){ if(!checkorderstatus($out_trade_no)){
orderhandle($parameter);
//进行订单处理,并传送从支付宝返回的参数;
}
}
echo"success"; //请不要修改或删除
}else{
//验证失败
echo"fail";
}
}
functionreturnurl(){
//头部的处理跟上面两个方法一样,这里不罗嗦了!
$alipay_config=C("alipay_config");
$alipayNotify=newAlipayNotify($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;
functioncheckorderstatus($ordid){
$Ord=M("Orderlist");
$ordstatus=$Ord->where("ordid=".$ordid)->getField("ordstatus");
if($ordstatus==1){
returntrue;
}else{
returnfalse;
}
}
//处理订单函数
//更新订单状态,写入订单支付后返回的数据
functionorderhandle($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);
}
//获取一个随机且唯一的订单号;
functiongetordcode(){
$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中正常使用!!
希望本文所述对大家的ThinkPHP框架程序设计有所帮助。
相关文章
- SAP License:实例讲解SAP与金税接口
- python调用webservice接口_webservice应用实例
- 遗传算法的应用实例python实现_python遗传算法库
- Java面向对象接口的应用实例练习详解编程语言
- SAP发布Rest接口实例(详细步骤)详解编程语言
- ServletConfig和ServletContext接口及其使用方法详解(附带实例)
- 深入解析MSSQL实例:掌握关键技巧提高数据库管理效率(mssql实例)
- Redis简单实现:快速了解高性能数据库(redis 简单实例)
- 基于cxoracle的实例使用指南(cx_oracle实例)
- Oracle中的左右连接技术使用实例分析(oracle中的左右连接)
- Redis集群多实例共享数据开放新模式(redis 集群 多实例)
- Redis解锁实例拓展数据处理潜能(redis解锁实例)
- SQLJoin的一些总结(实例)
- Java通过接口实现匿名类的实例代码
- .net实现微信公众账号接口开发实例代码
- 免费手机号码归属地API查询接口和PHP使用实例分享
- mysql实现事务的提交和回滚实例
- PHP多进程编程实例
- Winform实现调用asp.net数据接口实例
- Python编程中的反模式实例分析
- JS长整型精度问题实例分析