集成支付宝支付服务流程详解[面向 java c# php]

原文地址:http://www.cnblogs.com/nidakun/archive/2012/08/20/2647465.html


return_url.asp 是用户点击返回商城取货,或者页面自动跳转的地址,在这一页里,你可以将获取的返回结果写到数据库里。但是如果用户在页面跳转前关了页面,你将无法获得支付结果。这个跳转只有一次。

notify_url.asp 是在交易完成后,支付宝24小时内对你的服务器定时发起的请求页面,其中请求中包含了各种你需要的查询字符串。你如果设置了这一页,你就可以在这一页对查询字符串进行处理,成功后返回success,支付宝将不会继续请求这个页面。

如果你在以前的同步跳转页面因为某些原因,比如用户将浏览器关闭,或者你的服务器出了问题等,没有将交易订单处理成功,你就可以在notify_url.asp再处理一次,成功后返回sucess.如果你在之前的同步中已经处理成功了,则这一次就不需要再写数据库了,直接返回sucess就行了。

 

 

 

 

服务器异步通知页面

 

引用:http://www.oschina.net/question/163900_24009

原因: 买家支付完成后,当前界面会停留在支付宝的交易付款成功的提示界面上,如:

该页面有短暂的停留时间,买家看到这个提示信息后有可能会把当前页面关掉,导致页面没有自动跳转回商户网站(return_url)使得商户的业务数据没有被处理(如:订单没有更新)。出现这种情况的原因是:商户网站的支付宝接口并没有利用服务器异步通知页面文件(notify_url)或是该页面在订单执行过程中也出现异常。 解决方法: 解决人员:商户网店开发、维护或管理的程序开发技术人员、商户网店系统提供商 解决步骤: 1、打开return_url页面文件(参数参数return_url对应返回文件),找到已经编写好的业务逻辑处理程序代码段,对其增加防止该笔交易被重复处理判断。 2、打开notify_url页面文件(参数参数notify_url对应返回文件),找到可插入商户的业务逻辑处理程序代码的地方,编写与return_url页面文件中相类似的程序,也需要包含防止该笔交易被重复处理的判断。 修改完成后效果: 当买家关掉自动跳转回商户网站的返回页面(参数return_url对应的return_url返回文件)时,商户的业务处理依旧被notify_url页面文件所执行,因此就不会发生业务没有同步的现象出现(如:订单没有被更新) 注意: 1、注意获取值的方式,notify_url页面文件的获取方式如:request.form("参数名 ")、$_POST['参数名'],return_url页面文件的获取方式,如:request.querrystring("参数名 ")、$_GET['参数名'] 2、notify_url文件的特性是: 1、 必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等; 2、 该页面中获得参数的方式,需要使用POST方式获取,如: request.Form(“out_order_no”)、$_POST['out_order_no']; 3、 支付宝主动发起通知,该方式才会被启用; 4、 只有在支付宝的交易管理中存在该笔交易,且发生了交易状态的改变,支付宝才会通过该方式发起服务器通知(即时到账中交易状态为“等待买家付款”的状态默认是不会发送通知的); 5、 服务器间的交互,不像页面跳转同步服务器异步通知页面可以在页面上显示出来,这种交互方式是不可见的; 6、 第一次交易状态改变(即时到账中此时交易状态是交易完成)时,不仅页面跳转同步通知页面会启用,而且服务器异步通知页面也会收到支付宝发来的处理结果通知; 7、 程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。 在25小时内完成6~10次通知(通知频率:5s,2m,10m,15m,1h,2h,6h,15h); 8、 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付宝会收不到success字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知; 9、 cookies、session等在此页面会失效,即无法获取这些数据; 10、 该方式的调试与运行必须在服务器上,即互联网上能访问; 11、 该方式的作用主要防止订单丢失,即页面跳转同步服务器异步通知页面没有处理订单更新,它则去处理; 12、 通知ID(参数notify_id)只有一分钟有效期,超过一分钟该次通知会验证失败。一旦验证成功下次再验证就会失效。 "如果您依照以上方法还无法解决,可提交集成申请,我们的技术支持会及时与您联系,协助您解决。 申请地址:https://b.alipay.com/support/helperApply.htm?action=supportHome"

 

 

if (Request.Form["trade_status"] == "WAIT_BUYER_PAY")// 判断支付状态_等待买家付款(文档中有枚举表可以参考) 

//更新自己数据库的订单语句,请自己填写一下 
string strOrderNO = Request.Form["out_trade_no"];//订单号 
string strPrice = Request.Form["total_fee"];//金额 如果你申请了商家购物卷功能,在返回信息里面请不要做金额的判断,否则会校验通过不了。 

else if (Request.Form["trade_status"] == "TRADE_FINISHED" || Request.Form["trade_status"] == "TRADE_SUCCESS")// 判断支付状态_交易成功结束(文档中有枚举表可以参考) 

//更新自己数据库的订单语句,请自己填写一下 
string strOrderNO = Request.Form["out_trade_no"];//订单号 
string strPrice = Request.Form["total_fee"];//金额 

else 

//更新自己数据库的订单语句,请自己填写一下 

Response.Write( 
"success"); //返回给支付宝消息,成功,请不要改写这个success 
//success与fail及其他字符的区别在于,支付宝的服务器若遇到success时,则不再发送请求通知(即不再调用该页面,让该页面再次运行起来), 
//若不是success,则支付宝默认没有收到成功的信息,则会反复不停地调用该页面直到失效,有效调用时间是24小时以内。

 

-------------------------------------------------------------------接口原理-------------------------------------------------------------------

 

二、 工作原理 
大家对结构部分已经有所了解,那么我们就开始分析具体的这个接口是如何运作的。 
a) 接入部分原理 
i. 第一步——选定参数信息: 
结合技术文档以及接口代码DEMO,选定传递给支付宝服务器的参数,以实物标准双接口为例。如必传项service、partner、seller_email、sign、sign_type、out_trade 
_no、price、subject、quantity、payment_type以及最少一组的物流信息参数三个logistics_type、logistics_fee、logistics_payment 
等,选填项body、discount、show_url等。 
以ASP.NET C#语言代码程序为例: 

