WxPayApi.cs 25 KB

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