thinkphp接手机网站接口

首先说下,支付宝提供的demo不一定完全正确,可能回缺少些步骤,所以,最好按照规则文档的步骤参照demo写。

先说遇到的问题:

1.错误0001,缺少partner、service等必参数

最初选择的sign_type ='0001' 即rsa 的加密方式,需要用到公钥和私钥。公钥和私钥在支付宝的demo中都有,只是,如果使用支付宝的公钥和私钥大家都知道,不太安全。所以,一般应该在自己的电脑上生成一个公钥和私钥http://hmifly.blog.163.com/blog/static/128583507201403111438312,公钥是用来加密的,私钥是用来解密的,所以我们项目中用的公钥是支付宝默认的公钥和私钥是自己生成的私钥,然后将自己生成的公钥上传到支付宝。这样,我们传给支付宝的数据通过支付宝默认的公钥加密,然后支付宝通过自己默认的私钥解密;而支付宝返回来的数据,通过我们上传的公钥加密,然后会穿到我们的项目中后,我们通过自己生成的私钥解密。流程是这样的,但后来闲麻烦,选择了MD5加密的方法,所以就不用公钥个私钥了。

2.错误0004,req_data 传参格式不正确

这是因为,在个支付宝传参时,用的是xml格式,而我们上传的nofifyurl  和returnurl等参数中包含&等特殊符号,后来,我将这部分数据改写成一个www.XXX.com/alipay_returnurl.php  ,然后指向方法returnurl。然后数据就传过去了。或者可以通过<![CDADA[ $URL]]>,将含有特殊字符的链接地址阻止“编译”。

 下面说下具体步骤:

1.和接及时到账接口一样,将支付宝的几个类和方法文件包含到Vender下

2.新建一个PayAction.class.php文件

接收参数较网站即时到账略有不同 

