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