WebAlipay.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Net;
  5. using System.Text;
  6. using System.Xml;
  7. using BizCom;
  8. namespace SiteCore.Alipay
  9. {
  10. public class WebAlipay
  11. {
  12. public const string partner = "2088501970190189";
  13. public const string seller_email = "fatyi0112@sina.com";
  14. public const string key = "nsnvu34u1glfnu3148e1hwx7ln2r2aym";
  15. public const string input_charset = "utf-8";
  16. public const string sign_type = "MD5";
  17. public const string transport = "http";
  18. /// <summary>
  19. /// 付完款后跳转的页面 要用 以http开头格式的完整路径,不允许加?id=123这类自定义参数
  20. /// </summary>
  21. public string return_url;
  22. /// <summary>
  23. /// 交易过程中服务器通知的页面 要用 以http开格式的完整路径,不允许加?id=123这类自定义参数
  24. /// </summary>
  25. public string notify_url;
  26. /// <summary>
  27. /// 网站商品的展示地址,不允许加?id=123这类自定义参数
  28. /// </summary>
  29. public string show_url;
  30. /// <summary>
  31. /// 请与贵网站订单系统中的唯一订单号匹配
  32. /// </summary>
  33. public string out_trade_no;
  34. /// <summary>
  35. /// 订单名称,显示在支付宝收银台里的“商品名称”里,显示在支付宝的交易管理的“商品名称”的列表里。
  36. /// </summary>
  37. public string subject;
  38. /// <summary>
  39. /// 订单描述、订单详细、订单备注,显示在支付宝收银台里的“商品描述”里
  40. /// </summary>
  41. public string body;
  42. #region 即时到账
  43. /// <summary>
  44. /// 订单总金额,显示在支付宝收银台里的“应付总额”里
  45. /// </summary>
  46. public string total_fee;
  47. /// <summary>
  48. /// 默认支付方式,四个值可选:bankPay(网银); cartoon(卡通); directPay(余额); CASH(网点支付)
  49. /// </summary>
  50. public string paymethod = "";
  51. /// <summary>
  52. /// 默认网银代号,代号列表见club.alipay.com/read.php?tid=8681379
  53. /// </summary>
  54. public string defaultbank = "";
  55. /// <summary>
  56. /// 防钓鱼时间戳
  57. /// </summary>
  58. public string anti_phishing_key = "";
  59. /// <summary>
  60. /// 买家本地电脑的IP地址
  61. /// </summary>
  62. public string exter_invoke_ip = "";
  63. /// <summary>
  64. /// 自定义参数,可存放任何内容(除等特殊字符外),不会显示在页面上
  65. /// </summary>
  66. public string extra_common_param = "";
  67. #endregion
  68. #region 担保交易
  69. //订单总金额,显示在支付宝收银台里的“商品单价”里
  70. public string price;
  71. /// <summary>
  72. /// //商品数量,建议默认为1,不改变值,把一次交易看成是一次下订单而非购买一件商品。
  73. /// </summary>
  74. public string quantity = "1";
  75. //买家收货信息(推荐作为必填)
  76. //该功能作用在于买家已经在商户网站的下单流程中填过一次收货信息,而不需要买家在支付宝的付款流程中再次填写收货信息。
  77. //若要使用该功能,请至少保证receive_name、receive_address有值
  78. //收货信息格式请严格按照姓名、地址、邮编、电话、手机的格式填写
  79. /// <summary>
  80. /// //收货人姓名,如:张三
  81. /// </summary>
  82. public string receive_name = "海博公司";
  83. /// <summary>
  84. /// //收货人地址,如:XX省XXX市XXX区XXX路XXX小区XXX栋XXX单元XXX号
  85. /// </summary>
  86. public string receive_address = "福建省福州市鼓楼区";
  87. /// <summary>
  88. /// //收货人邮编,如:123456
  89. /// </summary>
  90. public string receive_zip = "350001";
  91. /// <summary>
  92. /// //收货人电话号码,如:0571-81234567
  93. /// </summary>
  94. public string receive_phone = "4000-717-718";
  95. /// <summary>
  96. /// //收货人手机号码,如:13312341234
  97. /// </summary>
  98. public string receive_mobile = "4000-717-718";
  99. /// <summary>
  100. /// //物流费用,即运费。
  101. /// </summary>
  102. public string logistics_fee = "0.00";
  103. /// <summary>
  104. /// //物流类型,三个值可选:EXPRESS(快递)、POST(平邮)、EMS(EMS)
  105. /// </summary>
  106. public string logistics_type = "EXPRESS";
  107. /// <summary>
  108. /// //物流支付方式,两个值可选:SELLER_PAY(卖家承担运费)、BUYER_PAY(买家承担运费)
  109. /// </summary>
  110. public string logistics_payment = "SELLER_PAY";
  111. #endregion
  112. public static string gateway = "https://www.alipay.com/cooperate/gateway.do?";
  113. //支付宝网关地址(新)
  114. public static string GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
  115. public string GetAlipayUrl()
  116. {
  117. SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
  118. Dictionary<string, string> para = new Dictionary<string, string>();
  119. //构造签名参数数组
  120. sParaTemp.Add("service", "create_partner_trade_by_buyer");
  121. sParaTemp.Add("payment_type", "1");
  122. sParaTemp.Add("partner", partner);
  123. sParaTemp.Add("seller_email", seller_email);
  124. sParaTemp.Add("_input_charset", "utf-8");
  125. sParaTemp.Add("return_url", return_url);
  126. sParaTemp.Add("notify_url", notify_url);
  127. sParaTemp.Add("show_url", show_url);
  128. sParaTemp.Add("out_trade_no", out_trade_no);
  129. sParaTemp.Add("subject", subject);
  130. sParaTemp.Add("body", body);
  131. #region 担保交易
  132. sParaTemp.Add("price", total_fee);
  133. sParaTemp.Add("quantity", quantity);
  134. sParaTemp.Add("logistics_fee", logistics_fee);
  135. sParaTemp.Add("logistics_payment", logistics_payment);
  136. sParaTemp.Add("logistics_type", logistics_type);
  137. sParaTemp.Add("receive_address", receive_address);
  138. sParaTemp.Add("receive_mobile", receive_mobile);
  139. sParaTemp.Add("receive_name", receive_name);
  140. sParaTemp.Add("receive_phone", receive_phone);
  141. sParaTemp.Add("receive_zip", receive_zip);
  142. #endregion
  143. #region 即时到账
  144. //sParaTemp.Add("total_fee", total_fee);
  145. //sParaTemp.Add("paymethod", paymethod);
  146. //sParaTemp.Add("defaultbank", defaultbank);
  147. //sParaTemp.Add("anti_phishing_key", anti_phishing_key);
  148. //sParaTemp.Add("exter_invoke_ip", exter_invoke_ip);
  149. //sParaTemp.Add("extra_common_param", extra_common_param);
  150. #endregion
  151. para = AlipayFunction.Para_filter(sParaTemp);
  152. //获得签名结果
  153. string mysign = AlipayFunction.Build_mysign(para, key, "MD5", "utf-8");
  154. /*
  155. string urlPara=Create_linkstring(para);
  156. StringBuilder url=new StringBuilder();
  157. url.Append(gateway);
  158. url.Append(urlPara);
  159. url.AppendFormat("&sign=" + mysign);
  160. url.AppendFormat("&sign_type=MD5");
  161. return url.ToString();*/
  162. return AlipayHtml(para, mysign);
  163. }
  164. private string AlipayHtml(Dictionary<string, string> sPara, string mysign)
  165. {
  166. StringBuilder sbHtml = new StringBuilder();
  167. //GET方式传递
  168. sbHtml.Append("<form id=\"alipaysubmit\" name=\"alipaysubmit\" action=\"" + gateway + "_input_charset=utf-8\" method=\"get\">");
  169. foreach (KeyValuePair<string, string> temp in sPara)
  170. {
  171. sbHtml.Append("<input type=\"hidden\" name=\"" + temp.Key + "\" value=\"" + temp.Value + "\"/>");
  172. }
  173. sbHtml.Append("<input type=\"hidden\" name=\"sign\" value=\"" + mysign + "\"/>");
  174. sbHtml.Append("<input type=\"hidden\" name=\"sign_type\" value=\"MD5\"/>");
  175. sbHtml.Append("<input type=\"submit\" value=\"支付宝确认付款\" style='display:none;'>");
  176. sbHtml.Append("</form>");
  177. sbHtml.Append("<script>document.forms['alipaysubmit'].submit();</script>");
  178. return sbHtml.ToString();
  179. }
  180. /// <summary>
  181. /// 生成要请求给支付宝的参数数组
  182. /// </summary>
  183. /// <param name="sParaTemp">请求前的参数数组</param>
  184. /// <returns>要请求的参数数组</returns>
  185. private static Dictionary<string, string> BuildRequestPara(SortedDictionary<string, string> sParaTemp)
  186. {
  187. //待签名请求参数数组
  188. Dictionary<string, string> sPara = new Dictionary<string, string>();
  189. //签名结果
  190. string mysign = "";
  191. //过滤签名参数数组
  192. sPara = AlipayFunction.Para_filter(sParaTemp);
  193. //获得签名结果
  194. mysign = AlipayFunction.Build_mysign(sPara, key, sign_type, input_charset);
  195. //签名结果与签名方式加入请求提交参数组中
  196. sPara.Add("sign", mysign);
  197. sPara.Add("sign_type", sign_type);
  198. return sPara;
  199. }
  200. /// <summary>
  201. /// 生成要请求给支付宝的参数数组
  202. /// </summary>
  203. /// <param name="sParaTemp">请求前的参数数组</param>
  204. /// <param name="code">字符编码</param>
  205. /// <returns>要请求的参数数组字符串</returns>
  206. private static string BuildRequestParaToString(SortedDictionary<string, string> sParaTemp, Encoding code)
  207. {
  208. //待签名请求参数数组
  209. Dictionary<string, string> sPara = new Dictionary<string, string>();
  210. sPara = BuildRequestPara(sParaTemp);
  211. //把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对参数值做urlencode
  212. string strRequestData = AlipayFunction.CreateLinkStringUrlencode(sPara, code);
  213. return strRequestData;
  214. }
  215. /// <summary>
  216. /// 构造确认发货接口
  217. /// </summary>
  218. /// <param name="sParaTemp">请求参数集合</param>
  219. /// <returns>支付宝的返回XML处理结果</returns>
  220. public static XmlDocument Send_goods_confirm_by_platform(SortedDictionary<string, string> sParaTemp)
  221. {
  222. //增加基本配置
  223. sParaTemp.Add("service", "send_goods_confirm_by_platform");
  224. sParaTemp.Add("partner", partner);
  225. sParaTemp.Add("_input_charset", input_charset);
  226. //获取支付宝的返回XML处理结果
  227. XmlDocument strHtml = new XmlDocument();
  228. strHtml = SendPostInfo(sParaTemp, GATEWAY_NEW);
  229. return strHtml;
  230. }
  231. /// <summary>
  232. /// 构造模拟远程HTTP的POST请求,获取支付宝的返回XML处理结果
  233. /// </summary>
  234. /// <param name="sParaTemp">请求参数数组</param>
  235. /// <param name="gateway">网关地址</param>
  236. /// <returns>支付宝返回XML处理结果</returns>
  237. public static XmlDocument SendPostInfo(SortedDictionary<string, string> sParaTemp, string gateway)
  238. {
  239. //待请求参数数组字符串
  240. Encoding code = Encoding.GetEncoding(input_charset);
  241. string strRequestData = BuildRequestParaToString(sParaTemp, code);
  242. //把数组转换成流中所需字节数组类型
  243. byte[] bytesRequestData = code.GetBytes(strRequestData);
  244. //构造请求地址
  245. string strUrl = gateway + "_input_charset=" + input_charset;
  246. //请求远程HTTP
  247. XmlDocument xmlDoc = new XmlDocument();
  248. try
  249. {
  250. //设置HttpWebRequest基本信息
  251. HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(strUrl);
  252. myReq.Method = "post";
  253. myReq.ContentType = "application/x-www-form-urlencoded";
  254. //填充POST数据
  255. myReq.ContentLength = bytesRequestData.Length;
  256. Stream requestStream = myReq.GetRequestStream();
  257. requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
  258. requestStream.Close();
  259. //发送POST数据请求服务器
  260. HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
  261. Stream myStream = HttpWResp.GetResponseStream();
  262. //获取服务器返回信息
  263. XmlTextReader Reader = new XmlTextReader(myStream);
  264. xmlDoc.Load(Reader);
  265. }
  266. catch (Exception exp)
  267. {
  268. string strXmlError = "<error>" + exp.Message + "</error>";
  269. xmlDoc.LoadXml(strXmlError);
  270. }
  271. return xmlDoc;
  272. }
  273. /// <summary>
  274. /// 构造模拟远程HTTP的GET请求,获取支付宝的返回XML处理结果
  275. /// </summary>
  276. /// <param name="sParaTemp">请求参数数组</param>
  277. /// <param name="gateway">网关地址</param>
  278. /// <returns>支付宝返回XML处理结果</returns>
  279. public XmlDocument SendGetInfo(SortedDictionary<string, string> sParaTemp, string gateway)
  280. {
  281. //待请求参数数组字符串
  282. Encoding code = Encoding.GetEncoding(input_charset);
  283. string strRequestData = BuildRequestParaToString(sParaTemp, code);
  284. //构造请求地址
  285. string strUrl = gateway + strRequestData;
  286. //请求远程HTTP
  287. XmlDocument xmlDoc = new XmlDocument();
  288. try
  289. {
  290. //设置HttpWebRequest基本信息
  291. HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(strUrl);
  292. myReq.Method = "get";
  293. //发送POST数据请求服务器
  294. HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
  295. Stream myStream = HttpWResp.GetResponseStream();
  296. //获取服务器返回信息
  297. XmlTextReader Reader = new XmlTextReader(myStream);
  298. xmlDoc.Load(Reader);
  299. }
  300. catch (Exception exp)
  301. {
  302. string strXmlError = "<error>" + exp.Message + "</error>";
  303. xmlDoc.LoadXml(strXmlError);
  304. }
  305. return xmlDoc;
  306. }
  307. public static bool ConfirmSendGoods(string trade_no)
  308. {
  309. //物流公司名称,物流公司名称
  310. string logistics_name = "海博公司";
  311. //物流发货单号
  312. string invoice_no = "000000";
  313. //物流发货时的运输类型,三个值可选:POST(平邮)、EXPRESS(快递)、EMS(EMS)
  314. string transport_type = "EXPRESS";
  315. SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
  316. sParaTemp.Add("trade_no", trade_no);
  317. sParaTemp.Add("logistics_name", logistics_name);
  318. sParaTemp.Add("invoice_no", invoice_no);
  319. sParaTemp.Add("transport_type", transport_type);
  320. try
  321. {
  322. XmlDocument xmlDoc = Send_goods_confirm_by_platform(sParaTemp);
  323. if (xmlDoc == null)
  324. {
  325. SyLog.WriteLog("支付宝发生错误!交易号:" + trade_no + "错误内容:没有XmlDocument");
  326. return false;
  327. }
  328. StringBuilder sbxml = new StringBuilder();
  329. string nodeIs_success = xmlDoc.SelectSingleNode("/alipay/is_success").InnerText;
  330. if (nodeIs_success != "T")//请求不成功的错误信息
  331. {
  332. SyLog.WriteLog("支付宝发生错误!交易号:" + trade_no + "错误内容:" + xmlDoc.SelectSingleNode("/alipay/error").InnerText);
  333. }
  334. else//请求成功的支付返回宝处理结果信息
  335. {
  336. //xmlDoc.SelectSingleNode("/alipay/response").InnerText;
  337. return true;
  338. }
  339. }
  340. catch (Exception ex)
  341. {
  342. SyLog.WriteLog("支付宝发生错误!交易号:" + trade_no, ex);
  343. }
  344. return false;
  345. }
  346. }
  347. }