string service = "trade_create_by_buyer"; 
string seller_email = "aaaa@126.com"; 
string sign_type = "MD5"; 
string key = "********************************"; 
string partner = "2088************"; 
string _input_charset = "utf-8"; 
string show_url = "http://www.alipay.com/"; 
string out_trade_no = TxtOrderno.Text.Trim(); 
string subject = TxtSubject.Text.Trim(); 
string body = TxtBody.Text.Trim(); 
string price = TxtPrice.Text.Trim(); 
string quantity = TxtQua.Text.Trim(); 
string logistics_type = "POST"; 
string logistics_fee = TxtPost.Text.Trim(); 
string logistics_payment = "BUYER_PAY"; 
string notify_url = "http://www.xxx.com/swnet05utf8/Alipay_Notify.aspx"; 
string return_url = "http://www.xxx.com/swnet05utf8/Alipay_Return.aspx"; 

ii. 第二步——排序: 
把这些参数的变量名(即技术文档里给出的变量名,以这种方式组合:service=”trade_create_by_buyer”作为一串字符串)按从a到z的顺序依次排序。以ASP.NET C#语言代码程序为例,该功能在ALIPAY.CS类中;以ASP代码中的程序为例,该功能在alipayto/Alipay_Payto.asp文件中。 
iii. 第三步——加密: 
目前一般的加密方式是MD5,不论是哪种加密方式,要加密的信息是要传给支付宝的信息,且存在于技术文档中,而非自定义的变量名。对以上排序好的所有参数(不包括网关参数即:string gateway = "https://www.alipay.com/cooperate/gateway.do?" ;)以循环的方式,用‘&’字符拼接成一长串字符串(这里需要注意,所有的参数都是&字符来拼接的,拼接后直接再拼接安全校验码Key, 在程序中大家可看到,这个key是直接加到该字符串后面而没有用&字符 ),之后进行加密。得出的加密字符串集存储于sign这个参数中。 
iv. 第四步——拼接字符串成URL链接 
我们已经拿到了各个参数、参数所属的值以及加密得出的加密字符串,那么手上现在的所有参数信息的格式,应当都是一组一组的 service=”trade_create_by_buyer”这种格式的字符串,拼接的话,则依靠循环的方式遍历所有的这种字符串,因为这次的拼接是要成URL链接,所以之前排除在外的网关gaetway和加密类型参数sig 
n_type也都会被拼接进来,那么,连接的字符则用大家所熟知的字符’&’,就这样得出一个完整的URL链接地址,如: 

