<%@ page language
="java" contentType
="text/html; charset=UTF-8"
pageEncoding
="UTF-8"%>
<%@ page
import="java.util.*"%>
<%@ page
import="com.alipay.util.*"%>
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html
>
<head
>
<meta http
-equiv
="Content-Type" content
="text/html; charset=UTF-8">
<title
>
</title
>
</head
>
<body
>
<%
String partner
= ""; //partner合作伙伴id(必须填写)
String privateKey
= ""; //partner 的对应交易安全校验码(必须填写)
//**********************************************************************************
//如果您服务器不支持https交互,可以使用http的验证查询地址
//String alipayNotifyURL = "https://www.alipay.com/cooperate/gateway.do?service=notify_verify"
String alipayNotifyURL
= "http://notify.alipay.com/trade/notify_query.do?"
+ "partner="
+ partner
+ "¬ify_id="
+ request.
getParameter("notify_id");
String sign
=request.
getParameter("sign");
//获取支付宝ATN返回结果,true是正确的订单信息,false 是无效的
String responseTxt
= CheckURL.
check(alipayNotifyURL
);
Map params
= new HashMap();
//获得POST 过来参数设置到新的params中
Map requestParams
= request.
getParameterMap();
for (Iterator iter
= requestParams.
keySet().
iterator(); iter
.
hasNext();) {
String name
= (String) iter.
next();
String[] values
= (String[]) requestParams.
get(name
);
String valueStr
= "";
for (int i
= 0; i
< values.
length; i
++) {
valueStr
= (i
== values.
length - 1) ? valueStr
+ values
[i
]
: valueStr
+ values
[i
] + ",";
}
params.
put(name, valueStr
);
}
String mysign
= com.
alipay.
util.
SignatureHelper_return.
sign(params, privateKey
);
//打印,收到消息比对sign的计算结果和传递来的sign是否匹配
//out.println(mysign+"--------------------"+sign);
if (mysign.
equals(request.
getParameter("sign")) && responseTxt.
equals("true") ){
out.
println("交易成功");
}
else
{
out.
println("交易失败");
}
%>
</body
>
</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″)。问题解决!