<?php
  2 header("content-type:text/html;charset=utf-8");
  3 class  PayAction extends  Action{
  4 
  5     //在类初始化方法中,引入相关类库    
  6     public function _initialize() {
  7 
  8 
  9         //wap端的
 10         vendor('AlipayWap.CorefunctionWap');
 11         vendor('AlipayWap.Md5functionWap');
 12         vendor('AlipayWap.NotifyWap');
 13         vendor('AlipayWap.SubmitWap');
 14         vendor('AlipayWap.RsafunctionWap');
 15 
 16     }
 17 
 18 
 19      //wap端的
 20 
 21        public function doalipay(){
 22         //echo "<pre>";var_dump( $_SERVER );echo "</pre>"; 
 23         //返回格式
 24         $format = "xml";//必填,不需要修改//返回格式
 25         $v = "2.0";
 26         //这里我们通过TP的C函数把配置项参数读出,赋给$alipay_config;
 27         $alipay_config=C('alipay_config');
 28 
 29         /**************************请求参数**************************/
 30         $payment_type = C('alipay_config.sign_type'); //支付类型 //必填,不能修改
 31         $notify_url = C('alipay.notify_urlWap'); //服务器异步通知页面路径
 32         $return_url = C('alipay.return_urlWap');//页面跳转同步通知页面路径
 33         $merchant_url = C('alipay.merchant_urlWap');//操作中断返回地址
 34         $seller_email = C('alipay.seller_email');//卖家支付宝帐户必填
 35         $out_trade_no = $_POST['trade_no']; //商户订单号 通过支付页面的表单进行传递,注意要唯一!
 36         $subject = $_POST['ordsubject'];  //订单名称 //必填 通过支付页面的表单进行传递
 37         $total_fee = $_POST['ordtotal_fee'];  //付款金额  //必填 通过支付页面的表单进行传递
 38         $body = $_POST['ordbody'];   //订单描述 通过支付页面的表单进行传递
 39         $show_url = $_POST['ordshow_url'];//商品展示地址 通过支付页面的表单进行传递
 40         $anti_phishing_key = "";//防钓鱼时间戳 //若要使用请调用类文件submit中的query_timestamp函数
 41         //$exter_invoke_ip = get_client_ip();//var_dump($exter_invoke_ip);die();   //客户端的IP地址 
 42         $exter_invoke_ip = $_SERVER["REMOTE_ADDR"];//var_dump($exter_invoke_ip);die();   //客户端的IP地址 
 43         /************************************************************/
 44 
 45         //对前台传过来的价钱数据做判断
 46         $orderId=$out_trade_no;
 47         $oOb=M("order");
 48         $orderArr=$oOb->field("count(*) as num")->where("orderId='{$orderId}'")->select();
 49         $num=$orderArr[0]['num'];
 50         if($num==0){
 51            $coOb = M("cardorder");
 52            $arr = $coOb->where("orderId='{$orderId}'")->select();
 53            //var_dump($arr);
 54            $realPrice = $arr[0]['price'] - $arr[0]['discount'] - $arr[0]['yhqPrice'];
 55            //var_dump($total_fee); var_dump($realPrice); die;
 56            if($total_fee != $realPrice){
 57                header("location:index.php?m=Member&a=payFail");
 58            }
 59         }else{
 60 
 61            $arr=$oOb->where("orderId='{$orderId}'")->select();
 62            $realPrice = $arr[0]['price'] - $arr[0]['discount'] - $arr[0]['yhq'];
 63 
 64            if($total_fee != $realPrice){
 65                header("location:index.php?m=Member&a=payFail");
 66            }
 67         }
 68         $call_back_url = $return_url;
 69         //请求业务参数详细
70         $req_data = '<direct_trade_create_req><notify_url>' . $notify_url . '</notify_url><call_back_url>' . $call_back_url . '</           call_back_url><seller_account_name>' . $seller_email . '</seller_account_name><out_trade_no>' . $out_trade_no . '</                         out_trade_no><subject>' . $subject . '</subject><total_fee>' . $total_fee . '</total_fee><merchant_url>' . $merchant_url . '</              merchant_url></direct_trade_create_req>';
 71         //echo "req_data";var_dump($req_data);echo "----------------------------------";
 72         //必填
 73         //构造要请求的参数数组,无需改动
 74         $para_token = array(
 75                 "service" => "alipay.wap.trade.create.direct",
 76                 "partner" => trim($alipay_config['partner']),
 77                 "sec_id"    => $payment_type,
 78                 "format"    => $format,
 79                 "v" => $v,
 80                 "req_id"    => $out_trade_no,
 81                 "req_data"  => trim($req_data),
 82                 "_input_charset"    => trim(strtolower($alipay_config['input_charset']))
 83                 );
 84         //echo "<pre>";var_dump($para_token);echo "</pre>";die();
 85         //建立请求
 86         $alipaySubmit = new AlipaySubmit($alipay_config);
 87 
 88         $html_text = $alipaySubmit->buildRequestHttp($para_token);
 89         //var_dump($html_text);die();
 90         //URLDECODE返回的信息
 91         $html_text = urldecode($html_text);
 92         //echo "<pre>";var_dump($html_text);echo "</pre>";die();
 93         //解析远程模拟提交后返回的信息
 94         $para_html_text = $alipaySubmit->parseResponse($html_text);
 95         //var_dump($para_html_text);die;
 96         //获取request_token
 97         $request_token = $para_html_text['request_token'];
 98 
 99         //var_dump($request_token);
102         /**************************根据授权码token调用交易接口alipay.wap.auth.authAndExecute**************************/
103 
104         //业务详细
105         $req_data = '<auth_and_execute_req><request_token>' . $request_token . '</request_token></auth_and_execute_req>';
106         //必填
107 
108         $parameter = array(
109                 "service" => "alipay.wap.auth.authAndExecute",
110                 "partner" => trim($alipay_config['partner']),
111                 "sec_id"    => $payment_type,
112                 "format"    => $format,
113                 "v" => $v,
114                 "req_id"    => $out_trade_no,
115                 "req_data"  => trim($req_data),
116                 "_input_charset"    => trim(strtolower($alipay_config['input_charset']))
117                 );
118         //var_dump($parameter);die();
119         $parameter1 = paraFilter($parameter);
120         $parameter2 = argSort($parameter);
121         //建立请求
122         $alipaySubmit = new AlipaySubmit($alipay_config);
123         $mysign = $alipaySubmit -> buildRequestMysign($parameter2);
124         $parameter2['sign'] = $mysign;
125         //echo "<pre>";var_dump($parameter2);echo "</pre>";die();
126         $html_text = $alipaySubmit->buildRequestForm($parameter2,"get", "确认");
127         echo $html_text;
128         }
129 
130         function notifyurlWap(){
131 
132         $str= "111\n";
133         if(isset($_POST) && !empty($_POST)){
134             foreach($_POST as $k=>$v){
135                 $str .= $k ."=>".$v."\n";
136             }
137         }
138         file_put_contents("notifyurlWap.txt",$str,FILE_APPEND);
139         $alipay_config=C('alipay_config');
140         //计算得出通知验证结果
141         $alipayNotify = new AlipayNotify($alipay_config);
142         $verify_result = $alipayNotify->verifyNotify();
143         file_put_contents("notifyurlWap.txt",$verify_result,FILE_APPEND);
144         if($verify_result) {
145             //验证成功
146             file_put_contents("notifyurlWap.txt","验证成功",FILE_APPEND);
147             $doc = new DOMDocument();
148             file_put_contents("notifyurlWap.txt","doc对象成功",FILE_APPEND);
149             $notify_data = $_POST['notify_data'];
150             $doc->loadXML($notify_data);
151             file_put_contents("notifyurlWap.txt",unserialize($doc),FILE_APPEND);
152             if( ! empty($doc->getElementsByTagName( "notify" )->item(0)->nodeValue) ) {
153                 //商户订单号
154                 $out_trade_no = $doc->getElementsByTagName( "out_trade_no" )->item(0)->nodeValue;
155                 //支付宝交易号
156                 $trade_no = $doc->getElementsByTagName( "trade_no" )->item(0)->nodeValue;
157                 //交易状态
158                 $trade_status = $doc->getElementsByTagName( "trade_status" )->item(0)->nodeValue;
159                 $parameter = array(
160                     "out_trade_no"     => $out_trade_no, //商户订单编号;
161                     "trade_no"     => $trade_no,     //支付宝交易号;
162                     "trade_status"     => $trade_status, //交易状态
163                 );
164                 //file_put_contents("/index/paylog.txt",$parameter,FILE_APPEND);
165                 file_put_contents("notifyurlWap.txt",$out_trade_no,FILE_APPEND);
166                 file_put_contents("notifyurlWap.txt",$trade_no,FILE_APPEND);
167                 file_put_contents("notifyurlWap.txt",$trade_status,FILE_APPEND);
168                 if($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS')  {
169                     if(!checkorderstatus($out_trade_no)){
170                         orderhandle($parameter);
171                             //进行订单处理,并传送从支付宝返回的参数;
172                     }
173                 }
174                 echo "success";        //请不要修改或删除
175             }
176         }else {
177                 //验证失败
178                 echo "fail";
179         }
180         }
181 
182         function returnurlWap(){
183 
184         $alipay_config = C('alipay_config');
185         $alipayNotify = new AlipayNotify($alipay_config);//计算得出通知验证结果
186         $verify_result = $alipayNotify->verifyReturn();
187         //var_dump($_GET);
188         if($verify_result) {
189             //验证成功
190             //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表
191             $out_trade_no   = $_GET['out_trade_no'];      //商户订单号
192             $trade_no       = $_GET['trade_no'];          //支付宝交易号
193             $trade_status   = $_GET['result'];      //交易状态
194 
195             $parameter = array(
196                     "out_trade_no"     => $out_trade_no,      //商户订单编号;
197                     "trade_no"     => $trade_no,          //支付宝交易号;
198                     "trade_status"     => $trade_status,      //交易状态
199             );
200 
201             //echo "<pre>";var_dump($parameter);echo "</pre>";die();
202 
203             if($_GET['result'] == 'success' ) {
204                 if(!checkorderstatus($out_trade_no)){
205                     orderhandle($parameter); //进行订单处理,并传送从支付宝返回的参数;
206                     //die();
207                 }
208                 $this->redirect(C('alipay.successpage'));//跳转到配置项中配置的支付成功页面;
209             }else {
210                 //echo "trade_status=".$_GET['trade_status'];
211                 $this->redirect(C('alipay.errorpage'));//跳转到配置项中配置的支付失败页面;
212             }
213         }else {
214             //验证失败
215             //如要调试,请看alipay_notify.php页面的verifyReturn函数
216             echo "支付失败!";
217         }
218         }
219 
220 }

 

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个必传参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  //支付宝配置参数
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=notifyurlWap',
52       'notify_url'=>'http://www.xxx.com/alipay_notifyurl.phpWap',
53       //这里是页面跳转通知url,提交到项目的Pay控制器的returnurl方法;
54       'return_url'=>'http://www.xxx.com/index.php?m=Pay&a=returnurlWap',
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}}&nbsp;元</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>&nbsp;元</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>

 

tip:

可能整合完后在跳到支付宝页面时会有一个确定按钮,显示几秒钟后自动跳转,想要隐藏这个按钮,只要在支付宝提供的类文件submit.php中将方法buildRequestForm中的    $sHtml = $sHtml."<input type='submit' value='".$button_name."' ></form>";改成$sHtml = $sHtml."<input type='submit' value='".$button_name."' style='display:none;'></form>"; 即可

posted @ 2014-05-10 17:05  笑月儿  Views(1762)  Comments(0Edit  收藏  举报