|
|
- using System.Web;
- using System.Text;
- using System.IO;
- using System.Net;
- using System;
- using System.Collections.Generic;
- using System.Xml;
-
- namespace Com.Alipay
- {
- /// <summary>
- /// 类名:Submit
- /// 功能:支付宝各接口请求提交类
- /// 详细:构造支付宝各接口表单HTML文本,获取远程HTTP数据
- /// 版本:3.3
- /// 修改日期:2011-07-05
- /// 说明:
- /// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
- /// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考
- /// </summary>
- public class Submit
- {
- #region 字段
- //支付宝网关地址(新)
- private static string GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
- //商户的私钥
- private static string _key = "";
- //编码格式
- private static string _input_charset = "";
- //签名方式
- private static string _sign_type = "";
- #endregion
-
- static Submit()
- {
- Basic.BLL.siteconfig bll = new Basic.BLL.siteconfig();
- Basic.Model.siteconfig model = bll.loadConfig(Basic.Tools.Utils.GetXmlMapPath(Basic.Keys.FILE_SITE_XML_CONFING));
- _key = model.Alipay_key;
- _input_charset = Config.Input_charset.Trim().ToLower();
- _sign_type = Config.Sign_type.Trim().ToUpper();
- }
-
- /// <summary>
- /// 生成请求时的签名
- /// </summary>
- /// <param name="sPara">请求给支付宝的参数数组</param>
- /// <returns>签名结果</returns>
- private static string BuildRequestMysign(Dictionary<string, string> sPara)
- {
- //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
- string prestr = Core.CreateLinkString(sPara);
-
- //把最终的字符串签名,获得签名结果
- string mysign = "";
- switch (_sign_type)
- {
- case "MD5":
- mysign = AlipayMD5.Sign(prestr, _key, _input_charset);
- break;
- default:
- mysign = "";
- break;
- }
-
- return mysign;
- }
-
- /// <summary>
- /// 生成要请求给支付宝的参数数组
- /// </summary>
- /// <param name="sParaTemp">请求前的参数数组</param>
- /// <returns>要请求的参数数组</returns>
- private static Dictionary<string, string> BuildRequestPara(SortedDictionary<string, string> sParaTemp)
- {
- //待签名请求参数数组
- Dictionary<string, string> sPara = new Dictionary<string, string>();
- //签名结果
- string mysign = "";
-
- //过滤签名参数数组
- sPara = Core.FilterPara(sParaTemp);
-
- //获得签名结果
- mysign = BuildRequestMysign(sPara);
-
- //签名结果与签名方式加入请求提交参数组中
- sPara.Add("sign", mysign);
- sPara.Add("sign_type", _sign_type);
-
- return sPara;
- }
-
- /// <summary>
- /// 生成要请求给支付宝的参数数组
- /// </summary>
- /// <param name="sParaTemp">请求前的参数数组</param>
- /// <param name="code">字符编码</param>
- /// <returns>要请求的参数数组字符串</returns>
- private static string BuildRequestParaToString(SortedDictionary<string, string> sParaTemp, Encoding code)
- {
- //待签名请求参数数组
- Dictionary<string, string> sPara = new Dictionary<string, string>();
- sPara = BuildRequestPara(sParaTemp);
-
- //把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对参数值做urlencode
- string strRequestData = Core.CreateLinkStringUrlencode(sPara, code);
-
- return strRequestData;
- }
-
- /// <summary>
- /// 建立请求,以表单HTML形式构造(默认)
- /// </summary>
- /// <param name="sParaTemp">请求参数数组</param>
- /// <param name="strMethod">提交方式。两个值可选:post、get</param>
- /// <param name="strButtonValue">确认按钮显示文字</param>
- /// <returns>提交表单HTML文本</returns>
- public static string BuildRequest(SortedDictionary<string, string> sParaTemp, string strMethod, string strButtonValue)
- {
- //待请求参数数组
- Dictionary<string, string> dicPara = new Dictionary<string, string>();
- dicPara = BuildRequestPara(sParaTemp);
-
- StringBuilder sbHtml = new StringBuilder();
-
- sbHtml.Append("<form id='alipaysubmit' name='alipaysubmit' action='" + GATEWAY_NEW + "_input_charset=" + _input_charset + "' method='" + strMethod.ToLower().Trim() + "'>");
-
- foreach (KeyValuePair<string, string> temp in dicPara)
- {
- sbHtml.Append("<input type='hidden' name='" + temp.Key + "' value='" + temp.Value + "'/>");
- }
-
- //submit按钮控件请不要含有name属性
- sbHtml.Append("<input type='submit' value='" + strButtonValue + "' style='display:none;'></form>");
-
- sbHtml.Append("<script>document.forms['alipaysubmit'].submit();</script>");
-
- return sbHtml.ToString();
- }
-
-
- /// <summary>
- /// 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果
- /// </summary>
- /// <param name="sParaTemp">请求参数数组</param>
- /// <returns>支付宝处理结果</returns>
- public static string BuildRequest(SortedDictionary<string, string> sParaTemp)
- {
- Encoding code = Encoding.GetEncoding(_input_charset);
-
- //待请求参数数组字符串
- string strRequestData = BuildRequestParaToString(sParaTemp,code);
-
- //把数组转换成流中所需字节数组类型
- byte[] bytesRequestData = code.GetBytes(strRequestData);
-
- //构造请求地址
- string strUrl = GATEWAY_NEW + "_input_charset=" + _input_charset;
-
- //请求远程HTTP
- string strResult = "";
- try
- {
- //设置HttpWebRequest基本信息
- HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl);
- myReq.Method = "post";
- myReq.ContentType = "application/x-www-form-urlencoded";
-
- //填充POST数据
- myReq.ContentLength = bytesRequestData.Length;
- Stream requestStream = myReq.GetRequestStream();
- requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
- requestStream.Close();
-
- //发送POST数据请求服务器
- HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
- Stream myStream = HttpWResp.GetResponseStream();
-
- //获取服务器返回信息
- StreamReader reader = new StreamReader(myStream, code);
- StringBuilder responseData = new StringBuilder();
- String line;
- while ((line = reader.ReadLine()) != null)
- {
- responseData.Append(line);
- }
-
- //释放
- myStream.Close();
-
- strResult = responseData.ToString();
- }
- catch (Exception exp)
- {
- strResult = "报错:"+exp.Message;
- }
-
- return strResult;
- }
-
- /// <summary>
- /// 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果,带文件上传功能
- /// </summary>
- /// <param name="sParaTemp">请求参数数组</param>
- /// <param name="strMethod">提交方式。两个值可选:post、get</param>
- /// <param name="fileName">文件绝对路径</param>
- /// <param name="data">文件数据</param>
- /// <param name="contentType">文件内容类型</param>
- /// <param name="lengthFile">文件长度</param>
- /// <returns>支付宝处理结果</returns>
- public static string BuildRequest(SortedDictionary<string, string> sParaTemp, string strMethod, string fileName, byte[] data, string contentType, int lengthFile)
- {
-
- //待请求参数数组
- Dictionary<string, string> dicPara = new Dictionary<string, string>();
- dicPara = BuildRequestPara(sParaTemp);
-
- //构造请求地址
- string strUrl = GATEWAY_NEW + "_input_charset=" + _input_charset;
-
- //设置HttpWebRequest基本信息
- HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(strUrl);
- //设置请求方式:get、post
- request.Method = strMethod;
- //设置boundaryValue
- string boundaryValue = DateTime.Now.Ticks.ToString("x");
- string boundary = "--" + boundaryValue;
- request.ContentType = "\r\nmultipart/form-data; boundary=" + boundaryValue;
- //设置KeepAlive
- request.KeepAlive = true;
- //设置请求数据,拼接成字符串
- StringBuilder sbHtml = new StringBuilder();
- foreach (KeyValuePair<string, string> key in dicPara)
- {
- sbHtml.Append(boundary + "\r\nContent-Disposition: form-data; name=\"" + key.Key + "\"\r\n\r\n" + key.Value + "\r\n");
- }
- sbHtml.Append(boundary + "\r\nContent-Disposition: form-data; name=\"withhold_file\"; filename=\"");
- sbHtml.Append(fileName);
- sbHtml.Append("\"\r\nContent-Type: " + contentType + "\r\n\r\n");
- string postHeader = sbHtml.ToString();
- //将请求数据字符串类型根据编码格式转换成字节流
- Encoding code = Encoding.GetEncoding(_input_charset);
- byte[] postHeaderBytes = code.GetBytes(postHeader);
- byte[] boundayBytes = Encoding.ASCII.GetBytes("\r\n" + boundary + "--\r\n");
- //设置长度
- long length = postHeaderBytes.Length + lengthFile + boundayBytes.Length;
- request.ContentLength = length;
-
- //请求远程HTTP
- Stream requestStream = request.GetRequestStream();
- Stream myStream;
- try
- {
- //发送数据请求服务器
- requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
- requestStream.Write(data, 0, lengthFile);
- requestStream.Write(boundayBytes, 0, boundayBytes.Length);
- HttpWebResponse HttpWResp = (HttpWebResponse)request.GetResponse();
- myStream = HttpWResp.GetResponseStream();
- }
- catch (WebException e)
- {
- return e.ToString();
- }
- finally
- {
- if (requestStream != null)
- {
- requestStream.Close();
- }
- }
-
- //读取支付宝返回处理结果
- StreamReader reader = new StreamReader(myStream, code);
- StringBuilder responseData = new StringBuilder();
-
- String line;
- while ((line = reader.ReadLine()) != null)
- {
- responseData.Append(line);
- }
- myStream.Close();
- return responseData.ToString();
- }
-
- /// <summary>
- /// 用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数
- /// 注意:远程解析XML出错,与IIS服务器配置有关
- /// </summary>
- /// <returns>时间戳字符串</returns>
- public static string Query_timestamp()
- {
-
- Basic.BLL.siteconfig bll = new Basic.BLL.siteconfig();
- Basic.Model.siteconfig model = bll.loadConfig(Basic.Tools.Utils.GetXmlMapPath(Basic.Keys.FILE_SITE_XML_CONFING));
-
- string url = GATEWAY_NEW + "service=query_timestamp&partner=" + model.Alipay_partner + "&_input_charset=" + Config.Input_charset;
- string encrypt_key = "";
-
- XmlTextReader Reader = new XmlTextReader(url);
- XmlDocument xmlDoc = new XmlDocument();
- xmlDoc.Load(Reader);
-
- encrypt_key = xmlDoc.SelectSingleNode("/alipay/response/timestamp/encrypt_key").InnerText;
-
- return encrypt_key;
- }
- }
- }
|