using System.Web; using System.Text; using System.IO; using System.Net; using System; using System.Collections.Generic; namespace Com.Alipay { /// /// 类名:Notify /// 功能:支付宝通知处理类 /// 详细:处理支付宝各接口通知返回 /// 版本:3.3 /// 修改日期:2011-07-05 /// '说明: /// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 /// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 /// /// //////////////////////注意///////////////////////////// /// 调试通知返回时,可查看或改写log日志的写入TXT里的数据,来检查通知返回是否正常 /// public class Notify { #region 字段 private string _partner = ""; //合作身份者ID private string _key = ""; //商户的私钥 private string _input_charset = ""; //编码格式 private string _sign_type = ""; //签名方式 //支付宝消息验证地址 private string Https_veryfy_url = "https://mapi.alipay.com/gateway.do?service=notify_verify&"; #endregion /// /// 构造函数 /// 从配置文件中初始化变量 /// /// 通知返回参数数组 /// 通知验证ID public Notify() { Basic.BLL.siteconfig bll = new Basic.BLL.siteconfig(); Basic.Model.siteconfig model = bll.loadConfig(Basic.Tools.Utils.GetXmlMapPath(Basic.Keys.FILE_SITE_XML_CONFING)); //初始化基础配置信息 _partner = model.Alipay_partner; _key = model.Alipay_key; _input_charset = Config.Input_charset.Trim().ToLower(); _sign_type = Config.Sign_type.Trim().ToUpper(); } /// /// 验证消息是否是支付宝发出的合法消息 /// /// 通知返回参数数组 /// 通知验证ID /// 支付宝生成的签名结果 /// 验证结果 public bool Verify(SortedDictionary inputPara, string notify_id, string sign) { //获取返回时的签名验证结果 bool isSign = GetSignVeryfy(inputPara, sign); //获取是否是支付宝服务器发来的请求的验证结果 string responseTxt = "true"; if (notify_id != null && notify_id != "") { responseTxt = GetResponseTxt(notify_id); } //写日志记录(若要调试,请取消下面两行注释) //string sWord = "responseTxt=" + responseTxt + "\n isSign=" + isSign.ToString() + "\n 返回回来的参数:" + GetPreSignStr(inputPara) + "\n "; //Core.LogResult(sWord); //判断responsetTxt是否为true,isSign是否为true //responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关 //isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关 if (responseTxt == "true" && isSign)//验证成功 { return true; } else//验证失败 { return false; } } /// /// 获取待签名字符串(调试用) /// /// 通知返回参数数组 /// 待签名字符串 private string GetPreSignStr(SortedDictionary inputPara) { Dictionary sPara = new Dictionary(); //过滤空值、sign与sign_type参数 sPara = Core.FilterPara(inputPara); //获取待签名字符串 string preSignStr = Core.CreateLinkString(sPara); return preSignStr; } /// /// 获取返回时的签名验证结果 /// /// 通知返回参数数组 /// 对比的签名结果 /// 签名验证结果 private bool GetSignVeryfy(SortedDictionary inputPara, string sign) { Dictionary sPara = new Dictionary(); //过滤空值、sign与sign_type参数 sPara = Core.FilterPara(inputPara); //获取待签名字符串 string preSignStr = Core.CreateLinkString(sPara); //获得签名验证结果 bool isSgin = false; if (sign != null && sign != "") { switch (_sign_type) { case "MD5": isSgin = AlipayMD5.Verify(preSignStr, sign, _key, _input_charset); break; default: break; } } return isSgin; } /// /// 获取是否是支付宝服务器发来的请求的验证结果 /// /// 通知验证ID /// 验证结果 private string GetResponseTxt(string notify_id) { string veryfy_url = Https_veryfy_url + "partner=" + _partner + "¬ify_id=" + notify_id; //获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求 string responseTxt = Get_Http(veryfy_url, 120000); return responseTxt; } /// /// 获取远程服务器ATN结果 /// /// 指定URL路径地址 /// 超时时间设置 /// 服务器ATN结果 private string Get_Http(string strUrl, int timeout) { string strResult; try { HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl); myReq.Timeout = timeout; HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse(); Stream myStream = HttpWResp.GetResponseStream(); StreamReader sr = new StreamReader(myStream, Encoding.Default); StringBuilder strBuilder = new StringBuilder(); while (-1 != sr.Peek()) { strBuilder.Append(sr.ReadLine()); } strResult = strBuilder.ToString(); } catch (Exception exp) { strResult = "错误:" + exp.Message; } return strResult; } } }