前几天公司的总监说网站支付宝支付完成后没有执行后台处理程序,之前没有写过支付宝接口,写之前在网上查了不少资料包括支付宝提供的资料。但是看别人的与自己写的差别还很大的,这次写的主要是关于测试方面的,关于接口中的其他参数的介绍前面有很多前辈已经写出来了,我就不在这里再说一遍了,我只是说一下关于测试的。
1. 关于notify_url与return_url参数
//支付类型 string payment_type = "1"; //必填,不能修改 //服务器异步通知页面路径
string notify_url = "http://www.sina.com"; //需http://格式的完整路径,不能加?id=123这类自定义参数http://www.chinamusic.com.s1.kingidc.net/ //页面跳转同步通知页面路径 string return_url = "http://www.baidu.com"; //需http://格式的完整路径,不能加?id=123这类自定义参数,不能写成http://localhost/ //卖家支付宝帐户 string seller_email = "***********@b.qq.com"; //必填 //商户订单号 string out_trade_no = horder_id.Value; //商户网站订单系统中唯一订单号,必填
支付宝支付完成后需要给咱们的网站传递一些参数。
这些参数是我们用来在后台处理的,例如我们的网站是一个下载**的网站需要下载币之类的,客户通过支付宝充值下载币,充值完成之后支付宝传给我们一下关于客户支付的一些信息与客户在我们网站的一些信息。
客户在我们网站中的信息支付宝是怎么知道的呢?这些信息都是在执行支付跳转到支付宝时我们传递给支付宝的信息,例如客户的ID,订单的信息,地址等等….
这些信息都是我们传递给支付宝的
//把请求参数打包成数组 SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>(); sParaTemp.Add("partner", Config.Partner); sParaTemp.Add("_input_charset", Config.Input_charset.ToLower()); sParaTemp.Add("service", "create_direct_pay_by_user"); sParaTemp.Add("payment_type", payment_type); sParaTemp.Add("notify_url", notify_url); sParaTemp.Add("return_url", return_url); sParaTemp.Add("seller_email", seller_email); sParaTemp.Add("out_trade_no", out_trade_no); sParaTemp.Add("subject", subject); sParaTemp.Add("total_fee", total_fee); sParaTemp.Add("body", body); sParaTemp.Add("show_url", show_url); sParaTemp.Add("extra_common_param", hmid.Value + "|" + xunibi.ToString() + "|xnb"); sParaTemp.Add("anti_phishing_key", anti_phishing_key); sParaTemp.Add("exter_invoke_ip", exter_invoke_ip);
上面这些参数中就包含我我们要传递的所有信息,有些参数可以为空,有些必须指定参数,例如企业的支付宝账户等。
其中notify_url 这个参数就是我们在支付成功后要进行后台处理页面的地址,一般都是http:/*****/notify_url .aspx
这个参数中的网址必须是在广域网上能访问到的,所以说必须得在服务器上运行才能调试支付宝,在本地localhost:上是不行的,因为支付宝服务器找不到这个地址。
支付宝这个跳转是隐形不可见的,不可见是对用户来说的,下面会有解释
关于用户不可见主要是因为还有return_url这个参数,这个参数就是用户支付完成后在客户端跳转的页面,这个也是支付宝服务器自动完成的。
支付宝传递到 notify_url.aspx 的数据后,我们在notify_url.aspx 这个页面收到支付宝传递的参数后要传递给支付宝一个信息,告诉支付宝我们收到这个信息了。
如果支付宝第一次发送这个参数但没有收到回应就会隔一段世间继续发送,这个时间是48小时之内。
而return_url这个客户端跳转页面的信息支付宝服务器只发送一次。
上面代码中填写的www.baidu.com 与www.sian.com 就是因为不了解这些 测试一下retutn_url与notify_url 的区别。
sb.Append("\r\n q.price"); _Context.user_cz_price.InsertOnSubmit(q); _Context.SubmitChanges(); } } } else { } //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— Response.Write("success"); //请不要修改或删除 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// } else//验证失败 { Response.Write("fail"); sb.Append("验证失败!"); } } else { Response.Write("无通知参数"); sb.Append("无通知参数"); } //-------------------------------------------------淫荡的分割线------------------------------------------------------------- Log.log(sb.ToString());
上面的这段代码就是在notify_url .aspx.cs 中拷贝的 其中Response.Write("success"); 就是我们在接受到支付宝传递给我们的信息后需要发送的“确认”信息,
下面还有连个类别分别是验证失败与无通知参数。
2. 后台处理 notify_url .aspx.cs
在跳转支付宝支付时传递的那些参数具体都有什么用这个我没仔细的研究,但是这个支付宝给的文档上面有介绍。
关于用户在网站的一些信息原来是把他封装到 extra_common_param 这个参数中,包括客户的ID之类的东西,用 | 进行String 拼接字符串,
在支付宝传回 notify_url.aspx中的数据中还能找到这个参数。
用Request.Params["extra_common_param"]) 来获取,只有这个参数中的信息是我们的网站在支付之前要传递给我们的是我们的网站要在成功支付之后传递给我们的后台的,剩下的一些其他的信息就是支付宝传递给我们的了,包括客户支付的金额等。
我在测试的时候是把付款金额改成0.01元进行测试的,支付宝测试必须进行真是的付款。
//把请求参数打包成数组 SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>(); sParaTemp.Add("partner", Config.Partner); sParaTemp.Add("_input_charset", Config.Input_charset.ToLower()); sParaTemp.Add("service", "create_direct_pay_by_user"); sParaTemp.Add("payment_type", payment_type); sParaTemp.Add("notify_url", notify_url); sParaTemp.Add("return_url", return_url); sParaTemp.Add("seller_email", seller_email); sParaTemp.Add("out_trade_no", out_trade_no); sParaTemp.Add("subject", subject); sParaTemp.Add("total_fee", total_fee); //这个就是客户将要支付的金额 sParaTemp.Add("body", body); sParaTemp.Add("show_url", show_url); sParaTemp.Add("extra_common_param", hmid.Value + "|" + xunibi.ToString() + "|xnb"); //这个是我们自己打包的客户数据 sParaTemp.Add("anti_phishing_key", anti_phishing_key); sParaTemp.Add("exter_invoke_ip", exter_invoke_ip); //建立请求 string sHtmlText = Submit.BuildRequest(sParaTemp, "post", "确认"); Response.Write(sHtmlText);
代码最后的 sHtmlText 加密之后的各种参数信息
因为我这里的服务器上面没有装VS 我想一般的都不能装开发工具的,所以我想到了一个好办法。。。。。
那就是把没一部执行的信息都写入到网站的日志,也有说在IIS中的日志查看,但是我没有找到,所以只能自己调用网站的日志方法了
/// <summary> /// 记录信息 /// </summary> /// <param name="body">信息</param> public static void log(string body) { try { string timeStr=getTimeString(); string strbody="*******************"+timeStr+"*******************\r\n"; strbody+=body+"\r\n"; strbody+="*******************"+timeStr+"*******************\r\n"; strbody+="======>>错误地址:"+System.Web.HttpContext.Current.Request.RawUrl +"\r\n"; string filename=getFileName()+".log"; filename=System.Web.HttpContext.Current.Request.MapPath("/log/"+filename); StreamWriter swriter=new StreamWriter(filename,true,Encoding.Default,128); swriter.Write(strbody); swriter.Flush(); swriter.Close(); } catch {} }
上面的代码就是写入日志的代码,只要把写入的地址改一下就可以直接用了
我是事先定义的 StringBuilder sb = new StringBuilder();
然后在每一个要检验的代码后面 sb.Append("检验1 商户订单号=" + out_trade_no);
我这个一共是写了11个检验…
并且每一个检验之后都直接写入
q.mid = int.Parse(common_param[0]); q.price = q.price + num; sb.Append("\r\n q.price"); Log.log(sb.ToString()); //写入日志 _Context.user_cz_price.InsertOnSubmit(q); _Context.SubmitChanges();
为什么要这样做呢?
原因就是看一下代码执行到那一句停止了,在 notify_url .aspx 处理页面如果出错的话网站是不会报错的,所以我们只能执行一句写一句的日志,并把参数写进去看与我们设想的一不一致。
当然了 不是每一行代码后都写入,只是在一些我们拿不准的代码后面才写的。。。
把一些支付宝传过来的数据还有SQL的语句什么的写入日志就可以了,然后在去数据库中查看有没有执行
就是这些了,为了测试这个玩意花了我两毛钱………………