实例介绍
访问地址:demo32/index.php/home/pay/payform
【实例截图】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | <?php namespace Home\controller; // 命名空间 use Think\Controller; class PayController extends Controller // 继承Controller类 { // 总结几点 // 1、接口包中lib文件中的文件复制到Vendor后,重命名为TP规范的命名规则,为的是调用方便,当然你要改成其他名称也可以; // 2、把执行支付操作(doalipay),处理异步返回结果(notifyurl),处理跳转返回结果(returnurl)三个支付接口的核心页面写到一个PayAction控制器中。 // 3、提交支付的页面中,可以在提交之前先把一些参数要传递的内容先通过隐藏域的方法组合好,比如金额先计算好,订单名称,订单描述等先用字符串组合好。然后提交表单,这样,在doalipay方法中只要直接构造传递参数,直接进行提交就行过了。 // 4、支付返回后的处理因为要在异步和跳转两个方法中都要进行相应的判断和处理,所以,把这些判断和处理写到一个自定义函数中,这样只要调用函数即可,使得代码更加清晰明了。 // 5、notify_url和return_url两种模式的返回url必须使用http://xxxxxxx这样的绝对路径,因为里是从支付宝平台返回到你的项目页面。不能使用相对路径。 // 在类初始化方法中,引入相关类库 // 页面跳转同步通知页面特性(return_url特性) // (1) 买家在支付成功后会看到一个支付宝提示交易成功的页面,该页面会停留几秒,然后会自动跳转回商户指定的同步通知页面(参数return_url); // (2) 该页面中获得参数的方式,需要使用GET方式获取,如request.QueryString("out_trade_no")、$_GET['out_trade_no']; // // (3) 该方式仅仅在买家付款完成以后进行自动跳转,因此只会进行一次; // (4) 该方式不是支付宝主动去调用商户页面,而是支付宝的程序利用页面自动跳转的函数,使用户的当前页面自动跳转; // // (5) 基于(4)的原因,可在本机而不是只能在服务器上进行调试; // (6) 返回URL只有一分钟的有效期,超过一分钟该链接地址会失效,验证则会失败; // (7) 设置页面跳转同步通知页面(return_url)的路径时,不要在页面文件的后面再加上自定义参数。例如: // // 错误的写法:<http://www.alipay.com/alipay/return_url.php?xx=11>; // 正确的写法:<http://www.alipay.com/alipay/return_url.php>; // 服务器异步通知页面特性(notify_url特性) // (1) 必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等; // (2) 支付宝是用POST方式发送通知信息,因此该页面中获取参数的方式,如: // request.Form("out_trade_no")、$_POST['out_trade_no']。 // (3) 支付宝主动发起通知,该方式才会被启用; // (4) 只有在支付宝的交易管理中存在该笔交易,且发生了交易状态的改变,支付宝才会通过该方式发起服务器通知(即时到账中交易状态为“等待买家付款”的状态默认是不会发送通知的); // (5) 服务器间的交互,不像页面跳转同步通知可以在页面上显示出来,这种交互方式是不可见的; // (6) 第一次交易状态改变(即时到账中此时交易状态是交易完成)时,不仅页面跳转同步通知页面会启用,而且服务器异步通知页面也会收到支付宝发来的处理结果通知; // (7) 程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。 // 一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:2m,10m,10m,1h,2h,6h,15h); // (8) 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付宝会收不到success字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知; // (9) cookies、session等在此页面会失效,即无法获取这些数据; // (10) 该方式的调试与运行必须在服务器上,即互联网上能访问; // (11) 该方式的作用主要防止订单丢失,即页面跳转同步通知没有处理订单更新,它则去处理; // (12) 通知ID(参数notify_id)只有一分钟有效期,超过一分钟该次通知会验证失败。一旦验证成功下次再验证就会失效。 public function _initialize() { vendor( 'Alipay.Corefunction' ); vendor( 'Alipay.Md5function' ); vendor( 'Alipay.Notify' ); vendor( 'Alipay.Submit' ); } public function payform(){ echo get_client_ip(); // 客户端的IP地址 $this ->display(); } // 执行支付操作 public function doalipay() { $fee = I( 'post.total_fee' ); if (! empty ( $fee ) && $fee > 0) { $alipay_config = C( 'alipay_config' ); $alipay = C( 'alipay' ); /** * ************************请求参数************************* */ // 需传入的参数 $out_trade_no = "sp" . date ( "YmdHis" ); // $_POST['trade_no'];//商户订单号 通过支付页面的表单进行传递,注意要唯一! $subject = '党费缴纳' ; // $_POST['ordsubject']; //订单名称 //必填 通过支付页面的表单进行传递 $total_fee = $fee ; // $_POST['ordtotal_fee']; //付款金额 //必填 通过支付页面的表单进行传递 $body = '党费缴纳' ; // $_POST['ordbody']; //订单描述 通过支付页面的表单进行传递 // $show_url ='https://www.so.com';// $_POST['ordshow_url']; //商品展示地址 通过支付页面的表单进行传递 // 支付类型 $payment_type = "1" ; // 必填,不能修改 $notify_url = C( 'alipay.notify_url' ); // 服务器异步通知页面路径 $return_url = C( 'alipay.return_url' ); // 页面跳转同步通知页面路径 $seller_email = C( 'alipay.seller_email' ); // 卖家支付宝帐户必填 $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' ]), "seller_email" => trim( $alipay [ 'seller_email' ]), "payment_type" => $payment_type , "notify_url" => $notify_url , "return_url" => $return_url , "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 , "get" , "确认" ); echo $html_text ; } else { $this ->error( "金额为空或小于等于零,请检查后,重新付款" ); } } // 处理异步返回结果 public function notifyurl() { // 这里还是通过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' ) {} echo "success" ; // 请不要修改或删除 } else { // 验证失败 echo "fail" ; } } // 处理跳转返回结果 public function returnurl() { // 这里还是通过C函数来读取配置项,赋值给$alipay_config $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' ) { echo "trade_status=" . $_GET [ 'trade_status' ]; $this ->redirect(C( 'alipay.successpage' ) . '?total_fee=' . $total_fee ); // 跳转到配置项中配置的支付成功页面; } else { echo "trade_status=" . $_GET [ 'trade_status' ]; $this ->redirect(C( 'alipay.errorpage' )); // 跳转到配置项中配置的支付失败页面; } } else { // 验证失败 // 如要调试,请看alipay_notify.php页面的verifyReturn函数 echo "支付失败!" ; } } } |
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)