25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

308 satır
13 KiB

  1. using System.Web;
  2. using System.Text;
  3. using System.IO;
  4. using System.Net;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Xml;
  8. namespace Com.Alipay
  9. {
  10. /// <summary>
  11. /// 类名:Submit
  12. /// 功能:支付宝各接口请求提交类
  13. /// 详细:构造支付宝各接口表单HTML文本,获取远程HTTP数据
  14. /// 版本:3.3
  15. /// 修改日期:2011-07-05
  16. /// 说明:
  17. /// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
  18. /// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考
  19. /// </summary>
  20. public class Submit
  21. {
  22. #region 字段
  23. //支付宝网关地址(新)
  24. private static string GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
  25. //商户的私钥
  26. private static string _key = "";
  27. //编码格式
  28. private static string _input_charset = "";
  29. //签名方式
  30. private static string _sign_type = "";
  31. #endregion
  32. static Submit()
  33. {
  34. Basic.BLL.siteconfig bll = new Basic.BLL.siteconfig();
  35. Basic.Model.siteconfig model = bll.loadConfig(Basic.Tools.Utils.GetXmlMapPath(Basic.Keys.FILE_SITE_XML_CONFING));
  36. _key = model.Alipay_key;
  37. _input_charset = Config.Input_charset.Trim().ToLower();
  38. _sign_type = Config.Sign_type.Trim().ToUpper();
  39. }
  40. /// <summary>
  41. /// 生成请求时的签名
  42. /// </summary>
  43. /// <param name="sPara">请求给支付宝的参数数组</param>
  44. /// <returns>签名结果</returns>
  45. private static string BuildRequestMysign(Dictionary<string, string> sPara)
  46. {
  47. //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
  48. string prestr = Core.CreateLinkString(sPara);
  49. //把最终的字符串签名,获得签名结果
  50. string mysign = "";
  51. switch (_sign_type)
  52. {
  53. case "MD5":
  54. mysign = AlipayMD5.Sign(prestr, _key, _input_charset);
  55. break;
  56. default:
  57. mysign = "";
  58. break;
  59. }
  60. return mysign;
  61. }
  62. /// <summary>
  63. /// 生成要请求给支付宝的参数数组
  64. /// </summary>
  65. /// <param name="sParaTemp">请求前的参数数组</param>
  66. /// <returns>要请求的参数数组</returns>
  67. private static Dictionary<string, string> BuildRequestPara(SortedDictionary<string, string> sParaTemp)
  68. {
  69. //待签名请求参数数组
  70. Dictionary<string, string> sPara = new Dictionary<string, string>();
  71. //签名结果
  72. string mysign = "";
  73. //过滤签名参数数组
  74. sPara = Core.FilterPara(sParaTemp);
  75. //获得签名结果
  76. mysign = BuildRequestMysign(sPara);
  77. //签名结果与签名方式加入请求提交参数组中
  78. sPara.Add("sign", mysign);
  79. sPara.Add("sign_type", _sign_type);
  80. return sPara;
  81. }
  82. /// <summary>
  83. /// 生成要请求给支付宝的参数数组
  84. /// </summary>
  85. /// <param name="sParaTemp">请求前的参数数组</param>
  86. /// <param name="code">字符编码</param>
  87. /// <returns>要请求的参数数组字符串</returns>
  88. private static string BuildRequestParaToString(SortedDictionary<string, string> sParaTemp, Encoding code)
  89. {
  90. //待签名请求参数数组
  91. Dictionary<string, string> sPara = new Dictionary<string, string>();
  92. sPara = BuildRequestPara(sParaTemp);
  93. //把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对参数值做urlencode
  94. string strRequestData = Core.CreateLinkStringUrlencode(sPara, code);
  95. return strRequestData;
  96. }
  97. /// <summary>
  98. /// 建立请求,以表单HTML形式构造(默认)
  99. /// </summary>
  100. /// <param name="sParaTemp">请求参数数组</param>
  101. /// <param name="strMethod">提交方式。两个值可选:post、get</param>
  102. /// <param name="strButtonValue">确认按钮显示文字</param>
  103. /// <returns>提交表单HTML文本</returns>
  104. public static string BuildRequest(SortedDictionary<string, string> sParaTemp, string strMethod, string strButtonValue)
  105. {
  106. //待请求参数数组
  107. Dictionary<string, string> dicPara = new Dictionary<string, string>();
  108. dicPara = BuildRequestPara(sParaTemp);
  109. StringBuilder sbHtml = new StringBuilder();
  110. sbHtml.Append("<form id='alipaysubmit' name='alipaysubmit' action='" + GATEWAY_NEW + "_input_charset=" + _input_charset + "' method='" + strMethod.ToLower().Trim() + "'>");
  111. foreach (KeyValuePair<string, string> temp in dicPara)
  112. {
  113. sbHtml.Append("<input type='hidden' name='" + temp.Key + "' value='" + temp.Value + "'/>");
  114. }
  115. //submit按钮控件请不要含有name属性
  116. sbHtml.Append("<input type='submit' value='" + strButtonValue + "' style='display:none;'></form>");
  117. sbHtml.Append("<script>document.forms['alipaysubmit'].submit();</script>");
  118. return sbHtml.ToString();
  119. }
  120. /// <summary>
  121. /// 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果
  122. /// </summary>
  123. /// <param name="sParaTemp">请求参数数组</param>
  124. /// <returns>支付宝处理结果</returns>
  125. public static string BuildRequest(SortedDictionary<string, string> sParaTemp)
  126. {
  127. Encoding code = Encoding.GetEncoding(_input_charset);
  128. //待请求参数数组字符串
  129. string strRequestData = BuildRequestParaToString(sParaTemp,code);
  130. //把数组转换成流中所需字节数组类型
  131. byte[] bytesRequestData = code.GetBytes(strRequestData);
  132. //构造请求地址
  133. string strUrl = GATEWAY_NEW + "_input_charset=" + _input_charset;
  134. //请求远程HTTP
  135. string strResult = "";
  136. try
  137. {
  138. //设置HttpWebRequest基本信息
  139. HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl);
  140. myReq.Method = "post";
  141. myReq.ContentType = "application/x-www-form-urlencoded";
  142. //填充POST数据
  143. myReq.ContentLength = bytesRequestData.Length;
  144. Stream requestStream = myReq.GetRequestStream();
  145. requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
  146. requestStream.Close();
  147. //发送POST数据请求服务器
  148. HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
  149. Stream myStream = HttpWResp.GetResponseStream();
  150. //获取服务器返回信息
  151. StreamReader reader = new StreamReader(myStream, code);
  152. StringBuilder responseData = new StringBuilder();
  153. String line;
  154. while ((line = reader.ReadLine()) != null)
  155. {
  156. responseData.Append(line);
  157. }
  158. //释放
  159. myStream.Close();
  160. strResult = responseData.ToString();
  161. }
  162. catch (Exception exp)
  163. {
  164. strResult = "报错:"+exp.Message;
  165. }
  166. return strResult;
  167. }
  168. /// <summary>
  169. /// 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果,带文件上传功能
  170. /// </summary>
  171. /// <param name="sParaTemp">请求参数数组</param>
  172. /// <param name="strMethod">提交方式。两个值可选:post、get</param>
  173. /// <param name="fileName">文件绝对路径</param>
  174. /// <param name="data">文件数据</param>
  175. /// <param name="contentType">文件内容类型</param>
  176. /// <param name="lengthFile">文件长度</param>
  177. /// <returns>支付宝处理结果</returns>
  178. public static string BuildRequest(SortedDictionary<string, string> sParaTemp, string strMethod, string fileName, byte[] data, string contentType, int lengthFile)
  179. {
  180. //待请求参数数组
  181. Dictionary<string, string> dicPara = new Dictionary<string, string>();
  182. dicPara = BuildRequestPara(sParaTemp);
  183. //构造请求地址
  184. string strUrl = GATEWAY_NEW + "_input_charset=" + _input_charset;
  185. //设置HttpWebRequest基本信息
  186. HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(strUrl);
  187. //设置请求方式:get、post
  188. request.Method = strMethod;
  189. //设置boundaryValue
  190. string boundaryValue = DateTime.Now.Ticks.ToString("x");
  191. string boundary = "--" + boundaryValue;
  192. request.ContentType = "\r\nmultipart/form-data; boundary=" + boundaryValue;
  193. //设置KeepAlive
  194. request.KeepAlive = true;
  195. //设置请求数据,拼接成字符串
  196. StringBuilder sbHtml = new StringBuilder();
  197. foreach (KeyValuePair<string, string> key in dicPara)
  198. {
  199. sbHtml.Append(boundary + "\r\nContent-Disposition: form-data; name=\"" + key.Key + "\"\r\n\r\n" + key.Value + "\r\n");
  200. }
  201. sbHtml.Append(boundary + "\r\nContent-Disposition: form-data; name=\"withhold_file\"; filename=\"");
  202. sbHtml.Append(fileName);
  203. sbHtml.Append("\"\r\nContent-Type: " + contentType + "\r\n\r\n");
  204. string postHeader = sbHtml.ToString();
  205. //将请求数据字符串类型根据编码格式转换成字节流
  206. Encoding code = Encoding.GetEncoding(_input_charset);
  207. byte[] postHeaderBytes = code.GetBytes(postHeader);
  208. byte[] boundayBytes = Encoding.ASCII.GetBytes("\r\n" + boundary + "--\r\n");
  209. //设置长度
  210. long length = postHeaderBytes.Length + lengthFile + boundayBytes.Length;
  211. request.ContentLength = length;
  212. //请求远程HTTP
  213. Stream requestStream = request.GetRequestStream();
  214. Stream myStream;
  215. try
  216. {
  217. //发送数据请求服务器
  218. requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
  219. requestStream.Write(data, 0, lengthFile);
  220. requestStream.Write(boundayBytes, 0, boundayBytes.Length);
  221. HttpWebResponse HttpWResp = (HttpWebResponse)request.GetResponse();
  222. myStream = HttpWResp.GetResponseStream();
  223. }
  224. catch (WebException e)
  225. {
  226. return e.ToString();
  227. }
  228. finally
  229. {
  230. if (requestStream != null)
  231. {
  232. requestStream.Close();
  233. }
  234. }
  235. //读取支付宝返回处理结果
  236. StreamReader reader = new StreamReader(myStream, code);
  237. StringBuilder responseData = new StringBuilder();
  238. String line;
  239. while ((line = reader.ReadLine()) != null)
  240. {
  241. responseData.Append(line);
  242. }
  243. myStream.Close();
  244. return responseData.ToString();
  245. }
  246. /// <summary>
  247. /// 用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数
  248. /// 注意:远程解析XML出错,与IIS服务器配置有关
  249. /// </summary>
  250. /// <returns>时间戳字符串</returns>
  251. public static string Query_timestamp()
  252. {
  253. Basic.BLL.siteconfig bll = new Basic.BLL.siteconfig();
  254. Basic.Model.siteconfig model = bll.loadConfig(Basic.Tools.Utils.GetXmlMapPath(Basic.Keys.FILE_SITE_XML_CONFING));
  255. string url = GATEWAY_NEW + "service=query_timestamp&partner=" + model.Alipay_partner + "&_input_charset=" + Config.Input_charset;
  256. string encrypt_key = "";
  257. XmlTextReader Reader = new XmlTextReader(url);
  258. XmlDocument xmlDoc = new XmlDocument();
  259. xmlDoc.Load(Reader);
  260. encrypt_key = xmlDoc.SelectSingleNode("/alipay/response/timestamp/encrypt_key").InnerText;
  261. return encrypt_key;
  262. }
  263. }
  264. }