thinkPHP 接支付宝及时到账接口
支付宝及时到帐接口,现在整理以下:
1.先将支付宝提供的公共类库函数库文件防盗thinkPHP的Vender目录下建的一个alipay文件下,以便之后的调用。
//四个文件我分别给他们改了下名字,因为由于thinkphp Vender目录下,调用路径的问题,如Vender("Alipay.Core.function")这样的结果的Alipay目录下的Core目录下function.php 文件
7 |~Alipay/ 8 | |-Corefunction.php* 9 | |-Md5function.php* 10 | |-Notify.php* 11 | |`-Submit.php*
2.新建一个PayAction.class.php文件
一共三个方法,doalipay是api文件,returnurl是同步传输文件,notifyurl是异步传输文件
<?php header("content-type:text/html;charset=utf-8"); class PayAction extends Action{ //在类初始化方法中,引入相关类库 public function _initialize() { vendor('Alipay.Corefunction'); vendor('Alipay.Md5function'); vendor('Alipay.Notify'); vendor('Alipay.Submit'); } public function doalipay(){ //这里我们通过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']; //付款金额 //必填 通过支付页面的表单进行传递 //对前台传过来的价钱数据做判断 $orderId=$out_trade_no; $oOb=M("order"); $orderArr=$oOb->field("count(*) as num")->where("orderId='{$orderId}'")->select(); $num=$orderArr[0]['num']; if($num==0){ $coOb = M("cardorder"); $arr = $coOb->where("orderId='{$orderId}'")->select(); //var_dump($arr); $realPrice = $arr[0]['price'] - $arr[0]['discount'] - $arr[0]['yhqPrice']; //var_dump($total_fee); var_dump($realPrice); die; if($total_fee != $realPrice){ header("location:index.php?m=Member&a=payFail"); } }else{ $arr=$oOb->where("orderId='{$orderId}'")->select(); $realPrice = $arr[0]['price'] - $arr[0]['discount'] - $arr[0]['yhq']; if($total_fee != $realPrice){ header("location:index.php?m=Member&a=payFail"); } } $body = $_POST['ordbody']; //订单描述 通过支付页面的表单进行传递 $show_url = $_POST['ordshow_url'];//商品展示地址 通过支付页面的表单进行传递 $anti_phishing_key = "";//防钓鱼时间戳 //若要使用请调用类文件submit中的query_timestamp函数 //$exter_invoke_ip = get_client_ip();//var_dump($exter_invoke_ip);die(); //客户端的IP地址 $exter_invoke_ip = $_SERVER["REMOTE_ADDR"];//var_dump($exter_invoke_ip);die(); //客户端的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'])) ); //var_dump($parameter);die(); //建立请求 $alipaySubmit = new AlipaySubmit($alipay_config); $html_text = $alipaySubmit->buildRequestForm($parameter,"post", "确认"); echo $html_text; } function notifyurl(){ $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, //买家支付宝帐号; ); //file_put_contents("/index/paylog.txt",$parameter,FILE_APPEND); 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(); //var_dump($_GET); 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, //买家支付宝帐号 ); //echo "<pre>";var_dump($parameter);echo "</pre>";die(); if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') { if(!checkorderstatus($out_trade_no)){ orderhandle($parameter); //进行订单处理,并传送从支付宝返回的参数; //die(); } $this->redirect(C('alipay.successpage'));//跳转到配置项中配置的支付成功页面; }else { echo "trade_status=".$_GET['trade_status']; $this->redirect(C('alipay.errorpage'));//跳转到配置项中配置的支付失败页面; } }else { //验证失败 //如要调试,请看alipay_notify.php页面的verifyReturn函数 echo "支付失败!"; } } }
3.在index/Common/common.php中加入两个函数,在上面Action中调用
//判断订单的状态是否已经修改 function checkorderstatus($orderId){ 94 $oOb=M("order"); 95 $cOb=M('cardorder'); 96 $orderArr=$oOb->field("count(*) as num")->where("orderId='{$orderId}'")->select(); 97 $num=$orderArr[0]['num']; 98 if($num==0){ 99 $ordstatus=$cOb->where("orderId='".$orderId."'")->getField('status'); 100 }else{ 101 $ordstatus=$oOb->where("orderId='".$orderId."'")->getField('status'); 102 } 103 if($ordstatus==1){ 104 return false; 105 }else{ 106 return true; 107 } 108 }
function orderhandle($parameter){ 112 123 $orderId=$parameter['out_trade_no']; 124 $oOb=M("order"); 125 $orderArr=$oOb->field("count(*) as num")->where("orderId='{$orderId}'")->select(); 126 $num=$orderArr[0]['num']; 130 $date=date("Y-m-d H:i:s"); 131 if($num==0){ 132 $coOb=M("cardorder"); 133 $arr=$coOb->where("orderId='{$orderId}'")->select(); 134 //echo "<pre>";var_dump($arr);echo "</pre>"; 135 $pid=$arr[0]['pid']; 136 $coOb->query("update r_cardorder set status=2,updateTime='{$date}' where orderId='{$orderId}'"); 137 //echo $coOb->getLastSql(); 138 $cOb=M("card"); 139 $cOb->query("update r_card set store=store-1 where id={$pid}"); 140 $cArr=$cOb->where("id={$pid}")->select(); 141 $buyedOb=M("buyedcard"); $type = $cArr[0]['type']; 152 $buyedArr=array("CCID"=>$arr[0]['CCID'],"type"=>$type,"beginTime"=>$cArr[0]['beginTime'],"endTime"=>$cArr[0]['endTime'], "data"=>$cArr[0]['data']); 153 $re2=$buyedOb->data($buyedArr)->add(); 154 $yhqId=$arr[0]['yhqId']; 155 if($yhqId!=0){ 156 $yOb=M("yhq"); 157 $yOb->query("update r_yhq set status=2,updateTime='{$date}' where id={$yhqId}"); 158 } 159 160 }else{ 161 $arr=$oOb->where("orderId='{$orderId}'")->select(); 162 //var_dump($arr); 163 $pid=$arr[0]['pid']; 164 $oOb->query("update r_order set status=2 ,updated_at='{$date}' where orderId='{$orderId}'"); 165 $ob=M("product"); 166 $ob->query("update r_product set store=store-1 where id={$pid}"); 167 }
4.修改配置文件 index/config.php
共5个必传参数
//支付宝配置参数 36 'alipay_config'=>array( 37 'partner' =>'1234567890123456', //这里是你在成功申请支付宝接口后获取到的PID; 38 'key'=>'qwaszxasqwqi07jyl6eudgzdfcmtpmxu',//这里是你在成功申请支付宝接口后获取到的Key 39 'sign_type'=>strtoupper('MD5'), 40 'input_charset'=> strtolower('utf-8'), 41 'cacert'=> getcwd().'\\cacert.pem', 42 'transport'=> 'http', 43 ), 44 46 47 'alipay' =>array( 48 //这里是卖家的支付宝账号,也就是你申请接口时注册的支付宝账号 49 'seller_email'=>'xxx@xxx.cn', 50 //这里是异步通知页面url,提交到项目的Pay控制器的notifyurl方法; 51 //'notify_url'=>'http://www.xxx.com/index.php?m=Pay&a=notifyurl', 52 'notify_url'=>'http://www.xxx.com/alipay_notifyurl.php', 53 //这里是页面跳转通知url,提交到项目的Pay控制器的returnurl方法; 54 'return_url'=>'http://www.xxx.com/index.php?m=Pay&a=returnurl', 55 //支付成功跳转到的页面,我这里跳转到项目的Member控制器,myorder方法,并传参payed(已支付列表)
5.在html中将支付宝必要的参数传到PayAction.class.php 里的doalipay 中,html文件如下:
<form action="?m=Pay&a=doalipay" method="post" id="form"> 237 238 <div class="title1 clear"> 239 <div class="leftt"> 240 <img style="margin: 0.4em" src="{{$pArr.thumbimg}}" class="iconimg" width="100%"> 241 </div> 242 <div class="desc"> 243 <h2>{{$pArr.title}}</h2> 244 245 <div>价格:¥{{$pArr.price-$pArr.discount}} 元</div> 246 247 </div> 248 <input type="hidden" name="trade_no" value="{{$orderId}}"><!--订单号--> //必传 249 250 <input type="hidden" name="ordsubject" value="WiFi随身宝"><!--订单名称--> //必传 251 <input type="hidden" name="ordbody" value="{{$data}}"><!--订单描述--> //必传 252 </div> 253 254 255 <input type="hidden" name="ordtotal_fee" value="{{$pArr.price-$pArr.discount}}" id="priceNew"><!--总金额--> //必传 256 <input type="hidden" name="ordshow_url" value="http://m.heimiwifi.com/index.php?m=Product&a=detail_buy&id={{$pArr.id}}"><!--商品展示url--> //必传 257 258 </div> 259 260 <div class="card_pay"> 261 <div class="cp_title">选择支付方式</div> 262 <div class="pay_div clear pay_div1"> 263 <div class="pay_left"> 264 <img width="100%" src="__ROOT__/index/Tpl/images/checked.png" id="pay1"> 265 </div> 266 <div class="pay_middle"> 267 <img width="100%" src="__ROOT__/index/Tpl/images/alipayicon.png"> 268 </div> 269 <div class="pay_right clear pay_div2"> 270 <span class="p1">支付宝在线支付</span>
284 </div>
285 </div>
286 </div>
287
288 <div class="sureOrderBtn">
289 <div class="sure_left">
290 <h2 style="color:#e54a3e;">应付金额:¥<span id="totalprice">{{$pArr.price-$pArr.discount}}</span> 元</h2>
291 </div>
292 <div class="sure_right">
293 <img style="line-height:140px" width="100%" src="__ROOT__/index/Tpl/images/ok.gif" id="orderBtn" >
294 </div>
295
296 </div>
297 </form>