Java版支付宝接口开发

需求:调用支付宝接口的接口并集成到商城

调用支付宝接口所需要的“支付宝合作伙伴id”和“支付宝安全校验码”公司都给提供好了,支付宝官方那里也有该接口的“实物商品交易服务集成技术文档”及相关的DEMO源码。公司让我用JAVA来写,终于暂时不用再写JS了,嘿嘿…
文档里也没什么深奥的东西,就是一些参数说明之类的,本想借着文档和DEMO的源码,这个接口我应该能够很快搞定的,可没想到还是花了不少功夫。
所遇到的问题就是,在支付宝上明明支付成功了,但是跳转到商城上却提示交易失败。打开DEMO中的alipay_return.jsp文件。


XML/HTML代码


1. <%@ page language="java" contentType="text/html; charset=UTF-8"
2. pageEncoding="UTF-8"%>
3. <%@ page import="java.util.*"%>
4. <%@ page import="com.alipay.util.*"%>
5. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
6. <html>
7. <head>
8. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
9. <title>
10. </title>
11. </head>
12. <body>
13. <%   
14. partner = ""; //partner合作伙伴id(必须填写)   
15. privateKey = ""; //partner 的对应交易安全校验码(必须填写)   
16. //**********************************************************************************   
17. //如果您服务器不支持https交互,可以使用http的验证查询地址         
18. alipayNotifyURL = "https://www.alipay.com/cooperate/gateway.do?service=notify_verify"
19. alipayNotifyURL = "http://notify.alipay.com/trade/notify_query.do?"
20. partner="   
21.                      + partner   
22. notify_id="   
23.                      + request.getParameter("notify_id");   
24. sign=request.getParameter("sign");   
25.              //获取支付宝ATN返回结果,true是正确的订单信息,false 是无效的   
26. responseTxt = CheckURL.check(alipayNotifyURL);   
27.     
28. params = new
29.              //获得POST 过来参数设置到新的params中   
30. requestrequestParams
31. iter = requestParams.keySet().iterator(); iter   
32.                      .hasNext();) {   
33. name
34. values
35. valueStr = "";   
36. i = 0; i < values.length; i++) {   
37. valueStr = (i
38.                              : valueStr + values[i] + ",";          
39.                  }   
40.                  params.put(name, valueStr);   
41.          }   
42.     
43. mysign = com.alipay.util.SignatureHelper_return.sign(params, privateKey);   
44.     
45.              //打印,收到消息比对sign的计算结果和传递来的sign是否匹配   
46.              //out.println(mysign+"——————–"+sign);   
47.              if (mysign.equals(request.getParameter("sign")) && responseTxt.equals("true") ){   
48.     
49.                  out.println("交易成功");   
50.              }   
51.                  else   
52.              {   
53.                  out.println("交易失败");   
54.              }          
55. >
56. </body>
57. </html>


根据源码可以看出,支付失败无非就是responseTxt不为true或mysign与支付宝返回的sign不一致。将这几个参数打印出来之后,发现在支付宝那里成功支付后,这里的responseTxt是为true的,而mysign与sign值却不同。

从支付宝提供的文档中可以知道,sign是商城提交相关参数给支付宝,在支付宝那边根据参数生的MD5,支付成功后,支付宝会将商城提交的参数及其计算的sign值一并返回,而商城这边再根据这些参数生成一个MD5值mysign,通过比对这两个值以判断是否签名成功。

加密前的参数应该也都是一致的,怎么加密得到的结果不一样呢,后来想一想,同样值的字符串,以不同编码方式进行MD5加密得到的结果也不同。在提交数据给 支付宝时有一个_input_charset参数,用于指定所采用的编码方式,我这里用的是UTF-8,而发现支付宝提供的UTF-8版的DEMO中的过 滤器却将字符编码都转成了GBK,晕倒…可是改成UTF-8后问题依旧,难道过滤器没有对支付宝传递过来的参数起作用?于是修改 alipay_return.jsp文件,在params.put(name, valueStr)之前加了valueStr = new String(valueStr.getBytes(”iso8859-1″),”utf-8″)。问题解决!