https://www.alipay.com/cooperate/gateway.do?s...3d199ba&sign_type=MD5 

该链接来自支付宝官方的技术文档“标准实物双接口技术文档” 
v. 第五步——自动跳转 
第四步中已经运算得出的URL链接字符串,我们则要让其活起来,那么活起来的方式就是——用程序调用它,也就是所谓的页面自动跳转。这样就能跳到支付宝的官方收银台页面。 
可以说,现在已经成功的把支付宝接口融合进了大家自己的网站中,且能够使用支付宝来进行付款了。 
b) 通知返回部分原理 
i. 专业术语 
通知返回是两个页面,即传递给支付宝时的notify_url参数所对应的页面文件(asp.net的是Alipay_Notify.aspx、asp的是Alipay_Notify.asp)称之为通知页,传递 
给支付宝时的return_url参数所对应的页面文件(asp.net的是Alipay_Return.aspx、asp的是return_Alipay_Notify.asp)称之为返回页。 
ii. 通知返回原理 
1. 第一步——验证是否是支付宝服务器发来的请求: 
a) 以asp程序代码为例: 

alipayNotifyURL = "http://notify.alipay.com/trade/notify_query.do?" 
alipayNotifyURL = alipayNotifyURL &"partner=" & partner & "&notify_id=" & request("notify_id") 
Set Retrieval = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0") 
Retrieval.setOption 2, 13056 
Retrieval.open "GET", alipayNotifyURL, False, "", "" 
Retrieval.send() 
ResponseTxt = Retrieval.ResponseText 
Set Retrieval = Nothing 

得到的便是ResponseTxt的值,这是下面的步骤要用到的。 
b) 以asp.net C#程序代码为例: 

//获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求 
public String Get_Http(String a_strUrl, int timeout) 

string strResult; 
try 

HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(a_strUrl); 
myReq.Timeout = timeout; 
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse(); 
Stream myStream = HttpWResp.GetResponseStream(); 
StreamReader sr = new StreamReader(myStream, Encoding.Default); 
StringBuilder strBuilder = new StringBuilder(); 
while (-1 != sr.Peek()) 

strBuilder.Append(sr.ReadLine()); 


strResult = strBuilder.ToString(); 

catch (Exception exp) 


strResult = "错误:" + exp.Message; 


return strResult; 


调用部分: 

string alipayNotifyURL = "https://www.alipay.com/cooperate/gateway.do?service=notify_verify"; 
string partner = "2088************"; 

alipayNotifyURL = alipayNotifyURL + "&partner=" + partner + "&notify_id=" + Request.Form["notify_id"]; 

//获取支付宝ATN返回结果,true是正确的订单信息,false 是无效的 
string responseTxt = Get_Http(alipayNotifyURL, 120000); 

得到的便是ResponseTxt的值,这是下面的步骤要用到的。 
2. 第二步——排序: 
该部分的排序的原理与“接入部分”的原理“排序步骤”一样,值得注意的是 ,这里的参数是支付宝通知返回时,传回来的订单信息的各种参数以及值。http://www.k686.com/ 
3. 第三步——加密: 
该部分的加密原理与“接入部分”的原理“加密步骤”一样,依然值得注意的部分是加密的参数信息,这些参数信息是来源于上面一步骤排序好后的参数拼接起来的字符串来加密的。 
4. 第四步——判断: 
上面我们有得到加密的结果(命名为mysign吧)、检验是否是支付宝发来的消息的正确性ResponseTxt、以及通过POST或GET的方式得到的sign参数的值,那么这个判断的含义便是通知返回里最重要 
的部分了,因为它是来检验下面的程序是否执行我们的数据处理的。如何判断呢?各语言程序代码中,都是把加密得出的结果mysign与从支付宝那或得到的sign的值进行比较,并且还要让reponseTxt这个的 
值要等于true,这样才达到验证成功。值得注意的是 ,大家都有遇到过这种事,支付部分即接入部分的确是做好了,但为什么无法与支付宝的交易信息同步,出现的问题就在这个判断上没有成功,下面的第五部分则会详细说明。 
5. 第五步——自身网站的数据处理 
终于判断成功了,程序已经执行到了这里。各语言程序代码的这块地方的注释都写着“更新自己数据库的订单语句”或是“这里可以指定你需要显示的内容”。如字面上的意思,这块地方就是要我们大家来对这笔交易信息进行数 
据处理,即编写程序。这个说法大概专业了点,简单易懂的讲法便是,支付宝的交易成功的信息和其他的一切交易状态,自己的网站也能够对这笔订单同步起来,即支付宝里这笔订单的交易状态是“买家已付款等待卖家发货”, 
那么自己网站里显示的这笔状态也因如此,那么就应当在这里面写下诸如: 

