using Aop.Api.Util; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; namespace EMIS.Utility.OnlinePay.Alipay.Models { public class Notify { #region 字段 private string _partner = ""; //合作身份者ID private string _charset = ""; //编码格式 private string _sign_type = ""; //签名方式 private string _alipay_public_key = ""; //支付宝公钥文件地址 //支付宝消息验证地址 private string Https_veryfy_url = ""; #endregion /// <summary> /// 构造函数 /// 从配置文件中初始化变量 /// </summary> /// <param name="inputPara">通知返回参数数组</param> /// <param name="notify_id">通知验证ID</param> public Notify(string charset, string sign_type, string pid, string mapiUrl, string alipay_public_key) { //初始化基础配置信息 _charset = charset; _sign_type = sign_type; _partner = pid; Https_veryfy_url = mapiUrl + "?service=notify_verify&"; _alipay_public_key = alipay_public_key; } /// <summary> /// 验证消息是否是支付宝发出的合法消息 /// </summary> /// <param name="inputPara">通知返回参数数组</param> /// <param name="notify_id">通知验证ID</param> /// <param name="sign">支付宝生成的签名结果</param> /// <returns>验证结果</returns> public bool Verify(SortedDictionary<string, string> inputPara, string notify_id, string sign) { //获取返回时的签名验证结果 bool isSign = GetSignVeryfy(inputPara, sign); //获取是否是支付宝服务器发来的请求的验证结果 //string responseTxt = "true"; //当面付2.0的异步通 //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); //对于开放平台的异步通知,通过验签可以达到安全校验的目的 //isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关 if (isSign)//验证成功 { return true; } else//验证失败 { return false; } } /// <summary> /// 获取待签名字符串(调试用) /// </summary> /// <param name="inputPara">通知返回参数数组</param> /// <returns>待签名字符串</returns> private string GetPreSignStr(SortedDictionary<string, string> inputPara) { Dictionary<string, string> sPara = new Dictionary<string, string>(); //过滤空值、sign与sign_type参数 sPara = Core.FilterPara(inputPara); //获取待签名字符串 string preSignStr = Core.CreateLinkString(sPara); return preSignStr; } /// <summary> /// 获取返回时的签名验证结果 /// </summary> /// <param name="inputPara">通知返回参数数组</param> /// <param name="sign">对比的签名结果</param> /// <returns>签名验证结果</returns> private bool GetSignVeryfy(SortedDictionary<string, string> inputPara, string sign) { Dictionary<string, string> sPara = new Dictionary<string, string>(); //过滤空值、sign与sign_type参数 sPara = Core.FilterPara(inputPara); //获取待签名字符串 string preSignStr = Core.CreateLinkString(sPara); //获得签名验证结果 bool isSign = false; if (sign != null && sign != "") { switch (_sign_type) { case "RSA": isSign = AlipaySignature.RSACheckContent(preSignStr, sign, _alipay_public_key, _charset, _sign_type, false); break; case "RSA2": isSign = AlipaySignature.RSACheckContent(preSignStr, sign, _alipay_public_key, _charset, _sign_type, false); break; default: break; } } return isSign; } /// <summary> /// 获取是否是支付宝服务器发来的请求的验证结果 /// </summary> /// <param name="notify_id">通知验证ID</param> /// <returns>验证结果</returns> 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; } /// <summary> /// 获取远程服务器ATN结果 /// </summary> /// <param name="strUrl">指定URL路径地址</param> /// <param name="timeout">超时时间设置</param> /// <returns>服务器ATN结果</returns> 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; } } }