Notify.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. using Aop.Api.Util;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Text;
  8. using System.Web;
  9. namespace EMIS.Utility.OnlinePay.Alipay.Models
  10. {
  11. public class Notify
  12. {
  13. #region 字段
  14. private string _partner = ""; //合作身份者ID
  15. private string _charset = ""; //编码格式
  16. private string _sign_type = ""; //签名方式
  17. private string _alipay_public_key = ""; //支付宝公钥文件地址
  18. //支付宝消息验证地址
  19. private string Https_veryfy_url = "";
  20. #endregion
  21. /// <summary>
  22. /// 构造函数
  23. /// 从配置文件中初始化变量
  24. /// </summary>
  25. /// <param name="inputPara">通知返回参数数组</param>
  26. /// <param name="notify_id">通知验证ID</param>
  27. public Notify(string charset, string sign_type, string pid, string mapiUrl, string alipay_public_key)
  28. {
  29. //初始化基础配置信息
  30. _charset = charset;
  31. _sign_type = sign_type;
  32. _partner = pid;
  33. Https_veryfy_url = mapiUrl + "?service=notify_verify&";
  34. _alipay_public_key = alipay_public_key;
  35. }
  36. /// <summary>
  37. /// 验证消息是否是支付宝发出的合法消息
  38. /// </summary>
  39. /// <param name="inputPara">通知返回参数数组</param>
  40. /// <param name="notify_id">通知验证ID</param>
  41. /// <param name="sign">支付宝生成的签名结果</param>
  42. /// <returns>验证结果</returns>
  43. public bool Verify(SortedDictionary<string, string> inputPara, string notify_id, string sign)
  44. {
  45. //获取返回时的签名验证结果
  46. bool isSign = GetSignVeryfy(inputPara, sign);
  47. //获取是否是支付宝服务器发来的请求的验证结果
  48. //string responseTxt = "true";
  49. //当面付2.0的异步通
  50. //if (notify_id != null && notify_id != "") { responseTxt = GetResponseTxt(notify_id); }
  51. //写日志记录(若要调试,请取消下面两行注释)
  52. //string sWord = "responseTxt=" + responseTxt + "\n isSign=" + isSign.ToString() + "\n 返回回来的参数:" + GetPreSignStr(inputPara) + "\n ";
  53. //Core.LogResult(sWord);
  54. //对于开放平台的异步通知,通过验签可以达到安全校验的目的
  55. //isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
  56. if (isSign)//验证成功
  57. {
  58. return true;
  59. }
  60. else//验证失败
  61. {
  62. return false;
  63. }
  64. }
  65. /// <summary>
  66. /// 获取待签名字符串(调试用)
  67. /// </summary>
  68. /// <param name="inputPara">通知返回参数数组</param>
  69. /// <returns>待签名字符串</returns>
  70. private string GetPreSignStr(SortedDictionary<string, string> inputPara)
  71. {
  72. Dictionary<string, string> sPara = new Dictionary<string, string>();
  73. //过滤空值、sign与sign_type参数
  74. sPara = Core.FilterPara(inputPara);
  75. //获取待签名字符串
  76. string preSignStr = Core.CreateLinkString(sPara);
  77. return preSignStr;
  78. }
  79. /// <summary>
  80. /// 获取返回时的签名验证结果
  81. /// </summary>
  82. /// <param name="inputPara">通知返回参数数组</param>
  83. /// <param name="sign">对比的签名结果</param>
  84. /// <returns>签名验证结果</returns>
  85. private bool GetSignVeryfy(SortedDictionary<string, string> inputPara, string sign)
  86. {
  87. Dictionary<string, string> sPara = new Dictionary<string, string>();
  88. //过滤空值、sign与sign_type参数
  89. sPara = Core.FilterPara(inputPara);
  90. //获取待签名字符串
  91. string preSignStr = Core.CreateLinkString(sPara);
  92. //获得签名验证结果
  93. bool isSign = false;
  94. if (sign != null && sign != "")
  95. {
  96. switch (_sign_type)
  97. {
  98. case "RSA":
  99. isSign = AlipaySignature.RSACheckContent(preSignStr, sign, _alipay_public_key, _charset, _sign_type, false);
  100. break;
  101. case "RSA2":
  102. isSign = AlipaySignature.RSACheckContent(preSignStr, sign, _alipay_public_key, _charset, _sign_type, false);
  103. break;
  104. default:
  105. break;
  106. }
  107. }
  108. return isSign;
  109. }
  110. /// <summary>
  111. /// 获取是否是支付宝服务器发来的请求的验证结果
  112. /// </summary>
  113. /// <param name="notify_id">通知验证ID</param>
  114. /// <returns>验证结果</returns>
  115. private string GetResponseTxt(string notify_id)
  116. {
  117. string veryfy_url = Https_veryfy_url + "partner=" + _partner + "&notify_id=" + notify_id;
  118. //获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求
  119. string responseTxt = Get_Http(veryfy_url, 120000);
  120. return responseTxt;
  121. }
  122. /// <summary>
  123. /// 获取远程服务器ATN结果
  124. /// </summary>
  125. /// <param name="strUrl">指定URL路径地址</param>
  126. /// <param name="timeout">超时时间设置</param>
  127. /// <returns>服务器ATN结果</returns>
  128. private string Get_Http(string strUrl, int timeout)
  129. {
  130. string strResult;
  131. try
  132. {
  133. HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl);
  134. myReq.Timeout = timeout;
  135. HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
  136. Stream myStream = HttpWResp.GetResponseStream();
  137. StreamReader sr = new StreamReader(myStream, Encoding.Default);
  138. StringBuilder strBuilder = new StringBuilder();
  139. while (-1 != sr.Peek())
  140. {
  141. strBuilder.Append(sr.ReadLine());
  142. }
  143. strResult = strBuilder.ToString();
  144. }
  145. catch (Exception exp)
  146. {
  147. strResult = "错误:" + exp.Message;
  148. }
  149. return strResult;
  150. }
  151. }
  152. }