支付宝接口支付成功后通过同步或异步跳转返回时,一般都要对数据来源做校验判断是否为真实支付宝提交过来的数据。
但是部分站点校验时
AlipayNotify.verify(params)
始终返回false。
经过分析返回为false的有几个原因
- request.getParameterMap()里的内容没有转换为正常的编码。如果有中文字符要通过编码转换为utf-8才能正常得到内容。
- 网络慢等原因,当第3方web得到支付宝返回参数中notifyid参数后去支付服务器验证时延迟超过了1分钟才完成。会导致支付宝那边验证失败。这个一般不会出现。
- 第3个原因,提供给支付宝接口中同步和异步回调方法中本身附加了一个本系统内部参数。如下pAction参数是第3方系统内部使用的。需要过滤掉。再调用验证模块才能成功。如下代码红色字体。(因为原demo中提供的2个url都是2个不带参数的jsp页面)
完整的检验来源代码段如下
//获取支付宝GET过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();)
{
String name = (String) iter.next();
if(name.equals("pAction"))continue; // pAction 参数是内部系统的参数要去掉。不能传给params检验
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] + ",";
}
//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
params.put(name, valueStr);
}
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
//商户订单号
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
//支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
//交易状态
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
//计算得出通知验证结果
boolean verify_result = AlipayNotify.verify(params);