目的:验证此次通知信息是否是支付宝服务器发来的信息,以帮助校验反馈回来的数据的真假性。

原理:获取支付宝返回数据之一的通知校验ID(notify_id),按照支付宝要求的格式拼接成要请求的链接,如:https://intlmapi.alipay.com/gateway.do?service=notify_verify&partner=2088002396712354¬ify_id=RqPnCoPT3K9%252Fvwbh3I%252BFioE227%252BPfNMl8jwyZqMIiXQWxhOCmQ5MQO%252FWd93rvCB%252BaiGg通过访问这个请求链接,利用编程方法来模拟http请求与支付宝服务器进行交互,获得支付宝服务器上处理的结果。 如果获得的信息是true,则校验成功;如果获得的信息是其他,则校验失败。

支付宝异步回调官方文档:https://global.alipay.com/docs/ac/global/notify_verify_cn

首先在项目中搭建好支付宝沙箱开发的demo环境,需要需注意查看以下几点:

1.获取支付宝POST过来反馈信息(notify_url.jsp):

Map<String,String> params = new HashMap<String,String>();
	Map<String,String[]> requestParams = request.getParameterMap();
	for (Iterator<String> 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] + ",";
		}
		//乱码解决,这段代码在出现乱码时使用
		valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
		params.put(name, valueStr);
	}

2.验证签名:这里有坑,官方给的代码中没有要求传入signType 参数,而代码中使用的是rsa算法 所以需要传入signType 将算法变为参数中的算法类型为自己AlipayConfig中设置的参数(rsa2)。
公钥是支付宝公钥,非应用公钥,这是一个细节方面

boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

注意:

  • 正确的验证异步通知的顺序是:
  • 收到异步通知后,先不要回复‘success’。否则会影响支付宝系统的行为(支付宝系统会对所有已经回复了 ‘success’的异步通知的验证请求返回false)
  • 调用这个接口来验证notify id.
  • 如果输入参数是无效的,支付宝会返回 ‘Invalid’
  • 如果异步通知是支付宝发出的并且验证请求是在异步通知发出后的1分钟内发起的,则返回‘True’
  • 如果该通知不是支付宝发送的,支付宝会返回 ‘False’
  • 如果验证请求在异步通知发送一分钟之后,支付宝会返回 ‘False’
  • 如果商家已经对异步通知返回了 ‘true’, 支付宝会返回 ‘False’
  • 异步通知一旦验证成功,商家需要回复 ‘Success’
  • 整个项目一定要在公网上运行测试,否则无法进行异步回调!!!!

做更好的自己~