if (Request.Form["trade_status"] == "WAIT_SELLER_SEND_GOODS")// 判断支付状态_买家付款成功,等待卖家发货(文档中有枚举表可以参考) 

//更新自己数据库的订单语句,请自己填写一下 
string strOrderNO = Request.Form["out_trade_no"];//订单号 
string strPrice = Request.Form["price"];//金额 
string sql = "update order_table set order_status = ‘买家已付款,等待卖家发货’ where order_no = " + strOrderNO; 
Update(sql); 


等数据库处理代码。 
iii. 存在的区别 
1. 大家仔细阅读代码不难发现,在通知页中程序运行时,获取参数的方法是用POST方式,而返回页中程序运行时,获取参数的方法是用GET方式。由此可知一些基本的信息——返回页传递回来的参数信息是储存在URL链接 
里的,而通知页的参数信息是不在URL链接里,也能从中推断出二者在功能上的差异。 
2. 大家可看到通知页面比返回页中多一个环节,那就是Response.Write("success"); 
作用上不同的详细说明,大家可以看下面的第四部分。http://www.k686.com/ 
------------------------------------------------------------------- 

三、 参数 
首先大家有个疑问,技术文档中的输入参数列表中给出了诸多参数,而手上拿到的代码里只写了一部分参数来进行传递信息,这究竟是为什么?那么我们先带着这个疑问往下看。 
以下讨论的参数不涵盖网关gateway、加密参数sign、加密类型sign_type,因为这些都是必须的。 
以实物标准双接口为例,可把参数看做几个功能部分组成 
a) 不可缺少的参数 
i. service服务参数,这个是用来区别这个接口是用的什么接口,所以绝对不能修改。 
ii. partner合作身份者ID、key安全校验码或称私钥这一组参数是签约合同生效后才能拿的到,partner是来鉴别是哪个商家与支付宝签约,而这个Key它如同钥匙般相当重要。 
iii. seller_email收款人支付宝账号,支付宝中有手机类型、电子邮件类型的支付宝账号是都可以用这个参数的。 
iv. subject在支付宝的收银台里是直接与商品名称关联在一起的,但是说的更准确些的话,这个参数是这笔交易的名称,因为这笔交易不一定只买一件商品。它的作用不仅是在收银台里可以清晰的显示出来,而且在支付宝的账 
户的交易明细的列表里,它也是排在第一列,由此可推测出,它有财务对账、作为交易查询的筛选条件等诸多作用。非常重要。 
v. out_trade_no技术文档中给出的是商户交易号(确保在商户系统中唯一),顾名思义这个就是我们大家自己网站的订单系统里的唯一订单号,而非支付宝的。这里需要强调的,这个订单号必须得是唯一的,如何唯一法?自己网站 
里订单系统的订单号是绝对唯一的吧,支付宝要求的唯一就是这个,为什么非要唯一?支付宝会根据订单号来判定这笔订单对于这个商家的所有交易中是否是唯一的。 
vi. price金额、quantity数量,这里设置有两种方式一种商品的单价金额,多个数量(即大于等于1)。另种是数量为1,金额代表总额,甚至是包含了运费。为什么大部分的客户要这么做?原因很简单,第一,购物车里的东西不一定是单纯的 
一件或者多件相同的商品,那么为商品设置金额时就有困难了,因此这里用总额是最好的,而数量就默认为1。第二,运费的设置很多客户是与各家快递公司签约、每件物品的快递费用也不尽相同,为了省去麻烦,在程序计算的 
时候干脆把运费也加进去。因此我们只需要记住一件事,这个price的金额就是所谓的总额了。 
vii. payment_type支付类型,没什么可说的直接写成1,无需改动。 
viii. 物流信息logistics_type、logistics_fee、logistics_payment这是一组物流信息,实物标准双接口中必须得至少有一组物流信息,也就是指这三个参数了,最多可有三组,哪三组呢?logistics_type_1、logistics_fee_1、 logistics_paymen 
t_1(第二组);logistics_type_2、logistics_fee_2、logistics_payment_2(第三组)。后两组为可选项。一般前面有说Price已经是总额了且包含了运费,那 
么这里物流运费就直接设置成0即可,即logistics_fee=”0”,其他两个的信息可参考技术文档来填写,因为要从技术文档中的枚举列表里来选择,所以绝不可乱填写。 
b) 可增加的有用参数 
i. 物流信息最多三组,最少一组,这已经在前部分有所提及,这里就不再细说。 
ii. _input_charset,当是UTF-8的编码格式时必须得用到且不允许为空的,即_input_charset=”utf-8” 
iii. notify_url、return_url,return_url代表支付完毕后可以自动从支付宝的官方页面跳转回来,notify_url这个是防止调单的首选最佳工具。 
iv. body,在支付宝收银台中的商品描述里显示,如果subject是订单名称的话,那么这个body则最准确的称之为订单描述,其实个人认为它作为备注之类的更为恰当。很多人都很郁闷支付宝为何不能像其他公司 
的接口有个自定义的参数来存放客户想要的东西,其实body也具有类似的这种功能,它不仅容纳的信息是所有参数里最大的,而且还是以字符串的形式储存,个人认为它其实也是非常重要的不可缺少的参数之一呢。 
v. discount折扣,顾名思义如果小于0,则是用原金额Price*quantity+(discount),实际金额便比原总额小了。现在有些商户有支付宝的优惠卷,而优惠卷的用途也是在这个参数中体现,具体做法与前 
面无异。 
vi. show_url商品展示地址,这个链接的作用是在支付宝收银台的商品链接旁边有个下划线“详情”的链接,而点链接弹出的一个新页面便是这个商品展示地址的页面。 
vii. 收货信息receive_name、receive_address、receive_zip、receive_phone、 receive_mobile,这些信息若也设置为传递给支付宝的参数之一的话,那么在支付宝收银台点选下一步的时候,本该出现的填写收货信息页面不见踪影,而直接跳到了收货信息页面的下一个页面去了。很多商户在自己的网站的购物 
流程中都有一个填写收货信息的选项卡,为了省去到支付宝收银台中还要填写一次收货信息的麻烦,那么这些收货信息的参数就派上用场了。值得注意的是,收货人姓名和地址是必填项,不然还是会出现收货信息填写页。 
viii. buyer_email买家支付宝账号,这个设置好后呈现的效果便是,原本是空的支付宝账号的输入框此时已经有个支付宝账号在里面放置。 
c) 剩下的参数无需理会 

