1 using System;
2 using System.Collections.Generic;
3 using System.Web;
4 using System.Net;
5 using System.IO;
6 using System.Text;
7 using System.Configuration;
8
9 namespace Components.Payment.WxPayAPI
10 {
11 public class WxPayApi
12 {
13 /**
14 *
15 * 查询订单
16 * @param WxPayData inputObj 提交给查询订单API的参数
17 * @param int timeOut 超时时间
18 * @throws WxPayException
19 * @return 成功时返回订单查询结果,其他抛异常
20 */
21 public static WxPayData OrderQuery(WxPayData inputObj,
int timeOut =
6)
22 {
23 string url =
"https://api.mch.weixin.qq.com/pay/orderquery";
24 //检测必填参数
25 if (!inputObj.IsSet(
"out_trade_no") && !inputObj.IsSet(
"transaction_id"))
26 {
27 throw new WxPayException(
"订单查询接口中,out_trade_no、transaction_id至少填一个!");
28 }
29
30 inputObj.SetValue(
"appid", WxPayConfig.APPID);
//公众账号ID
31 inputObj.SetValue(
"mch_id", WxPayConfig.MCHID);
//商户号
32 inputObj.SetValue(
"nonce_str", WxPayApi.GenerateNonceStr());
//随机字符串
33 inputObj.SetValue(
"sign", inputObj.MakeSign(WxPayConfig.KEY));
//签名
34
35 string xml =
inputObj.ToXml();
36
37 var start =
DateTime.Now;
38
39 string response = HttpService.Post(xml, url,
false, timeOut);
//调用HTTP通信接口提交数据
40
41 var end =
DateTime.Now;
42 int timeCost = (
int)((end - start).TotalMilliseconds);
//获得接口耗时
43
44 //将xml格式的数据转化为对象以返回
45 WxPayData result =
new WxPayData();
46 result.FromXml(response);
47
48 ReportCostTime(url, timeCost, result);
//测速上报
49
50 return result;
51 }
52
53
54 /**
55 *
56 * 撤销订单API接口
57 * @param WxPayData inputObj 提交给撤销订单API接口的参数,out_trade_no和transaction_id必填一个
58 * @param int timeOut 接口超时时间
59 * @throws WxPayException
60 * @return 成功时返回API调用结果,其他抛异常
61 */
62 public static WxPayData Reverse(WxPayData inputObj,
int timeOut =
6)
63 {
64 string url =
"https://api.mch.weixin.qq.com/secapi/pay/reverse";
65 //检测必填参数
66 if (!inputObj.IsSet(
"out_trade_no") && !inputObj.IsSet(
"transaction_id"))
67 {
68 throw new WxPayException(
"撤销订单API接口中,参数out_trade_no和transaction_id必须填写一个!");
69 }
70
71 inputObj.SetValue(
"appid", WxPayConfig.APPID);
//公众账号ID
72 inputObj.SetValue(
"mch_id", WxPayConfig.MCHID);
//商户号
73 inputObj.SetValue(
"nonce_str", GenerateNonceStr());
//随机字符串
74 inputObj.SetValue(
"sign", inputObj.MakeSign(WxPayConfig.KEY));
//签名
75 string xml =
inputObj.ToXml();
76
77 var start = DateTime.Now;
//请求开始时间
78
79
80 string response = HttpService.Post(xml, url,
true, timeOut);
81
82
83 var end =
DateTime.Now;
84 int timeCost = (
int)((end -
start).TotalMilliseconds);
85
86 WxPayData result =
new WxPayData();
87 result.FromXml(response);
88
89 ReportCostTime(url, timeCost, result);
//测速上报
90
91 return result;
92 }
93
94
95 /**
96 *
97 * 申请退款
98 * @param WxPayData inputObj 提交给申请退款API的参数
99 * @param int timeOut 超时时间
100 * @throws WxPayException
101 * @return 成功时返回接口调用结果,其他抛异常
102 */
103 public static WxPayData Refund(WxPayData inputObj,
int timeOut =
6)
104 {
105 string url =
"https://api.mch.weixin.qq.com/secapi/pay/refund";
106 //检测必填参数
107 if (!inputObj.IsSet(
"out_trade_no") && !inputObj.IsSet(
"transaction_id"))
108 {
109 throw new WxPayException(
"退款申请接口中,out_trade_no、transaction_id至少填一个!");
110 }
111 else if (!inputObj.IsSet(
"out_refund_no"))
112 {
113 throw new WxPayException(
"退款申请接口中,缺少必填参数out_refund_no!");
114 }
115 else if (!inputObj.IsSet(
"total_fee"))
116 {
117 throw new WxPayException(
"退款申请接口中,缺少必填参数total_fee!");
118 }
119 else if (!inputObj.IsSet(
"refund_fee"))
120 {
121 throw new WxPayException(
"退款申请接口中,缺少必填参数refund_fee!");
122 }
123 else if (!inputObj.IsSet(
"op_user_id"))
124 {
125 throw new WxPayException(
"退款申请接口中,缺少必填参数op_user_id!");
126 }
127
128 inputObj.SetValue(
"appid", WxPayConfig.APPID);
//公众账号ID
129 inputObj.SetValue(
"mch_id", WxPayConfig.MCHID);
//商户号
130 inputObj.SetValue(
"nonce_str", Guid.NewGuid().ToString().Replace(
"-",
""));
//随机字符串
131 inputObj.SetValue(
"sign", inputObj.MakeSign(WxPayConfig.KEY));
//签名
132
133 string xml =
inputObj.ToXml();
134 var start =
DateTime.Now;
135
136 string response = HttpService.Post(xml, url,
true, timeOut);
//调用HTTP通信接口提交数据到API
137
138 var end =
DateTime.Now;
139 int timeCost = (
int)((end - start).TotalMilliseconds);
//获得接口耗时
140
141 //将xml格式的结果转换为对象以返回
142 WxPayData result =
new WxPayData();
143 result.FromXml(response);
144
145 ReportCostTime(url, timeCost, result);
//测速上报
146
147 return result;
148 }
149
150
151 /**
152 *
153 * 查询退款
154 * 提交退款申请后,通过该接口查询退款状态。退款有一定延时,
155 * 用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。
156 * out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个
157 * @param WxPayData inputObj 提交给查询退款API的参数
158 * @param int timeOut 接口超时时间
159 * @throws WxPayException
160 * @return 成功时返回,其他抛异常
161 */
162 public static WxPayData RefundQuery(WxPayData inputObj,
int timeOut =
6)
163 {
164 string url =
"https://api.mch.weixin.qq.com/pay/refundquery";
165 //检测必填参数
166 if(!inputObj.IsSet(
"out_refund_no") && !inputObj.IsSet(
"out_trade_no") &&
167 !inputObj.IsSet(
"transaction_id") && !inputObj.IsSet(
"refund_id"))
168 {
169 throw new WxPayException(
"退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个!");
170 }
171
172 inputObj.SetValue(
"appid",WxPayConfig.APPID);
//公众账号ID
173 inputObj.SetValue(
"mch_id",WxPayConfig.MCHID);
//商户号
174 inputObj.SetValue(
"nonce_str",GenerateNonceStr());
//随机字符串
175 inputObj.SetValue(
"sign", inputObj.MakeSign(WxPayConfig.KEY));
//签名
176
177 string xml =
inputObj.ToXml();
178
179 var start = DateTime.Now;
//请求开始时间
180
181 string response = HttpService.Post(xml, url,
false, timeOut);
//调用HTTP通信接口以提交数据到API
182
183 var end =
DateTime.Now;
184 int timeCost = (
int)((end-start).TotalMilliseconds);
//获得接口耗时
185
186 //将xml格式的结果转换为对象以返回
187 WxPayData result =
new WxPayData();
188 result.FromXml(response);
189
190 ReportCostTime(url, timeCost, result);
//测速上报
191
192 return result;
193 }
194
195
196 /**
197 * 下载对账单
198 * @param WxPayData inputObj 提交给下载对账单API的参数
199 * @param int timeOut 接口超时时间
200 * @throws WxPayException
201 * @return 成功时返回,其他抛异常
202 */
203 public static WxPayData DownloadBill(WxPayData inputObj,
int timeOut =
6)
204 {
205 string url =
"https://api.mch.weixin.qq.com/pay/downloadbill";
206 //检测必填参数
207 if (!inputObj.IsSet(
"bill_date"))
208 {
209 throw new WxPayException(
"对账单接口中,缺少必填参数bill_date!");
210 }
211
212 inputObj.SetValue(
"appid", WxPayConfig.APPID);
//公众账号ID
213 inputObj.SetValue(
"mch_id", WxPayConfig.MCHID);
//商户号
214 inputObj.SetValue(
"nonce_str", GenerateNonceStr());
//随机字符串
215 inputObj.SetValue(
"sign", inputObj.MakeSign(WxPayConfig.KEY));
//签名
216
217 string xml =
inputObj.ToXml();
218
219 string response = HttpService.Post(xml, url,
false, timeOut);
//调用HTTP通信接口以提交数据到API
220
221 WxPayData result =
new WxPayData();
222 //若接口调用失败会返回xml格式的结果
223 if (response.Substring(
0,
5) ==
"<xml>")
224 {
225 result.FromXml(response);
226 }
227 //接口调用成功则返回非xml格式的数据
228 else
229 result.SetValue(
"result", response);
230
231 return result;
232 }
233
234
235 /**
236 *
237 * 转换短链接
238 * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),
239 * 减小二维码数据量,提升扫描速度和精确度。
240 * @param WxPayData inputObj 提交给转换短连接API的参数
241 * @param int timeOut 接口超时时间
242 * @throws WxPayException
243 * @return 成功时返回,其他抛异常
244 */
245 public static WxPayData ShortUrl(WxPayData inputObj,
int timeOut =
6)
246 {
247 string url =
"https://api.mch.weixin.qq.com/tools/shorturl";
248 //检测必填参数
249 if(!inputObj.IsSet(
"long_url"))
250 {
251 throw new WxPayException(
"需要转换的URL,签名用原串,传输需URL encode!");
252 }
253
254 inputObj.SetValue(
"appid",WxPayConfig.APPID);
//公众账号ID
255 inputObj.SetValue(
"mch_id",WxPayConfig.MCHID);
//商户号
256 inputObj.SetValue(
"nonce_str",GenerateNonceStr());
//随机字符串
257 inputObj.SetValue(
"sign", inputObj.MakeSign(WxPayConfig.KEY));
//签名
258 string xml =
inputObj.ToXml();
259
260 var start = DateTime.Now;
//请求开始时间
261
262 string response = HttpService.Post(xml, url,
false, timeOut);
263
264 var end =
DateTime.Now;
265 int timeCost = (
int)((end -
start).TotalMilliseconds);
266
267 WxPayData result =
new WxPayData();
268 result.FromXml(response);
269 ReportCostTime(url, timeCost, result);
//测速上报
270
271 return result;
272 }
273
274
275 /**
276 *
277 * 统一下单
278 * @param WxPaydata inputObj 提交给统一下单API的参数
279 * @param int timeOut 超时时间
280 * @throws WxPayException
281 * @return 成功时返回,其他抛异常
282 */
283 public static WxPayData UnifiedOrder(WxPayData inputObj,
string key,
int timeOut =
6)
284 {
285 string url =
"https://api.mch.weixin.qq.com/pay/unifiedorder";
286 //检测必填参数
287 if (!inputObj.IsSet(
"out_trade_no"))
288 {
289 throw new WxPayException(
"缺少统一支付接口必填参数out_trade_no!");
290 }
291 else if (!inputObj.IsSet(
"body"))
292 {
293 throw new WxPayException(
"缺少统一支付接口必填参数body!");
294 }
295 else if (!inputObj.IsSet(
"total_fee"))
296 {
297 throw new WxPayException(
"缺少统一支付接口必填参数total_fee!");
298 }
299 else if (!inputObj.IsSet(
"trade_type"))
300 {
301 throw new WxPayException(
"缺少统一支付接口必填参数trade_type!");
302 }
303
304 //关联参数
305 if (inputObj.GetValue(
"trade_type").ToString() ==
"JSAPI" && !inputObj.IsSet(
"openid"))
306 {
307 throw new WxPayException(
"统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
308 }
309 if (inputObj.GetValue(
"trade_type").ToString() ==
"NATIVE" && !inputObj.IsSet(
"product_id"))
310 {
311 throw new WxPayException(
"统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
312 }
313
314 ////异步通知url未设置,则使用配置文件中的url
315 //if (!inputObj.IsSet("notify_url"))
316 //{
317 // inputObj.SetValue("notify_url", ConfigurationManager.AppSettings["Domain"] + WxPayConfig.NOTIFY_URL);//异步通知url
318 //}
319
320 //inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
321 //inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
322 //inputObj.SetValue("spbill_create_ip", WxPayConfig.IP);//终端ip
323 inputObj.SetValue(
"nonce_str", GenerateNonceStr());
//随机字符串
324
325 //签名
326 inputObj.SetValue(
"sign", inputObj.MakeSign(key));
327 string xml =
inputObj.ToXml();
328
329 var start =
DateTime.Now;
330 //Functions.Write("当前请求的XML为:"+xml);
331 string response = HttpService.Post(xml, url,
false, timeOut);
332 Functions.Write(
"response:" +
response);
333 var end =
DateTime.Now;
334 int timeCost = (
int)((end -
start).TotalMilliseconds);
335
336 WxPayData result =
new WxPayData(key);
337 result.FromXml(response);
338
339 ReportCostTime(url, timeCost, result);
//测速上报
340
341 return result;
342 }
343
344 /**
345 *
346 * 统一下单
347 * @param WxPaydata inputObj 提交给统一下单API的参数
348 * @param int timeOut 超时时间
349 * @throws WxPayException
350 * @return 成功时返回,其他抛异常
351 */
352 public static SortedDictionary<
string,
object> UnifiedOrderStr(WxPayData 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 WxPayException(
"缺少统一支付接口必填参数out_trade_no!");
359 }
360 else if (!inputObj.IsSet(
"body"))
361 {
362 throw new WxPayException(
"缺少统一支付接口必填参数body!");
363 }
364 else if (!inputObj.IsSet(
"total_fee"))
365 {
366 throw new WxPayException(
"缺少统一支付接口必填参数total_fee!");
367 }
368 else if (!inputObj.IsSet(
"trade_type"))
369 {
370 throw new WxPayException(
"缺少统一支付接口必填参数trade_type!");
371 }
372
373 //关联参数
374 if (inputObj.GetValue(
"trade_type").ToString() ==
"JSAPI" && !inputObj.IsSet(
"openid"))
375 {
376 throw new WxPayException(
"统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
377 }
378 if (inputObj.GetValue(
"trade_type").ToString() ==
"NATIVE" && !inputObj.IsSet(
"product_id"))
379 {
380 throw new WxPayException(
"统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
381 }
382
383 //异步通知url未设置,则使用配置文件中的url
384 if (!inputObj.IsSet(
"notify_url"))
385 {
386 inputObj.SetValue(
"notify_url", WxPayConfig.NOTIFY_URL);
//异步通知url
387 }
388
389 //inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
390 //inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
391 //inputObj.SetValue("spbill_create_ip", WxPayConfig.IP);//终端ip
392 inputObj.SetValue(
"nonce_str", GenerateNonceStr());
//随机字符串
393
394 //签名
395 inputObj.SetValue(
"sign", inputObj.MakeSign(WxPayConfig.KEY));
396 string xml =
inputObj.ToXml();
397
398 var start =
DateTime.Now;
399 string response = HttpService.Post(xml, url,
false, timeOut);
400 Functions.Write(
"response:" +
response);
401 var end =
DateTime.Now;
402 int timeCost = (
int)((end -
start).TotalMilliseconds);
403
404 WxPayData result =
new WxPayData();
405 var reslutStr =
result.FromXml(response);
406 reslutStr.Add(
"paySign", inputObj.MakeSign(WxPayConfig.KEY));
407 ReportCostTime(url, timeCost, result);
//测速上报
408 return reslutStr;
409 }
410 /**
411 *
412 * 关闭订单
413 * @param WxPayData inputObj 提交给关闭订单API的参数
414 * @param int timeOut 接口超时时间
415 * @throws WxPayException
416 * @return 成功时返回,其他抛异常
417 */
418 public static WxPayData CloseOrder(WxPayData inputObj,
int timeOut =
6)
419 {
420 string url =
"https://api.mch.weixin.qq.com/pay/closeorder";
421 //检测必填参数
422 if(!inputObj.IsSet(
"out_trade_no"))
423 {
424 throw new WxPayException(
"关闭订单接口中,out_trade_no必填!");
425 }
426
427 inputObj.SetValue(
"appid",WxPayConfig.APPID);
//公众账号ID
428 inputObj.SetValue(
"mch_id",WxPayConfig.MCHID);
//商户号
429 inputObj.SetValue(
"nonce_str",GenerateNonceStr());
//随机字符串
430 inputObj.SetValue(
"sign", inputObj.MakeSign(WxPayConfig.KEY));
//签名
431 string xml =
inputObj.ToXml();
432
433 var start = DateTime.Now;
//请求开始时间
434
435 string response = HttpService.Post(xml, url,
false, timeOut);
436
437 var end =
DateTime.Now;
438 int timeCost = (
int)((end -
start).TotalMilliseconds);
439
440 WxPayData result =
new WxPayData();
441 result.FromXml(response);
442
443 ReportCostTime(url, timeCost, result);
//测速上报
444
445 return result;
446 }
447
448
449 /**
450 *
451 * 测速上报
452 * @param string interface_url 接口URL
453 * @param int timeCost 接口耗时
454 * @param WxPayData inputObj参数数组
455 */
456 private static void ReportCostTime(
string interface_url,
int timeCost, WxPayData inputObj)
457 {
458 //如果不需要进行上报
459 if(WxPayConfig.REPORT_LEVENL ==
0)
460 {
461 return;
462 }
463
464 //如果仅失败上报
465 if(WxPayConfig.REPORT_LEVENL ==
1 && inputObj.IsSet(
"return_code") && inputObj.GetValue(
"return_code").ToString() ==
"SUCCESS" &&
466 inputObj.IsSet(
"result_code") && inputObj.GetValue(
"result_code").ToString() ==
"SUCCESS")
467 {
468 return;
469 }
470
471 //上报逻辑
472 WxPayData data =
new WxPayData();
473 data.SetValue(
"interface_url",interface_url);
474 data.SetValue(
"execute_time_",timeCost);
475 //返回状态码
476 if(inputObj.IsSet(
"return_code"))
477 {
478 data.SetValue(
"return_code",inputObj.GetValue(
"return_code"));
479 }
480 //返回信息
481 if(inputObj.IsSet(
"return_msg"))
482 {
483 data.SetValue(
"return_msg",inputObj.GetValue(
"return_msg"));
484 }
485 //业务结果
486 if(inputObj.IsSet(
"result_code"))
487 {
488 data.SetValue(
"result_code",inputObj.GetValue(
"result_code"));
489 }
490 //错误代码
491 if(inputObj.IsSet(
"err_code"))
492 {
493 data.SetValue(
"err_code",inputObj.GetValue(
"err_code"));
494 }
495 //错误代码描述
496 if(inputObj.IsSet(
"err_code_des"))
497 {
498 data.SetValue(
"err_code_des",inputObj.GetValue(
"err_code_des"));
499 }
500 //商户订单号
501 if(inputObj.IsSet(
"out_trade_no"))
502 {
503 data.SetValue(
"out_trade_no",inputObj.GetValue(
"out_trade_no"));
504 }
505 //设备号
506 if(inputObj.IsSet(
"device_info"))
507 {
508 data.SetValue(
"device_info",inputObj.GetValue(
"device_info"));
509 }
510
511 try
512 {
513 Report(data);
514 }
515 catch (WxPayException ex)
516 {
517 //不做任何处理
518 }
519 }
520
521
522 /**
523 *
524 * 测速上报接口实现
525 * @param WxPayData inputObj 提交给测速上报接口的参数
526 * @param int timeOut 测速上报接口超时时间
527 * @throws WxPayException
528 * @return 成功时返回测速上报接口返回的结果,其他抛异常
529 */
530 public static WxPayData Report(WxPayData inputObj,
int timeOut =
1)
531 {
532 string url =
"https://api.mch.weixin.qq.com/payitil/report";
533 //检测必填参数
534 if(!inputObj.IsSet(
"interface_url"))
535 {
536 throw new WxPayException(
"接口URL,缺少必填参数interface_url!");
537 }
538 if(!inputObj.IsSet(
"return_code"))
539 {
540 throw new WxPayException(
"返回状态码,缺少必填参数return_code!");
541 }
542 if(!inputObj.IsSet(
"result_code"))
543 {
544 throw new WxPayException(
"业务结果,缺少必填参数result_code!");
545 }
546 if(!inputObj.IsSet(
"user_ip"))
547 {
548 throw new WxPayException(
"访问接口IP,缺少必填参数user_ip!");
549 }
550 if(!inputObj.IsSet(
"execute_time_"))
551 {
552 throw new WxPayException(
"接口耗时,缺少必填参数execute_time_!");
553 }
554
555 inputObj.SetValue(
"appid",WxPayConfig.APPID);
//公众账号ID
556 inputObj.SetValue(
"mch_id",WxPayConfig.MCHID);
//商户号
557 inputObj.SetValue(
"user_ip",WxPayConfig.IP);
//终端ip
558 inputObj.SetValue(
"time",DateTime.Now.ToString(
"yyyyMMddHHmmss"));
//商户上报时间
559 inputObj.SetValue(
"nonce_str",GenerateNonceStr());
//随机字符串
560 inputObj.SetValue(
"sign", inputObj.MakeSign(WxPayConfig.KEY));
//签名
561 string xml =
inputObj.ToXml();
562
563
564 string response = HttpService.Post(xml, url,
false, timeOut);
565
566
567 WxPayData result =
new WxPayData();
568 result.FromXml(response);
569 return result;
570 }
571
572 /**
573 * 根据当前系统时间加随机序列来生成订单号
574 * @return 订单号
575 */
576 public static string GenerateOutTradeNo()
577 {
578 var ran =
new Random();
579 return string.Format(
"{0}{1}{2}", WxPayConfig.MCHID, DateTime.Now.ToString(
"yyyyMMddHHmmss"), ran.Next(
999));
580 }
581
582 /**
583 * 生成时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数
584 * @return 时间戳
585 */
586 public static string GenerateTimeStamp()
587 {
588 TimeSpan ts = DateTime.UtcNow -
new DateTime(
1970,
1,
1,
0,
0,
0,
0);
589 return Convert.ToInt64(ts.TotalSeconds).ToString();
590 }
591
592 /**
593 * 生成随机串,随机串包含字母或数字
594 * @return 随机串
595 */
596 public static string GenerateNonceStr()
597 {
598 return Guid.NewGuid().ToString().Replace(
"-",
"");
599 }
600 }
601 }
微信支付类
1 using System;
2 using System.Collections.Generic;
3 using System.Web;
4 using System.Web.UI;
5 using System.Web.UI.WebControls;
6 using System.Runtime.Serialization;
7 using System.IO;
8 using System.Text;
9 using System.Net;
10 using System.Web.Security;
11 using LitJson;
12
13 namespace Components.Payment.WxPayAPI
14 {
15 public class JsApiPay
16 {
17 /// <summary>
18 /// 保存页面对象,因为要在类的方法中使用Page的Request对象
19 /// </summary>
20 //private Page page {get;set;}
21
22 /// <summary>
23 /// openid用于调用统一下单接口
24 /// </summary>
25 public string openid {
get;
set; }
26
27 /// <summary>
28 /// access_token用于获取收货地址js函数入口参数
29 /// </summary>
30 public string access_token {
get;
set; }
31
32 /// <summary>
33 /// 商品金额,用于统一下单
34 /// </summary>
35 public int total_fee {
get;
set; }
36
37 public string out_trade_no {
get;
set; }
38 public string body {
get;
set; }
39 public string notify_url {
get;
set; }
40 public string appid {
get;
set; }
41 public string mch_id {
get;
set; }
42 public string key {
get;
set; }
43 public string APPSECRET {
get;
set; }
44 /// <summary>
45 /// 统一下单接口返回结果
46 /// </summary>
47 public WxPayData unifiedOrderResult {
get;
set; }
48
49 public JsApiPay()
50 {
51
52 }
53
54 public JsApiPay(
string notify_url,
string appid,
string mch_id,
string key,
string APPSECRET)
55 {
56 this.notify_url =
notify_url;
57 this.appid =
appid;
58 this.mch_id =
mch_id;
59 this.key =
key;
60 this.APPSECRET =
APPSECRET;
61 }
62
63
64 /**
65 *
66 * 网页授权获取用户基本信息的全部过程
67 * 详情请参看网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
68 * 第一步:利用url跳转获取code
69 * 第二步:利用code去获取openid和access_token
70 *
71 */
72 public void GetOpenidAndAccessToken()
73 {
74 var page =
HttpContext.Current;
75 if (!
string.IsNullOrEmpty(page.Request.QueryString[
"code"]))
76 {
77 //获取code码,以获取openid和access_token
78 string code = page.Request.QueryString[
"code"];
79 GetOpenidAndAccessTokenFromCode(code);
80 Functions.Write(
"第二次执行");
81 }
82 else
83 {
84 //构造网页授权获取code的URL
85 string host =
page.Request.Url.Host;
86 string path =
page.Request.Path;
87 string redirect_uri = HttpUtility.UrlEncode(
"http://" + host +
path);
88 WxPayData data =
new WxPayData();
89 data.SetValue(
"appid", WxPayConfig.APPID);
90 data.SetValue(
"redirect_uri", redirect_uri);
91 data.SetValue(
"response_type",
"code");
92 data.SetValue(
"scope",
"snsapi_base");
93 data.SetValue(
"state",
"STATE" +
"#wechat_redirect");
94 string url =
"https://open.weixin.qq.com/connect/oauth2/authorize?" +
data.ToUrl();
95 try
96 {
97 //触发微信返回code码
98 page.Response.Redirect(url);
//Redirect函数会抛出ThreadAbortException异常,不用处理这个异常
99
100 }
101 catch(System.Threading.ThreadAbortException ex)
102 {
103 Functions.Write(
"GetOpenidAndAccessToken()方法异常" +
ex.Message);
104 }
105 }
106 }
107
108 /**
109 *
110 * 网页授权获取用户基本信息的全部过程
111 * 详情请参看网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
112 *
113 */
114 public JsonData GetUserInfoByOpenidAndAccessToken(
string token,
string openid)
115 {
116 WxPayData data =
new WxPayData();
117 data.SetValue(
"access_token", token);
118 data.SetValue(
"openid", openid);
119 data.SetValue(
"lang",
"zh_CN");
120 string url =
"https://api.weixin.qq.com/sns/userinfo?" +
data.ToUrl();
121 try
122 {
123 //请求url以获取数据
124 string result =
HttpService.Get(url);
125 JsonData jd =
JsonMapper.ToObject(result);
126 return jd;
127 }
128 catch (System.Threading.ThreadAbortException ex)
129 {
130 Functions.Write(
"GetUserInfoByOpenidAndAccessToken()方法异常" +
ex.Message);
131 return null;
132 }
133 }
134
135 /**
136 *
137 * 通过code换取网页授权access_token和openid的返回数据,正确时返回的JSON数据包如下:
138 * {
139 * "access_token":"ACCESS_TOKEN",
140 * "expires_in":7200,
141 * "refresh_token":"REFRESH_TOKEN",
142 * "openid":"OPENID",
143 * "scope":"SCOPE",
144 * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
145 * }
146 * 其中access_token可用于获取共享收货地址
147 * openid是微信支付jsapi支付接口统一下单时必须的参数
148 * 更详细的说明请参考网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
149 * @失败时抛异常WxPayException
150 */
151 public void GetOpenidAndAccessTokenFromCode(
string code)
152 {
153 try
154 {
155 //构造获取openid及access_token的url
156 WxPayData data =
new WxPayData();
157 data.SetValue(
"appid",
this.appid);
158 data.SetValue(
"secret",
this.APPSECRET);
159 data.SetValue(
"code", code);
160 data.SetValue(
"grant_type",
"authorization_code");
161 string url =
"https://api.weixin.qq.com/sns/oauth2/access_token?" +
data.ToUrl();
162
163 //请求url以获取数据
164 string result =
HttpService.Get(url);
165 //保存access_token,用于收货地址获取
166 JsonData jd =
JsonMapper.ToObject(result);
167 access_token = (
string)jd[
"access_token"];
168
169 //获取用户openid
170 openid = (
string)jd[
"openid"];
171 }
172 catch (Exception ex)
173 {
174 Functions.Write(
"GetOpenidAndAccessTokenFromCode()方法异常" +
ex.Message);
175 }
176 }
177
178 /**
179 * 调用统一下单,获得下单结果
180 * @return 统一下单结果
181 * @失败时抛异常WxPayException
182 */
183 public WxPayData GetUnifiedOrderResult()
184 {
185 //统一下单
186 WxPayData data =
new WxPayData();
187 data.SetValue(
"body", body);
188 //data.SetValue("attach", "test");
189 data.SetValue(
"out_trade_no", out_trade_no);
190 data.SetValue(
"total_fee", total_fee);
191 data.SetValue(
"time_start", DateTime.Now.ToString(
"yyyyMMddHHmmss"));
192 data.SetValue(
"time_expire", DateTime.Now.AddMinutes(
10).ToString(
"yyyyMMddHHmmss"));
193 data.SetValue(
"goods_tag",
"test");
194 data.SetValue(
"trade_type",
"JSAPI");
195 data.SetValue(
"openid", openid);
196 data.SetValue(
"appid", WxPayConfig.APPID);
//公众账号ID
197 data.SetValue(
"mch_id", WxPayConfig.MCHID);
//商户号
198 data.SetValue(
"spbill_create_ip",Functions.GetIP());
//终端ip
199 data.SetValue(
"notify_url", notify_url);
200 WxPayData result = WxPayApi.UnifiedOrder(data,
this.key);
201 if (!result.IsSet(
"appid") || !result.IsSet(
"prepay_id") || result.GetValue(
"prepay_id").ToString() ==
"")
202 {
203 throw new WxPayException(
"UnifiedOrder response error!");
204 }
205
206 unifiedOrderResult =
result;
207 return result;
208 }
209
210 /**
211 *
212 * 从统一下单成功返回的数据中获取微信浏览器调起jsapi支付所需的参数,
213 * 微信浏览器调起JSAPI时的输入参数格式如下:
214 * {
215 * "appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入
216 * "timeStamp":" 1395712654", //时间戳,自1970年以来的秒数
217 * "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串
218 * "package" : "prepay_id=u802345jgfjsdfgsdg888",
219 * "signType" : "MD5", //微信签名方式:
220 * "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名
221 * }
222 * @return string 微信浏览器调起JSAPI时的输入参数,json格式可以直接做参数用
223 * 更详细的说明请参考网页端调起支付API:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7
224 *
225 */
226 public string GetJsApiParameters()
227 {
228
229 WxPayData jsApiParam =
new WxPayData();
230 jsApiParam.SetValue(
"appId", unifiedOrderResult.GetValue(
"appid"));
231 jsApiParam.SetValue(
"timeStamp", WxPayApi.GenerateTimeStamp());
232 jsApiParam.SetValue(
"nonceStr", WxPayApi.GenerateNonceStr());
233 jsApiParam.SetValue(
"package",
"prepay_id=" + unifiedOrderResult.GetValue(
"prepay_id"));
234 jsApiParam.SetValue(
"signType",
"MD5");
235 jsApiParam.SetValue(
"paySign", jsApiParam.MakeSign(
this.key));
236 jsApiParam.SetValue(
"openid",
this.openid);
237 string parameters =
jsApiParam.ToJson();
238
239 return parameters;
240 }
241
242 public string GetJsApiParameters(
string openid)
243 {
244
245 WxPayData jsApiParam =
new WxPayData();
246 jsApiParam.SetValue(
"appId", unifiedOrderResult.GetValue(
"appid"));
247 jsApiParam.SetValue(
"timeStamp", WxPayApi.GenerateTimeStamp());
248 jsApiParam.SetValue(
"nonceStr", WxPayApi.GenerateNonceStr());
249 jsApiParam.SetValue(
"package",
"prepay_id=" + unifiedOrderResult.GetValue(
"prepay_id"));
250 jsApiParam.SetValue(
"signType",
"MD5");
251 jsApiParam.SetValue(
"paySign", jsApiParam.MakeSign(
this.key));
252 jsApiParam.SetValue(
"openid", openid);
253 string parameters =
jsApiParam.ToJson();
254
255 return parameters;
256 }
257 /**
258 *
259 * 获取收货地址js函数入口参数,详情请参考收货地址共享接口:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_9
260 * @return string 共享收货地址js函数需要的参数,json格式可以直接做参数使用
261 */
262 public string GetEditAddressParameters()
263 {
264 var page =
HttpContext.Current;
265 string parameter =
"";
266 try
267 {
268 string host =
page.Request.Url.Host;
269 string path =
page.Request.Path;
270 string queryString =
page.Request.Url.Query;
271 //这个地方要注意,参与签名的是网页授权获取用户信息时微信后台回传的完整url
272 string url =
"http://" + host + path +
queryString;
273
274 //构造需要用SHA1算法加密的数据
275 WxPayData signData =
new WxPayData();
276 signData.SetValue(
"appid", WxPayConfig.APPID);
277 signData.SetValue(
"url", url);
278 signData.SetValue(
"timestamp",WxPayApi.GenerateTimeStamp());
279 signData.SetValue(
"noncestr",WxPayApi.GenerateNonceStr());
280 signData.SetValue(
"accesstoken",access_token);
281 string param =
signData.ToUrl();
282
283 //SHA1加密
284 string addrSign = FormsAuthentication.HashPasswordForStoringInConfigFile(param,
"SHA1");
285
286 //获取收货地址js函数入口参数
287 WxPayData afterData =
new WxPayData();
288 afterData.SetValue(
"appId", WxPayConfig.APPID);
289 afterData.SetValue(
"scope",
"jsapi_address");
290 afterData.SetValue(
"signType",
"sha1");
291 afterData.SetValue(
"addrSign",addrSign);
292 afterData.SetValue(
"timeStamp",signData.GetValue(
"timestamp"));
293 afterData.SetValue(
"nonceStr",signData.GetValue(
"noncestr"));
294
295 //转为json格式
296 parameter =
afterData.IObjectToJSON();
297 }
298 catch (Exception ex)
299 {
300 //throw new WxPayException(ex.ToString());
301 }
302
303 return parameter;
304 }
305 }
306 }
jsApi
1 using System;
2 using System.Collections.Generic;
3 using System.Web;
4 using System.Net;
5 using System.IO;
6 using System.Text;
7 using System.Net.Security;
8 using System.Security.Authentication;
9 using System.Security.Cryptography.X509Certificates;
10
11 namespace Components.Payment.WxPayAPI
12 {
13 /// <summary>
14 /// http连接基础类,负责底层的http通信
15 /// </summary>
16 public class HttpService
17 {
18
19 public static bool CheckValidationResult(
object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
20 {
21 //直接确认,否则打不开
22 return true;
23 }
24
25 public static string Post(
string xml,
string url,
bool isUseCert,
int timeout)
26 {
27 System.GC.Collect();
//垃圾回收,回收没有正常关闭的http连接
28
29 string result =
"";
//返回结果
30
31 HttpWebRequest request =
null;
32 HttpWebResponse response =
null;
33 Stream reqStream =
null;
34
35 try
36 {
37 //设置最大连接数
38 ServicePointManager.DefaultConnectionLimit =
200;
39 //设置https验证方式
40 if (url.StartsWith(
"https", StringComparison.OrdinalIgnoreCase))
41 {
42 ServicePointManager.ServerCertificateValidationCallback =
43 new RemoteCertificateValidationCallback(CheckValidationResult);
44 }
45
46 /***************************************************************
47 * 下面设置HttpWebRequest的相关属性
48 * ************************************************************/
49 request =
(HttpWebRequest)WebRequest.Create(url);
50
51 request.Method =
"POST";
52 request.Timeout = timeout *
1000;
53
54 //设置代理服务器
55 //WebProxy proxy = new WebProxy(); //定义一个网关对象
56 //proxy.Address = new Uri(WxPayConfig.PROXY_URL); //网关服务器端口:端口
57 //request.Proxy = proxy;
58
59 //设置POST的数据类型和长度
60 request.ContentType =
"text/xml";
61 byte[] data =
System.Text.Encoding.UTF8.GetBytes(xml);
62 request.ContentLength =
data.Length;
63
64 //是否使用证书
65 if (isUseCert)
66 {
67 string path =
HttpContext.Current.Request.PhysicalApplicationPath;
68 X509Certificate2 cert =
new X509Certificate2(path +
WxPayConfig.SSLCERT_PATH, WxPayConfig.SSLCERT_PASSWORD);
69 request.ClientCertificates.Add(cert);
70 }
71
72 //往服务器写入数据
73 reqStream =
request.GetRequestStream();
74 reqStream.Write(data,
0, data.Length);
75 reqStream.Close();
76
77 //获取服务端返回
78 response =
(HttpWebResponse)request.GetResponse();
79
80 //获取服务端返回数据
81 StreamReader sr =
new StreamReader(response.GetResponseStream(), Encoding.UTF8);
82 result =
sr.ReadToEnd().Trim();
83 sr.Close();
84 }
85 catch (System.Threading.ThreadAbortException e)
86 {
87 System.Threading.Thread.ResetAbort();
88 }
89 catch (WebException e)
90 {
91 if (e.Status ==
WebExceptionStatus.ProtocolError)
92 {
93 }
94 throw new WxPayException(e.ToString());
95 }
96 catch (Exception e)
97 {
98 throw new WxPayException(e.ToString());
99 }
100 finally
101 {
102 //关闭连接和流
103 if (response !=
null)
104 {
105 response.Close();
106 }
107 if(request !=
null)
108 {
109 request.Abort();
110 }
111 }
112 return result;
113 }
114
115 /// <summary>
116 /// 处理http GET请求,返回数据
117 /// </summary>
118 /// <param name="url">请求的url地址</param>
119 /// <returns>http GET成功后返回的数据,失败抛WebException异常</returns>
120 public static string Get(
string url)
121 {
122 System.GC.Collect();
123 string result =
"";
124
125 HttpWebRequest request =
null;
126 HttpWebResponse response =
null;
127
128 //请求url以获取数据
129 try
130 {
131 //设置最大连接数
132 ServicePointManager.DefaultConnectionLimit =
200;
133 //设置https验证方式
134 if (url.StartsWith(
"https", StringComparison.OrdinalIgnoreCase))
135 {
136 ServicePointManager.ServerCertificateValidationCallback =
137 new RemoteCertificateValidationCallback(CheckValidationResult);
138 }
139
140 /***************************************************************
141 * 下面设置HttpWebRequest的相关属性
142 * ************************************************************/
143 request =
(HttpWebRequest)WebRequest.Create(url);
144
145 request.Method =
"GET";
146
147 //设置代理
148 //WebProxy proxy = new WebProxy();
149 //proxy.Address = new Uri(WxPayConfig.PROXY_URL);
150 //request.Proxy = proxy;
151
152 //获取服务器返回
153 response =
(HttpWebResponse)request.GetResponse();
154
155 //获取HTTP返回数据
156 StreamReader sr =
new StreamReader(response.GetResponseStream(), Encoding.UTF8);
157 result =
sr.ReadToEnd().Trim();
158 sr.Close();
159 }
160 catch (System.Threading.ThreadAbortException e)
161 {
162 System.Threading.Thread.ResetAbort();
163 }
164 catch (WebException e)
165 {
166 if (e.Status ==
WebExceptionStatus.ProtocolError)
167 {
168 }
169 throw new WxPayException(e.ToString());
170 }
171 catch (Exception e)
172 {
173 throw new WxPayException(e.ToString());
174 }
175 finally
176 {
177 //关闭连接和流
178 if (response !=
null)
179 {
180 response.Close();
181 }
182 if (request !=
null)
183 {
184 request.Abort();
185 }
186 }
187 return result;
188 }
189 }
190 }
httpService
1 using System;
2 using System.Collections.Generic;
3 using System.Web;
4 using System.Xml;
5 using System.Security.Cryptography;
6 using System.Text;
7 using LitJson;
8
9
10 namespace Components.Payment.WxPayAPI
11 {
12 /// <summary>
13 /// 微信支付协议接口数据类,所有的API接口通信都依赖这个数据结构,
14 /// 在调用接口之前先填充各个字段的值,然后进行接口通信,
15 /// 这样设计的好处是可扩展性强,用户可随意对协议进行更改而不用重新设计数据结构,
16 /// 还可以随意组合出不同的协议数据包,不用为每个协议设计一个数据包结构
17 /// </summary>
18 public class WxPayData
19 {
20 public WxPayData()
21 {
22
23 }
24 public string key {
get;
set; }
25 public WxPayData(
string key)
26 {
27 this.key =
key;
28 }
29 //采用排序的Dictionary的好处是方便对数据包进行签名,不用再签名之前再做一次排序
30 private SortedDictionary<
string,
object> m_values =
new SortedDictionary<
string,
object>
();
31
32 /**
33 * 设置某个字段的值
34 * @param key 字段名
35 * @param value 字段值
36 */
37 public void SetValue(
string key,
object value)
38 {
39 m_values[key] =
value;
40 }
41
42 /**
43 * 根据字段名获取某个字段的值
44 * @param key 字段名
45 * @return key对应的字段值
46 */
47 public object GetValue(
string key)
48 {
49 object o =
null;
50 m_values.TryGetValue(key,
out o);
51 return o;
52 }
53
54 /**
55 * 判断某个字段是否已设置
56 * @param key 字段名
57 * @return 若字段key已被设置,则返回true,否则返回false
58 */
59 public bool IsSet(
string key)
60 {
61 object o =
null;
62 m_values.TryGetValue(key,
out o);
63 if (
null !=
o)
64 return true;
65 else
66 return false;
67 }
68
69 /**
70 * @将Dictionary转成xml
71 * @return 经转换得到的xml串
72 * @throws WxPayException
73 **/
74 public string ToXml()
75 {
76 //数据为空时不能转化为xml格式
77 if (
0 ==
m_values.Count)
78 {
79 throw new WxPayException(
"WxPayData数据为空!");
80 }
81
82 string xml =
"<xml>";
83 foreach (KeyValuePair<
string,
object> pair
in m_values)
84 {
85 //字段值不能为null,会影响后续流程
86 if (pair.Value ==
null)
87 {
88 throw new WxPayException(
"WxPayData内部含有值为null的字段!");
89 }
90
91 if (pair.Value.GetType() ==
typeof(
int))
92 {
93 xml +=
"<" + pair.Key +
">" + pair.Value +
"</" + pair.Key +
">";
94 }
95 else if (pair.Value.GetType() ==
typeof(
string))
96 {
97 xml +=
"<" + pair.Key +
">" + pair.Value +
"</" + pair.Key +
">";
98 //xml += "<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">";
99 }
100 else//除了string和int类型不能含有其他数据类型
101 {
102 throw new WxPayException(
"WxPayData字段数据类型错误!");
103 }
104 }
105 xml +=
"</xml>";
106 return xml;
107 }
108
109 /**
110 * @将xml转为WxPayData对象并返回对象内部的数据
111 * @param string 待转换的xml串
112 * @return 经转换得到的Dictionary
113 * @throws WxPayException
114 */
115 public SortedDictionary<
string,
object> FromXml(
string xml)
116 {
117 if (
string.IsNullOrEmpty(xml))
118 {
119 throw new WxPayException(
"将空的xml串转换为WxPayData不合法!");
120 }
121
122 XmlDocument xmlDoc =
new XmlDocument();
123 xmlDoc.LoadXml(xml);
124 XmlNode xmlNode = xmlDoc.FirstChild;
//获取到根节点<xml>
125 XmlNodeList nodes =
xmlNode.ChildNodes;
126 foreach (XmlNode xn
in nodes)
127 {
128 XmlElement xe =
(XmlElement)xn;
129 m_values[xe.Name] = xe.InnerText;
//获取xml的键值对到WxPayData内部的数据中
130 }
131 try
132 {
133 CheckSign(
this.key);
//验证签名,不通过会抛异常
134 }
135 catch(WxPayException ex)
136 {
137 throw new WxPayException(ex.Message);
138 }
139
140 return m_values;
141 }
142
143 /**
144 * @Dictionary格式转化成url参数格式
145 * @ return url格式串, 该串不包含sign字段值
146 */
147 public string ToUrl()
148 {
149 string buff =
"";
150 foreach (KeyValuePair<
string,
object> pair
in m_values)
151 {
152 if (pair.Value ==
null)
153 {
154 throw new WxPayException(
"WxPayData内部含有值为null的字段!");
155 }
156
157 if (pair.Key !=
"sign" && pair.Value.ToString() !=
"")
158 {
159 buff += pair.Key +
"=" + pair.Value +
"&";
160 }
161 }
162 buff = buff.Trim(
'&');
163 return buff;
164 }
165
166
167 public string ToJson()
168 {
169 string jsonStr =
JsonMapper.ToJson(m_values);
170 return jsonStr;
171 }
172
173 /**
174 * @values格式化成能在Web页面上显示的结果(因为web页面上不能直接输出xml格式的字符串)
175 */
176 public string ToPrintStr()
177 {
178 string str =
"";
179 foreach (KeyValuePair<
string,
object> pair
in m_values)
180 {
181 if (pair.Value ==
null)
182 {
183 throw new WxPayException(
"WxPayData内部含有值为null的字段!");
184 }
185
186 str +=
string.Format(
"{0}={1}<br>", pair.Key, pair.Value.ToString());
187 }
188 return str;
189 }
190
191 /**
192 * @生成签名,详见签名生成算法
193 * @return 签名, sign字段不参加签名
194 */
195 public string MakeSign(
string key)
196 {
197 //转url格式
198 string str =
ToUrl();
199 //Functions.Write("转url格式str" + str);
200 //在string后加入API KEY
201 str +=
"&key=" +
key;
202 //MD5加密
203 var md5 =
MD5.Create();
204 var bs =
md5.ComputeHash(Encoding.UTF8.GetBytes(str));
205 var sb =
new StringBuilder();
206 foreach (
byte b
in bs)
207 {
208 sb.Append(b.ToString(
"x2"));
209 }
210 //所有字符转为大写
211 return sb.ToString().ToUpper();
212 }
213
214 /**
215 *
216 * 检测签名是否正确
217 * 正确返回true,错误抛异常
218 */
219 public bool CheckSign(
string key)
220 {
221 //如果没有设置签名,则跳过检测
222 if (!IsSet(
"sign"))
223 {
224 return true;
225 }
226 //如果设置了签名但是签名为空,则抛异常
227 else if(GetValue(
"sign") ==
null || GetValue(
"sign").ToString() ==
"")
228 {
229 throw new WxPayException(
"WxPayData签名存在但不合法!");
230 }
231
232 //获取接收到的签名
233 string return_sign = GetValue(
"sign").ToString();
234
235 //在本地计算新的签名
236 string cal_sign =
MakeSign(key);
237
238 if (cal_sign ==
return_sign)
239 {
240 return true;
241 }
242
243 throw new WxPayException(
"WxPayData签名验证错误!");
244 }
245
246 /**
247 * @获取Dictionary
248 */
249 public SortedDictionary<
string,
object>
GetValues()
250 {
251 return m_values;
252 }
253 }
254 }
Data
1 using System;
2 using System.Collections.Generic;
3 using System.Configuration;
4 using System.Web;
5
6 namespace Components.Payment.WxPayAPI
7 {
8 /**
9 * 配置账号信息
10 */
11 public class WxPayConfig
12 {
13
14 //=======【基本信息设置】=====================================
15 /* 微信公众号信息配置
16 * APPID:绑定支付的APPID(必须配置)
17 * MCHID:商户号(必须配置)
18 * KEY:商户支付密钥,参考开户邮件设置(必须配置)
19 * APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置)
20 */
21 public const string APPID =
"wx7db8888888888888";
22 public const string MCHID =
"1234567890";
23 public const string KEY =
"";
24 public const string APPSECRET =
"";
25
26 //=======【证书路径设置】=====================================
27 /* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要)
28 */
29 public const string SSLCERT_PATH =
"cert/apiclient_cert.p12";
30 public const string SSLCERT_PASSWORD =
"1234567890";
31
32
33
34 //=======【支付结果通知url】=====================================
35 /* 支付结果通知回调url,用于商户接收支付结果
36 */
37 public const string NOTIFY_URL =
"/Mobile/WXPay/WXPayNotify";
38
39 //=======【商户系统后台机器IP】=====================================
40 /* 此参数可手动配置也可在程序中自动获取
41 */
42 public const string IP =
"8.8.8.8";
43
44
45 //=======【代理服务器设置】===================================
46 /* 默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置)
47 */
48 public const string PROXY_URL =
"http://10.152.18.220:8080";
49
50 //=======【上报信息配置】===================================
51 /* 测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报
52 */
53 public const int REPORT_LEVENL =
1;
54
55 //=======【日志级别】===================================
56 /* 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息
57 */
58 public const int LOG_LEVENL =
0;
59 }
60 }
参数配置
根据以上的帮助类,可以在后台构造APP支付所需要的签名参数,或者生成公众号支付的参数,代码使用示例
1 /// <summary>
2 /// 支付宝App支付
3 /// </summary>
4 /// <param name="postData"></param>
5 /// <returns></returns>
6 public ApiResult AliServicePayMethodToApi(IDictionary<
string,
string>
postData)
7 {
8 var res =
new ApiResult();
9 // 从数据库取得部分参数
10 var m_info = GetAliAppPayParamsInfo(
true);
11 List<
string> ordreNoList =
new List<
string>
();
12 // 参数设置
13 string service =
"mobile.securitypay.pay";
14 string out_trade_no =
"";
15 string total_fee =
"";
16 // 判断是交易号还是订单号
17 if (postData.ContainsKey(
"out_trade_no"))
18 {
19 out_trade_no = postData[
"out_trade_no"];
20 string orderno =
string.Empty;
21 int order_type =
0;
22 if (out_trade_no.Contains(
'_'))
23 {
24 orderno = out_trade_no.Split(
'_')[
0].IString();
25 order_type = out_trade_no.Split(
'_')[
1].IInt();
26 }
27 if (order_type ==
EnumOrderTypeSuffix.交易订单.IInt())
28 {
29 OrderTradingModels tradingmodel = UContainer.GetInstanse<IOrderBaseData>
().GetOrderTradingInfo(orderno);
30 if (!
tradingmodel.IsEmpty())
31 {
32 total_fee =
tradingmodel.TotalAmount.IString();
33 }
34 }
35 else if (order_type ==
EnumOrderTypeSuffix.商品订单.IInt())
36 {
37 OrderInfoModels orderModel = UContainer.GetInstanse<IOrderBaseData>
().GetOrderInfoByOrderNo(orderno);
38 if (!
orderModel.IsEmpty())
39 {
40 total_fee =
orderModel.TotalAmount.IString();
41 }
42 }
43 else if (order_type ==
EnumOrderTypeSuffix.服务订单.IInt())
44 {
45 var serviceorderinfo = UContainer.GetInstanse<IServiceOrderBaseData>
().GetServiceOrderInfoByOrderNo(orderno);
46 if (!
serviceorderinfo.IsEmpty())
47 {
48 total_fee =
serviceorderinfo.TotalAmount.IString();
49 }
50 }
51 }
52
53 string notify_url = ConfigurationManager.AppSettings[
"Domain"] +
"/Mobile/Alipay/Notify_Url";
54 string return_url = ConfigurationManager.AppSettings[
"Domain"] +
"/Mobile/Alipay/PaySuccess";
55 string payment_type =
"1";
56
57 Config.Partner =
m_info.Partner;
58 Config.Seller_id =
m_info.SellerId;
59 Config.Private_key =
m_info.RsaPrivate;
60 Config.Public_key =
m_info.RsaPublic;
61
62 //参数签名
63 SortedDictionary<
string,
string> dicArrayPre =
new SortedDictionary<
string,
string>
();
64 dicArrayPre.Add(
"partner", Config.Partner);
65 dicArrayPre.Add(
"seller_id", Config.Seller_id);
66 dicArrayPre.Add(
"out_trade_no", out_trade_no);
67 dicArrayPre.Add(
"subject",
"uyacOrder");
68 dicArrayPre.Add(
"body",
"XXX交易订单");
69 dicArrayPre.Add(
"total_fee", total_fee);
70 dicArrayPre.Add(
"notify_url", notify_url);
71 dicArrayPre.Add(
"service", service);
72 dicArrayPre.Add(
"payment_type", payment_type);
73 dicArrayPre.Add(
"_input_charset", Config.Input_charset.ToLower());
74 dicArrayPre.Add(
"return_url", return_url);
75 dicArrayPre.Add(
"it_b_pay",
"30m");
76
77 string str =
Submit.BuildRequestParaToStringNoEncode(dicArrayPre);
78 if (!str.IsEmpty() && str.ToString() !=
"")
79 {
80 res.Result =
str;
81 res.Message =
"调用成功";
82 res.Code =
"000";
83 }
84 else
85 {
86 res.Message =
"支付参数有误,请联系商家";
87 }
88 return res;
89 }
APP支付实例
转载于:https://www.cnblogs.com/HuberyHu/p/5390141.html
相关资源:JAVA上百实例源码以及开源项目