WxPayApi.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. using System;
  2. using Utils;
  3. namespace WxPayAPI
  4. {
  5. public class WxPayApi
  6. {
  7. /**
  8. * 提交被扫支付API
  9. * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,
  10. * 由商户收银台或者商户后台调用该接口发起支付。
  11. * @param WxPayData inputObj 提交给被扫支付API的参数
  12. * @param int timeOut 超时时间
  13. * @throws WxPayException
  14. * @return 成功时返回调用结果,其他抛异常
  15. */
  16. public static WxPayData Micropay(WxPayData inputObj, int timeOut = 10)
  17. {
  18. string url = "https://api.mch.weixin.qq.com/pay/micropay";
  19. //检测必填参数
  20. if (!inputObj.IsSet("body"))
  21. {
  22. throw new WxPayException("提交被扫支付API接口中,缺少必填参数body!");
  23. }
  24. else if (!inputObj.IsSet("out_trade_no"))
  25. {
  26. throw new WxPayException("提交被扫支付API接口中,缺少必填参数out_trade_no!");
  27. }
  28. else if (!inputObj.IsSet("total_fee"))
  29. {
  30. throw new WxPayException("提交被扫支付API接口中,缺少必填参数total_fee!");
  31. }
  32. else if (!inputObj.IsSet("auth_code"))
  33. {
  34. throw new WxPayException("提交被扫支付API接口中,缺少必填参数auth_code!");
  35. }
  36. inputObj.SetValue("spbill_create_ip", WxPayConfig.IP);//终端ip
  37. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  38. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  39. inputObj.SetValue("nonce_str", Guid.NewGuid().ToString().Replace("-", ""));//随机字符串
  40. inputObj.SetValue("sign", inputObj.MakeSign());//签名
  41. string xml = inputObj.ToXml();
  42. var start = DateTime.Now;//请求开始时间
  43. NlogHelper.quartzLogger.Info("WxPayApi MicroPay request : " + xml);
  44. string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口以提交数据到API
  45. NlogHelper.quartzLogger.Debug("WxPayApi", "MicroPay response : " + response);
  46. var end = DateTime.Now;
  47. int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时
  48. //将xml格式的结果转换为对象以返回
  49. WxPayData result = new WxPayData();
  50. result.FromXml(response);
  51. ReportCostTime(url, timeCost, result);//测速上报
  52. return result;
  53. }
  54. /**
  55. *
  56. * 查询订单
  57. * @param WxPayData inputObj 提交给查询订单API的参数
  58. * @param int timeOut 超时时间
  59. * @throws WxPayException
  60. * @return 成功时返回订单查询结果,其他抛异常
  61. */
  62. public static WxPayData OrderQuery(WxPayData inputObj, int timeOut = 6)
  63. {
  64. string url = "https://api.mch.weixin.qq.com/pay/orderquery";
  65. //检测必填参数
  66. if (!inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id"))
  67. {
  68. throw new WxPayException("订单查询接口中,out_trade_no、transaction_id至少填一个!");
  69. }
  70. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  71. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  72. inputObj.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//随机字符串
  73. inputObj.SetValue("sign", inputObj.MakeSign());//签名
  74. string xml = inputObj.ToXml();
  75. var start = DateTime.Now;
  76. NlogHelper.quartzLogger.Debug($"【OrderQuery】 xml request:{xml}");
  77. string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口提交数据
  78. NlogHelper.quartzLogger.Debug($"【OrderQuery】 xml response:{response}" );
  79. var end = DateTime.Now;
  80. int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时
  81. //将xml格式的数据转化为对象以返回
  82. WxPayData result = new WxPayData();
  83. result.FromXml(response);
  84. ReportCostTime(url, timeCost, result);//测速上报
  85. return result;
  86. }
  87. /**
  88. *
  89. * 撤销订单API接口
  90. * @param WxPayData inputObj 提交给撤销订单API接口的参数,out_trade_no和transaction_id必填一个
  91. * @param int timeOut 接口超时时间
  92. * @throws WxPayException
  93. * @return 成功时返回API调用结果,其他抛异常
  94. */
  95. public static WxPayData Reverse(WxPayData inputObj, int timeOut = 6)
  96. {
  97. string url = "https://api.mch.weixin.qq.com/secapi/pay/reverse";
  98. //检测必填参数
  99. if (!inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id"))
  100. {
  101. throw new WxPayException("撤销订单API接口中,参数out_trade_no和transaction_id必须填写一个!");
  102. }
  103. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  104. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  105. inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
  106. inputObj.SetValue("transaction_id", "");//签名
  107. inputObj.SetValue("sign", inputObj.MakeSign());//签名
  108. string xml = inputObj.ToXml();
  109. var start = DateTime.Now;//请求开始时间
  110. NlogHelper.quartzLogger.Debug("WxPayApi", "Reverse request : " + xml);
  111. string response = HttpService.Post(xml, url, true, timeOut);
  112. NlogHelper.quartzLogger.Debug("WxPayApi", "Reverse response : " + response);
  113. var end = DateTime.Now;
  114. int timeCost = (int)((end - start).TotalMilliseconds);
  115. WxPayData result = new WxPayData();
  116. result.FromXml(response);
  117. ReportCostTime(url, timeCost, result);//测速上报
  118. return result;
  119. }
  120. /**
  121. *
  122. * 申请退款
  123. * @param WxPayData inputObj 提交给申请退款API的参数
  124. * @param int timeOut 超时时间
  125. * @throws WxPayException
  126. * @return 成功时返回接口调用结果,其他抛异常
  127. */
  128. public static WxPayData Refund(WxPayData inputObj, int timeOut = 6)
  129. {
  130. string url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
  131. //检测必填参数
  132. if (!inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id"))
  133. {
  134. throw new WxPayException("退款申请接口中,out_trade_no、transaction_id至少填一个!");
  135. }
  136. else if (!inputObj.IsSet("out_refund_no"))
  137. {
  138. throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!");
  139. }
  140. else if (!inputObj.IsSet("total_fee"))
  141. {
  142. throw new WxPayException("退款申请接口中,缺少必填参数total_fee!");
  143. }
  144. else if (!inputObj.IsSet("refund_fee"))
  145. {
  146. throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!");
  147. }
  148. else if (!inputObj.IsSet("op_user_id"))
  149. {
  150. throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!");
  151. }
  152. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  153. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  154. inputObj.SetValue("nonce_str", Guid.NewGuid().ToString().Replace("-", ""));//随机字符串
  155. inputObj.SetValue("sign", inputObj.MakeSign());//签名
  156. string xml = inputObj.ToXml();
  157. var start = DateTime.Now;
  158. NlogHelper.quartzLogger.Debug("WxPayApi", "Refund request : " + xml);
  159. string response = HttpService.Post(xml, url, true, timeOut);//调用HTTP通信接口提交数据到API
  160. NlogHelper.quartzLogger.Debug("WxPayApi", "Refund response : " + response);
  161. var end = DateTime.Now;
  162. int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时
  163. //将xml格式的结果转换为对象以返回
  164. WxPayData result = new WxPayData();
  165. result.FromXml(response);
  166. ReportCostTime(url, timeCost, result);//测速上报
  167. return result;
  168. }
  169. /**
  170. *
  171. * 查询退款
  172. * 提交退款申请后,通过该接口查询退款状态。退款有一定延时,
  173. * 用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。
  174. * out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个
  175. * @param WxPayData inputObj 提交给查询退款API的参数
  176. * @param int timeOut 接口超时时间
  177. * @throws WxPayException
  178. * @return 成功时返回,其他抛异常
  179. */
  180. public static WxPayData RefundQuery(WxPayData inputObj, int timeOut = 6)
  181. {
  182. string url = "https://api.mch.weixin.qq.com/pay/refundquery";
  183. //检测必填参数
  184. if (!inputObj.IsSet("out_refund_no") && !inputObj.IsSet("out_trade_no") &&
  185. !inputObj.IsSet("transaction_id") && !inputObj.IsSet("refund_id"))
  186. {
  187. throw new WxPayException("退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个!");
  188. }
  189. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  190. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  191. inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
  192. inputObj.SetValue("sign", inputObj.MakeSign());//签名
  193. string xml = inputObj.ToXml();
  194. var start = DateTime.Now;//请求开始时间
  195. NlogHelper.quartzLogger.Debug("WxPayApi", "RefundQuery request : " + xml);
  196. string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口以提交数据到API
  197. NlogHelper.quartzLogger.Debug("WxPayApi", "RefundQuery response : " + response);
  198. var end = DateTime.Now;
  199. int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时
  200. //将xml格式的结果转换为对象以返回
  201. WxPayData result = new WxPayData();
  202. result.FromXml(response);
  203. ReportCostTime(url, timeCost, result);//测速上报
  204. return result;
  205. }
  206. /**
  207. * 下载对账单
  208. * @param WxPayData inputObj 提交给下载对账单API的参数
  209. * @param int timeOut 接口超时时间
  210. * @throws WxPayException
  211. * @return 成功时返回,其他抛异常
  212. */
  213. public static WxPayData DownloadBill(WxPayData inputObj, int timeOut = 6)
  214. {
  215. string url = "https://api.mch.weixin.qq.com/pay/downloadbill";
  216. //检测必填参数
  217. if (!inputObj.IsSet("bill_date"))
  218. {
  219. throw new WxPayException("对账单接口中,缺少必填参数bill_date!");
  220. }
  221. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  222. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  223. inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
  224. inputObj.SetValue("sign", inputObj.MakeSign());//签名
  225. string xml = inputObj.ToXml();
  226. NlogHelper.quartzLogger.Debug("WxPayApi", "DownloadBill request : " + xml);
  227. string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口以提交数据到API
  228. NlogHelper.quartzLogger.Debug("WxPayApi", "DownloadBill result : " + response);
  229. WxPayData result = new WxPayData();
  230. //若接口调用失败会返回xml格式的结果
  231. if (response.Substring(0, 5) == "<xml>")
  232. {
  233. result.FromXml(response);
  234. }
  235. //接口调用成功则返回非xml格式的数据
  236. else
  237. result.SetValue("result", response);
  238. return result;
  239. }
  240. /**
  241. *
  242. * 转换短链接
  243. * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),
  244. * 减小二维码数据量,提升扫描速度和精确度。
  245. * @param WxPayData inputObj 提交给转换短连接API的参数
  246. * @param int timeOut 接口超时时间
  247. * @throws WxPayException
  248. * @return 成功时返回,其他抛异常
  249. */
  250. public static WxPayData ShortUrl(WxPayData inputObj, int timeOut = 6)
  251. {
  252. string url = "https://api.mch.weixin.qq.com/tools/shorturl";
  253. //检测必填参数
  254. if (!inputObj.IsSet("long_url"))
  255. {
  256. throw new WxPayException("需要转换的URL,签名用原串,传输需URL encode!");
  257. }
  258. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  259. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  260. inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
  261. inputObj.SetValue("sign", inputObj.MakeSign());//签名
  262. string xml = inputObj.ToXml();
  263. var start = DateTime.Now;//请求开始时间
  264. NlogHelper.quartzLogger.Debug("WxPayApi", "ShortUrl request : " + xml);
  265. string response = HttpService.Post(xml, url, false, timeOut);
  266. NlogHelper.quartzLogger.Debug("WxPayApi", "ShortUrl response : " + response);
  267. var end = DateTime.Now;
  268. int timeCost = (int)((end - start).TotalMilliseconds);
  269. WxPayData result = new WxPayData();
  270. result.FromXml(response);
  271. ReportCostTime(url, timeCost, result);//测速上报
  272. return result;
  273. }
  274. /**
  275. *
  276. * 统一下单
  277. * @param WxPaydata inputObj 提交给统一下单API的参数
  278. * @param int timeOut 超时时间
  279. * @throws WxPayException
  280. * @return 成功时返回,其他抛异常
  281. */
  282. public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 6)
  283. {
  284. string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  285. //检测必填参数
  286. if (!inputObj.IsSet("out_trade_no"))
  287. {
  288. throw new WxPayException("缺少统一支付接口必填参数out_trade_no!");
  289. }
  290. else if (!inputObj.IsSet("body"))
  291. {
  292. throw new WxPayException("缺少统一支付接口必填参数body!");
  293. }
  294. else if (!inputObj.IsSet("total_fee"))
  295. {
  296. throw new WxPayException("缺少统一支付接口必填参数total_fee!");
  297. }
  298. else if (!inputObj.IsSet("trade_type"))
  299. {
  300. throw new WxPayException("缺少统一支付接口必填参数trade_type!");
  301. }
  302. //关联参数
  303. if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))
  304. {
  305. throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
  306. }
  307. if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))
  308. {
  309. throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为NATIVE时,product_id为必填参数!");
  310. }
  311. //异步通知url未设置,则使用配置文件中的url
  312. //if (!inputObj.IsSet("notify_url"))
  313. //{
  314. // inputObj.SetValue("notify_url", WxPayConfig.NOTIFY_URL);//异步通知url
  315. //}
  316. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  317. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  318. inputObj.SetValue("spbill_create_ip", WxPayConfig.IP);//终端ip
  319. inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
  320. inputObj.SetValue("notify_url", WxPayConfig.NOTIFY_URL);
  321. //签名
  322. inputObj.SetValue("sign", inputObj.MakeSign());
  323. //Log.Info("sign:", inputObj.MakeSign());
  324. string xml = inputObj.ToXml();
  325. var start = DateTime.Now;
  326. NlogHelper.quartzLogger.Debug("WxPayApi", "UnfiedOrder request : " + xml);
  327. string response = HttpService.Post(xml, url, false, timeOut);
  328. NlogHelper.quartzLogger.Debug("WxPayApi", "UnfiedOrder response : " + response);
  329. var end = DateTime.Now;
  330. int timeCost = (int)((end - start).TotalMilliseconds);
  331. WxPayData result = new WxPayData();
  332. result.FromXml(response);
  333. ReportCostTime(url, timeCost, result);//测速上报
  334. return result;
  335. }
  336. /**
  337. *
  338. * 关闭订单
  339. * @param WxPayData inputObj 提交给关闭订单API的参数
  340. * @param int timeOut 接口超时时间
  341. * @throws WxPayException
  342. * @return 成功时返回,其他抛异常
  343. */
  344. public static WxPayData CloseOrder(WxPayData inputObj, int timeOut = 6)
  345. {
  346. string url = "https://api.mch.weixin.qq.com/pay/closeorder";
  347. //检测必填参数
  348. if (!inputObj.IsSet("out_trade_no"))
  349. {
  350. throw new WxPayException("关闭订单接口中,out_trade_no必填!");
  351. }
  352. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  353. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  354. inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
  355. inputObj.SetValue("sign", inputObj.MakeSign());//签名
  356. string xml = inputObj.ToXml();
  357. var start = DateTime.Now;//请求开始时间
  358. string response = HttpService.Post(xml, url, false, timeOut);
  359. var end = DateTime.Now;
  360. int timeCost = (int)((end - start).TotalMilliseconds);
  361. WxPayData result = new WxPayData();
  362. result.FromXml(response);
  363. ReportCostTime(url, timeCost, result);//测速上报
  364. return result;
  365. }
  366. /**
  367. *
  368. * 测速上报
  369. * @param string interface_url 接口URL
  370. * @param int timeCost 接口耗时
  371. * @param WxPayData inputObj参数数组
  372. */
  373. private static void ReportCostTime(string interface_url, int timeCost, WxPayData inputObj)
  374. {
  375. //如果不需要进行上报
  376. if (WxPayConfig.REPORT_LEVENL == 0)
  377. {
  378. return;
  379. }
  380. //如果仅失败上报
  381. if (WxPayConfig.REPORT_LEVENL == 1 && inputObj.IsSet("return_code") && inputObj.GetValue("return_code").ToString() == "SUCCESS" &&
  382. inputObj.IsSet("result_code") && inputObj.GetValue("result_code").ToString() == "SUCCESS")
  383. {
  384. return;
  385. }
  386. //上报逻辑
  387. WxPayData data = new WxPayData();
  388. data.SetValue("interface_url", interface_url);
  389. data.SetValue("execute_time_", timeCost);
  390. //返回状态码
  391. if (inputObj.IsSet("return_code"))
  392. {
  393. data.SetValue("return_code", inputObj.GetValue("return_code"));
  394. }
  395. //返回信息
  396. if (inputObj.IsSet("return_msg"))
  397. {
  398. data.SetValue("return_msg", inputObj.GetValue("return_msg"));
  399. }
  400. //业务结果
  401. if (inputObj.IsSet("result_code"))
  402. {
  403. data.SetValue("result_code", inputObj.GetValue("result_code"));
  404. }
  405. //错误代码
  406. if (inputObj.IsSet("err_code"))
  407. {
  408. data.SetValue("err_code", inputObj.GetValue("err_code"));
  409. }
  410. //错误代码描述
  411. if (inputObj.IsSet("err_code_des"))
  412. {
  413. data.SetValue("err_code_des", inputObj.GetValue("err_code_des"));
  414. }
  415. //商户订单号
  416. if (inputObj.IsSet("out_trade_no"))
  417. {
  418. data.SetValue("out_trade_no", inputObj.GetValue("out_trade_no"));
  419. }
  420. //设备号
  421. if (inputObj.IsSet("device_info"))
  422. {
  423. data.SetValue("device_info", inputObj.GetValue("device_info"));
  424. }
  425. try
  426. {
  427. Report(data);
  428. }
  429. catch (WxPayException ex)
  430. {
  431. //不做任何处理
  432. }
  433. }
  434. /**
  435. *
  436. * 测速上报接口实现
  437. * @param WxPayData inputObj 提交给测速上报接口的参数
  438. * @param int timeOut 测速上报接口超时时间
  439. * @throws WxPayException
  440. * @return 成功时返回测速上报接口返回的结果,其他抛异常
  441. */
  442. public static WxPayData Report(WxPayData inputObj, int timeOut = 1)
  443. {
  444. string url = "https://api.mch.weixin.qq.com/payitil/report";
  445. //检测必填参数
  446. if (!inputObj.IsSet("interface_url"))
  447. {
  448. throw new WxPayException("接口URL,缺少必填参数interface_url!");
  449. }
  450. if (!inputObj.IsSet("return_code"))
  451. {
  452. throw new WxPayException("返回状态码,缺少必填参数return_code!");
  453. }
  454. if (!inputObj.IsSet("result_code"))
  455. {
  456. throw new WxPayException("业务结果,缺少必填参数result_code!");
  457. }
  458. if (!inputObj.IsSet("user_ip"))
  459. {
  460. throw new WxPayException("访问接口IP,缺少必填参数user_ip!");
  461. }
  462. if (!inputObj.IsSet("execute_time_"))
  463. {
  464. throw new WxPayException("接口耗时,缺少必填参数execute_time_!");
  465. }
  466. inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  467. inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
  468. inputObj.SetValue("user_ip", WxPayConfig.IP);//终端ip
  469. inputObj.SetValue("time", DateTime.Now.ToString("yyyyMMddHHmmss"));//商户上报时间
  470. inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
  471. inputObj.SetValue("sign", inputObj.MakeSign());//签名
  472. string xml = inputObj.ToXml();
  473. NlogHelper.quartzLogger.Info("WxPayApi", "Report request : " + xml);
  474. string response = HttpService.Post(xml, url, false, timeOut);
  475. NlogHelper.quartzLogger.Info("WxPayApi", "Report response : " + response);
  476. WxPayData result = new WxPayData();
  477. result.FromXml(response);
  478. return result;
  479. }
  480. /**
  481. * 根据当前系统时间加随机序列来生成订单号
  482. * @return 订单号
  483. */
  484. public static string GenerateOutTradeNo()
  485. {
  486. var ran = new Random();
  487. return string.Format("{0}{1}{2}", WxPayConfig.MCHID, DateTime.Now.ToString("yyyyMMddHHmmss"), ran.Next(999));
  488. }
  489. /**
  490. * 生成时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数
  491. * @return 时间戳
  492. */
  493. public static string GenerateTimeStamp()
  494. {
  495. TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
  496. return Convert.ToInt64(ts.TotalSeconds).ToString();
  497. }
  498. /**
  499. * 生成随机串,随机串包含字母或数字
  500. * @return 随机串
  501. */
  502. public static string GenerateNonceStr()
  503. {
  504. return Guid.NewGuid().ToString().Replace("-", "");
  505. }
  506. }
  507. }