整个实物标准双接口的参数介绍完毕,那么其他接口的参数还要介绍吗?大家从上面分析得出的东西对比技术文档的参数列表是否看出什么来了? 

1、 参数列表的最后一列叫“可空”,N代表不允许为空,Y代表允许为空,结合上面的不可缺少参数与增加的有用参数来进行比较,不难发现,不可缺少的参数全是为N的。 
2、 有些为Y的参数有一组,例如buyer_email、buyer_id,凡是遇到这种的一般都是二可选一也可都不选,或是二必选一。举例说明:二必选一的是seller_email、seller_id,二选一的 
是buyer_email、buyer_id。 
所有的接口的参数如此分析就能判断出哪些是重要参数哪些可不要,结合技术文档与程序接口来研究就能一目了然。 
-------------------------------------------------------- 

四、 通知返回 
a) 返回页 
传递给支付宝时的return_url参数所对应的页面文件。 
具备的属性: 
1、支付接口中买家的购买流程已经走到支付宝里且支付宝提示支付成功时,页面会自动跳转回自身网站的这个页面里来。 
2、同步的,无时差 
3、获得参数的方法是用get方式获取。 
4、不论跳转回来程序判断是真还是假(if(sign = mysign and responseTxt = true))只跳转回来一次,不重复。 
5、这个并不是支付宝服务器调用了该页面,而是通过与组合拼接各参数形成的URL链接原理等同,拼接出来的URL链接,之后程序上做自动跳转。 
6、基于5的原因,该页面的程序调试可不必在服务器上而是本机上调试、运行。 
b) 通知页 
传递给支付宝时的notify_url参数所对应的页面文件 
具备的属性: 
1、这个通知页就是被支付宝调用才能启动的。 
2、服务器间的互动,不像返回页肉眼可以看到,这个是看不到的。 
3、获得参数的方法是用POST方式获取。 
4、支付宝中的该笔交易存在,且该笔交易状态发生了变更,就会被调用。 
5、被调用程序判断(if(sign = mysign and responseTxt = true)),若我们自己在该判断中有做程序编写,成功则不再被调用,不成功则会反复被调用。 
6、异步的,第一次收到订单信息(以下都称之为“通知”)是与返回页近乎等同或等同的同步时间,在判断不成功的情况下,会收到第二次第三次等次数的通知,时间间隔从最先的一两分钟,到后面的几个小时。失效时间是4 
8小时。 
7、基于6的原因,该页面的程序调试必须在服务器上调试、运行。 
8、程序编写时必须采用程序执行成功,才写页面response.Write(“success”);,不成功则写页面response.Write(“fail”); 支付宝根据success来判定是否要重新再次发送通知。 
9、该页面的Html页面中必须是空白、无任何Html标签、无任何空格、不允许做页面跳转。 

