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', 53 //这里是页面跳转通知url,提交到项目的Pay控制器的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>
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>"; 即可
thinkphp接手机网站接口的更多相关文章
- 自己动手搞定支付宝手机网站支付接口 FOR ECShop
支付宝WAP网站版本的支付接口网上整合的比较少,看到很多网站在卖,顿觉无语. 主要是得自己查看支付宝官方提供的SDK中的开发文档. 支付宝sdk下载地址:https://doc.open.alipay ...
- Asp.Net支付宝手机网站支付接口API之C#版
一.准备工作 1.使用企业支付宝签约手机网站支付 2.下载支付宝官方demo 文档地址:https://doc.open.alipay.com/doc2/detail?treeId=60&ar ...
- 手机网站支付如何接入支付宝简易版支付功能PHP版
接入支付宝准备工作:(关于账号可以是个体商户也可以是企业账号但必须有营业执照) 1.登录蚂蚁金服开放平台 2.创建应用,应用分类网页应用和移动应用.应用提交审核审核通过后得到Appid才能调用相应的 ...
- 支付宝PC即时到账和手机网站支付同步
前几个月做了一个旅游网站,有PC站和手机站,涉及支付宝支付功能. 要求:PC站下的单,用户用手机登录也能支付;同理,手机站下的单,PC端登录也能支付. 附支付宝开放平台网址:即时到账 ,手机网站支付. ...
- 支付宝手机网站支付流程(Node实现)
前言 公司M站要接入支付宝,借机研究了一下支付宝的支付流程.毕竟,只有公司才能拿到支付接口权限. 主要参考文档: https://doc.open.alipay.com/doc2/detail?tre ...
- tp3.2 支付宝手机网站支付
手机网站支付接口,支付宝官方文档:https://b.alipay.com/signing/productSet.htm?navKey=all 第一步: 1)登陆支付宝企业账号 进入支付宝官网 ,登陆 ...
- 在laravel中使用支付宝手机网站支付 和 支付宝退款
1.在蚂蚁金服开放平台中申请对应的应用,并根据提示进行签约 2.给对应的应用信息 生成私钥和公钥(私钥会保存在本地,公钥会放在对应的应用信息中) 3.下载手机网站支付 对应的php sdk 4.将sd ...
- 支付宝开发之手机网站支付(H5支付)
其实官方的文档中:https://docs.open.alipay.com/203 介绍的已经很详细了,我就实地的看文档操作了一遍,具体步骤如下: 一.创建应用 流程如下: 首先要有支付宝开放平台: ...
- 请问IOS中做一个手机网站的app壳复杂吗?
公司开发了一个平台,手机网站已经做出来了,想开发一个苹果应用app,但公司没人会IOS开发,为了减小成本,现在想直接做一个壳来加载手机网站,请问在ios中复杂吗?是否有相应的控件直接加载url就行? ...
随机推荐
- FlexSlider插件的详细设置参数
FlexSlider是一个非常出色的jQuery滑动切换插件,它支持所有主流浏览器,并有淡入淡出效果.适合所有初级和高级网页设计师使用.不过很多人都只是使用默认的参数,今天来说说具体的参数来给大家看看 ...
- iOS-TextField知多少
iOS-TextField知多少 //初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRect ...
- OpenCV 3.0 VS2010 Configuration
Add in the system Path: C:\opencv\build\x86\vc10\bin; Project->Project Property->Configuration ...
- Linux环境下实现哲学家就餐问题(2)
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <string.h& ...
- java中.equals和==的区别?
Java中的equals是十分重要的,和= =要区别开来,孙卫琴的JAVA面向对象编程一书对这个做了阐述,现在小结其主要内容,而且要将 = =和 equals列为重要的对比概念来学习 1.声明格式 ...
- IOS第七天(1:UiTableView 的基本用法)
***表格控件 #import "HMViewController.h" @interface HMViewController () <UITableViewDataSou ...
- Android 通用流行框架大全
1. 缓存 DiskLruCache Java实现基于LRU的磁盘缓存 2.图片加载 Android Universal Image Loader 一个强大的加载,缓存,展示图片的库 Picas ...
- Scrum会议5
组名称:天天向上 项目名称:连连看 参会成员:王森(Master)张金生 张政 栾骄阳 时间:2016.10.20 已完成内容: 1.游戏中实现了两个按钮消除的算法. 2.在游戏中加入了音乐. 计划完 ...
- 动态input file多文件上传到后台没反应的解决方法!!!
其实我也不太清除具体是什么原因,但是后面就可以了!!! 我用的是springMVC 自带的文件上传 1.首先肯定是要有springMVC上传文件的相关配置! 2.前端 这是动态input file上传 ...
- Web 在线文件管理器学习笔记与总结(4)查看文件内容
② 查看文件内容 a.通过 file_get_contents($filename) 得到文件内容 b.通过 highlight_string($string) 或者 highlight_file($ ...