BUG出现在类文件WxPayData.cs中的FromXml(string xml)方法
1 /** 2 * @将xml转为WxPayData对象并返回对象内部的数据 3 * @param string 待转换的xml串 4 * @return 经转换得到的Dictionary 5 * @throws WxPayException 6 */ 7 public SortedDictionary<string, object> FromXml(string xml) 8 { 9 if (string.IsNullOrEmpty(xml)) 10 { 11 Log.Error(this.GetType().ToString(), "将空的xml串转换为WxPayData不合法!"); 12 throw new WxPayException("将空的xml串转换为WxPayData不合法!"); 13 } 14 15 16 SafeXmlDocument xmlDoc = new SafeXmlDocument(); 17 xmlDoc.LoadXml(xml); 18 XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml> 19 XmlNodeList nodes = xmlNode.ChildNodes; 20 foreach (XmlNode xn in nodes) 21 { 22 XmlElement xe = (XmlElement)xn; 23 m_values[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中 24 } 25 26 try 27 { 28 //2015-06-29 错误是没有签名 29 if(m_values["return_code"] != "SUCCESS") 30 { 31 return m_values; 32 } 33 CheckSign();//验证签名,不通过会抛异常 34 } 35 catch(WxPayException ex) 36 { 37 throw new WxPayException(ex.Message); 38 } 39 40 return m_values; 41 }
根据VS代码提示 ,可能非有意的引用比较;左侧需要强制转换。
经调试监听,即使m_values["return_code"]返回值为SUCCESS,此处判断也是true。这样就绕过了CheckSign()验证签名的方法。
如果按照VS代码提示进行修改:
//2015-06-29 错误是没有签名 if(m_values["return_code"].ToString() != "SUCCESS") { return m_values; } CheckSign();//验证签名,不通过会抛异常
经调试,m_values["return_code"]返回值为SUCCESS,下一步走CheckSign()验证签名的方法,然后报“WxPayData字段数据类型错误!”
然后下载Java SDK进行代码对比,发现只要m_values["return_code"]返回值为SUCCESS,就要进行签名验证,Java代码如下
/** * 处理 HTTPS API返回数据,转换成Map对象。return_code为SUCCESS时,验证签名。 * @param xmlStr API返回的XML格式数据 * @return Map类型数据 * @throws Exception */ public Map<String, String> processResponseXml(String xmlStr) throws Exception { String RETURN_CODE = "return_code"; String return_code; Map<String, String> respData = WXPayUtil.xmlToMap(xmlStr); if (respData.containsKey(RETURN_CODE)) { return_code = respData.get(RETURN_CODE); } else { throw new Exception(String.format("No `return_code` in XML: %s", xmlStr)); } if (return_code.equals(WXPayConstants.FAIL)) { return respData; } else if (return_code.equals(WXPayConstants.SUCCESS)) { if (this.isResponseSignatureValid(respData)) { return respData; } else { throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr)); } } else { throw new Exception(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr)); } }
对于.NET SDK 中这个处理,不太明白。还请大神指点迷津!