以C# ASP.NET实物标准双接口代码为例: 

if (mysign == sign && responseTxt == "true") 

if (Request.Form["trade_status"] == "WAIT_BUYER_PAY")// 判断支付状态_等待买家付款(文档中有枚举表可以参考) 

//更新自己数据库的订单语句,请自己填写一下 

else if (Request.Form["trade_status"] == "WAIT_SELLER_SEND_GOODS")// 判断支付状态_买家付款成功,等待卖家发货(文档中有枚举表可以参考) 

//更新自己数据库的订单语句,请自己填写一下 
string strOrderNO = Request.Form["out_trade_no"];//订单号 
string strPrice = Request.Form["price"];//金额 
string sql = "update order_table set order_status = '买家已付款,等待卖家发货' where order_no = @out_trade_no"; 
Update(sql,para); 

else if (Request.Form["trade_status"] == "WAIT_BUYER_CONFIRM_GOODS")// 判断支付状态_卖家已发货等待买家确认(文档中有枚举表可以参考) 

//更新自己数据库的订单语句,请自己填写一下 
string strOrderNO = Request.Form["out_trade_no"];//订单号 
string strPrice = Request.Form["price"];//金额 
string sql = "update order_table set order_status = '卖家已发货,等待买家确认收货' where order_no = @out_trade_no"; 
Update(sql, para); 

else if (Request.Form["trade_status"] == "TRADE_FINISHED")// 判断支付状态_交易成功结束(文档中有枚举表可以参考) 

//更新自己数据库的订单语句,请自己填写一下 
string strOrderNO = Request.Form["out_trade_no"];//订单号 
string strPrice = Request.Form["price"];//金额 
string sql = "update order_table set order_status = '交易成功' where order_no = @out_trade_no"; 
Update(sql, para); 

else 

//更新自己数据库的订单语句,请自己填写一下 


Response.Write("success"); 

else 

Response.Write("fail"); 


c) 在支付宝的众多接口中,不是所有的接口都拥有通知页与返回页的。 
有的接口只有返回页;有的接口有通知页且用XML格式的内容显示在当前页面中;有的没有通知页也没有返回页仅仅只以XML格式的内容显示在当前页面中。所以,我们要根据各接口的技术文档与程序实例来做相应的数据处 
理。 
d) 大家这里存在一个疑问,一般大家的做法都是把数据库更新些在返回页中,但是很多情况下出现了订单不同步即掉单现象。这是为什么? 
答:返回页是当前页面自动跳转的,这虽然跳转的反应速度不错,但人的手动关闭该页面操作绝对可以使之在没有跳转回来之前就关掉了该页面,此时原本该数据库更新的程序并没有被启动,这样直接导致了掉单,所以一般大商 
户,尤其是网络游戏行业的即时到帐充值的技术做法是:返回页中有订单处理程序,通知页中也有,当返回页中的订单没做过处理时,通知页中的数据处理程序便启动;这样即可近乎100%解决掉单问题(还有种掉单原因是大家自己的服务器出现问题,比如MS3XML.DLL问题,这个问题至今没有什么可以解决的办法,只能重装或是更换服务器,也有的服务器因为中毒才导致的)。本文来源于 http://www.k686.com/ 
------------------------------------------------- 

五、 调试 
接入部分做好了,通知返回部分也做好了,那么开始调试吧。 
调试也分成两大部分来做。 
a) 部分网站用了框架模式frame,但这个并不适用支付宝的接口程序,因此绝对不能把支付宝的接口页面置于整个网站的框架之下。 
b) 确定好要用POST还是GET方式来传递参数,二者不能混用。由于有些网站中不一定只有一个接口入口,所以整个网站都必须保持一致性,不能这个接口用POST,那个接口用GET,这样直接导致后续出现一系列连查找 
原因都极其困难的现象。 
c) 接入部分的调试工作,则是输入支付宝要求的格式的值,如subject、body的值不允许有非法字符、金额格式必须是小数点后两位数或是正整数且不是金额格式(即$123.00),以及非常重要的一个原则,传递的参数要么不传递这个参数(即传递的众多参数中,这个参数完全不存在),要么这个参数不允许为空。很多人在调试时支付出现一系列“调试错误”有很大的一部分原因就是参 
数的设置存在问题。 
d) 编码格式一定要确认再确认,在支付时直接出现“调试错误,SIGN不对”只有两种原因,一是C部分已提到的参数的设置问题,另一个便是这个编码格式的问题。编码格式是非常重要的,绝对不能这个地方用GBK,另个地方用utf-8。 
e) 通过接口走一次真实的操作,若是支付接口,则走一笔真实的交易,金额则是0.01元(支付宝是没有测试环境的,所以请老实的使用自己签约的号去走真实交易),不要觉得很麻烦,也不要把这个工作交个经理或者你的老板 
来做,因为它直接关系到你后续的操作步骤与调试的顺畅程度。 
f) 返回部分在本机电脑上就可以调试完毕,之前有提到不要把支付测试工作交给自己以外的其他人,这里就可以得到充分的说明,不论是哪种语言都拥有自己风格的单步监控程序代码的能力,返回部分就要一步一步监控程序的执行,确保1、是否执行到了“mysign == sign && responseTxt == "true"”,这个IF语句的判断;2、是否进入了这个语句里而不是else里;3、数据库更新程序是否执行成功,而不是卡着不动了;4、数据库更新完毕后,程序是否走完。基本出现问题的地方就在第一步,所以不要 
觉得奇怪为什么掉单? 
g) 通知页的调试,这个调试就比较麻烦了,首先这个支付宝接口已经完成且放在了服务器上,别人可以通过互联网来进行支付;其次,要把通知页中的“写日志”程序启动起来,日志内容主要记录trade_status、tr 
ade_no、out_trade_no、price、sign、mysign、responseTxt等。一般出现的原因依旧是“mysign == sign && responseTxt == "true"”这个判断上不被通过。 
具体检测方式: 
1、直接用互联网访问http://www.xxx.com/alipay/notify_url.asp 
访问是否能够访问得到,且显示"fail"的字眼,其他如空白或是其他程序错误提示等内容,均属程序执行出错。 
2、程序是否执行到,sign=mysgin and responseTxt = "true"这个判断中,如果执行到这个判断时跳到ELSE的判断语句去了,则表示您的接口程序在支付时传递的参数信息或是您的编码格式、合作身份者ID与安全校验码的设置存在问题。 
3、程序已经执行到sign=mysgin and responseTxt = "true"这个判断中,却没有执行到response.Write("success")这句话,说明您自己编写进去的程序代码执行出错,请检查。 

---------------------------------------------------------- 

六、 其他 
a) 有些接口,例如支付的接口,是支持POST或者GET方式传递参数的。 
i. POST传递方式: 
这里需要注意的地方是:<form action=” aliay_url” …>中action的值是网关+编码格式参数,即https://www.alipay.com/cooperate/gateway.do? _input_charset=utf-8,GBK的编码格式可以为:https://www.alipay.com/cooperate /gateway.do?。 
ii. GET传递方式: 
是用&字符来连接起来的一长串URL链接字符串,通过自动跳转不是<form action=” aliay_url” …>的方式来存放,而是用Response.Redirect(aliay_url)方式来进行跳转。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值