1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Xml;
6
7 namespace Common
8 {
9 public class TenpayUtil
10 {
11 ///
12 /// 统一支付接口
13 ///
14 const string UnifiedPayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
15
16 ///
17 /// 网页授权接口
18 ///
19 const string access_tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
20
21 ///
22 /// 微信订单查询接口
23 ///
24 const string OrderQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
25
26 ///
27 /// 随机串
28 ///
29 public static string getNoncestr()
30 {
31 Random random = new Random();
32 return MD5Util.GetMD5(random.Next(1000).ToString(), "GBK").ToLower().Replace("s", "S");
33 }
34
35 ///
36 /// 时间截,自1970年以来的秒数
37 ///
38 public static string getTimestamp()
39 {
40 TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
41 return Convert.ToInt64(ts.TotalSeconds).ToString();
42 }
43
44 ///
45 /// 网页授权接口
46 ///
47 public static string getAccess_tokenUrl()
48 {
49 return access_tokenUrl;
50 }
51
52 ///
53 /// 获取微信签名
54 ///
55 ///
56 ///
57 public string getsign(SortedDictionary sParams, string key)
58 {
59 int i = 0;
60 string sign = string.Empty;
61 StringBuilder sb = new StringBuilder();
62 foreach (KeyValuePair temp in sParams.Reverse().Reverse())
63 {
64 if (temp.Value == "" || temp.Value == null || temp.Key.ToLower() == "sign")
65 {
66 continue;
67 }
68 i++;
69 sb.Append(temp.Key.Trim() + "=" + temp.Value.Trim() + "&");
70 }
71 sb.Append("key=" + key.Trim() + "");
72 string signkey = sb.ToString();
73
74 Logger.WriteAppLog("signkey:" + signkey);
75 sign = MD5Util.GetMD5(signkey, "utf-8").ToUpper();
76
77
78 return sign;
79 }
80
81
82 ///
83 /// 获取微信签名
84 ///
85 ///
86 ///
87 public string getpaySign(SortedDictionary sParams, string key)
88 {
89 int i = 0;
90 string sign = string.Empty;
91 StringBuilder sb = new StringBuilder();
92 foreach (KeyValuePair temp in sParams.Reverse().Reverse())
93 {
94 if (temp.Value == "" || temp.Value == null || temp.Key.ToLower() == "paySign")
95 {
96 continue;
97 }
98 i++;
99 sb.Append(temp.Key.Trim() + "=" + temp.Value.Trim() + "&");
100 }
101 sb.Append("key=" + key.Trim() + "");
102 string signkey = sb.ToString();
103
104 Logger.WriteAppLog("paySign:" + signkey);
105 sign = MD5Util.GetMD5(signkey, "utf-8").ToUpper();
106
107
108 return sign;
109 }
110
111 ///
112 /// post数据到指定接口并返回数据
113 ///
114 public string PostXmlToUrl(string url, string postData)
115 {
116 string returnmsg = "";
117
118 Logger.WriteAppLog("postData:" + postData);
119 using (System.Net.WebClient wc = new System.Net.WebClient())
120 {
121 wc.Encoding = System.Text.Encoding.UTF8;//定义对象语言
122 returnmsg = wc.UploadString(url, "POST", postData);
123 }
124 return returnmsg;
125 }
126
127 ///
128 /// 获取prepay_id
129 ///
130 public string getPrepay_id(UnifiedOrder order, string key)
131 {
132 string prepay_id = "";
133 string post_data = getUnifiedOrderXml(order, key);
134 string request_data = PostXmlToUrl(UnifiedPayUrl, post_data);
135
136
137 Logger.WriteAppLog("getPrepay_id :" + request_data);
138 SortedDictionary requestXML = GetInfoFromXml(request_data);
139 foreach (KeyValuePair k in requestXML)
140 {
141 if (k.Key == "prepay_id")
142 {
143 prepay_id = k.Value;
144 break;
145 }
146 }
147 return prepay_id;
148 }
149
150 ///
151 /// 获取微信订单明细
152 ///
153 public OrderDetail getOrderDetail(QueryOrder queryorder, string key)
154 {
155 string post_data = getQueryOrderXml(queryorder, key);
156 string request_data = PostXmlToUrl(OrderQueryUrl, post_data);
157 OrderDetail orderdetail = new OrderDetail();
158 SortedDictionary requestXML = GetInfoFromXml(request_data);
159 foreach (KeyValuePair k in requestXML)
160 {
161 switch (k.Key)
162 {
163 case "retuen_code":
164 orderdetail.result_code = k.Value;
165 break;
166 case "return_msg":
167 orderdetail.return_msg = k.Value;
168 break;
169 case "appid":
170 orderdetail.appid = k.Value;
171 break;
172 case "mch_id":
173 orderdetail.mch_id = k.Value;
174 break;
175 case "nonce_str":
176 orderdetail.nonce_str = k.Value;
177 break;
178 case "sign":
179 orderdetail.sign = k.Value;
180 break;
181 case "result_code":
182 orderdetail.result_code = k.Value;
183 break;
184 case "err_code":
185 orderdetail.err_code = k.Value;
186 break;
187 case "err_code_des":
188 orderdetail.err_code_des = k.Value;
189 break;
190 case "trade_state":
191 orderdetail.trade_state = k.Value;
192 break;
193 case "device_info":
194 orderdetail.device_info = k.Value;
195 break;
196 case "openid":
197 orderdetail.openid = k.Value;
198 break;
199 case "is_subscribe":
200 orderdetail.is_subscribe = k.Value;
201 break;
202 case "trade_type":
203 orderdetail.trade_type = k.Value;
204 break;
205 case "bank_type":
206 orderdetail.bank_type = k.Value;
207 break;
208 case "total_fee":
209 orderdetail.total_fee = k.Value;
210 break;
211 case "coupon_fee":
212 orderdetail.coupon_fee = k.Value;
213 break;
214 case "fee_type":
215 orderdetail.fee_type = k.Value;
216 break;
217 case "transaction_id":
218 orderdetail.transaction_id = k.Value;
219 break;
220 case "out_trade_no":
221 orderdetail.out_trade_no = k.Value;
222 break;
223 case "attach":
224 orderdetail.attach = k.Value;
225 break;
226 case "time_end":
227 orderdetail.time_end = k.Value;
228 break;
229 default:
230 break;
231 }
232 }
233 return orderdetail;
234 }
235
236 ///
237 /// 把XML数据转换为SortedDictionary集合
238 ///
239 ///
240 ///
241 protected SortedDictionary GetInfoFromXml(string xmlstring)
242 {
243 SortedDictionary sParams = new SortedDictionary();
244 try
245 {
246 XmlDocument doc = new XmlDocument();
247 doc.LoadXml(xmlstring);
248 XmlElement root = doc.DocumentElement;
249 int len = root.ChildNodes.Count;
250 for (int i = 0; i < len; i++)
251 {
252 string name = root.ChildNodes[i].Name;
253 if (!sParams.ContainsKey(name))
254 {
255 sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
256 }
257 }
258 }
259 catch { }
260 return sParams;
261 }
262
263 ///
264 /// 微信统一下单接口xml参数整理
265 ///
266 ///微信支付参数实例
267 ///密钥
268 ///
269 protected string getUnifiedOrderXml(UnifiedOrder order, string key)
270 {
271 string return_string = string.Empty;
272 SortedDictionary sParams = new SortedDictionary();
273 sParams.Add("appid", order.appid);
274 sParams.Add("mch_id", order.mch_id);
275 sParams.Add("nonce_str", order.nonce_str);
276
277 //SortedDictionary singparams = new SortedDictionary();
278 //singparams.Add("appid", order.appid);
279 //singparams.Add("body", order.body);
280 //singparams.Add("device_info", order.device_info);
281 //singparams.Add("mch_id", order.mch_id);
282 //singparams.Add("nonce_str", order.nonce_str);
283
284
285
286
287
288 // sParams.Add("sign", order.sign);
289 sParams.Add("body", order.body);
290 sParams.Add("out_trade_no", order.out_trade_no);
291 sParams.Add("total_fee", order.total_fee.ToString());
292 sParams.Add("spbill_create_ip", order.spbill_create_ip);
293 sParams.Add("notify_url", order.notify_url);
294 sParams.Add("trade_type", order.trade_type);
295 sParams.Add("openid", order.openid);
296 sParams.Add("device_info", order.device_info);
297
298
299 // sParams.Add("attach", order.attach);
300
301 //sParams.Add("device_info", order.device_info);
302
303 //sParams.Add("nonce_str", order.nonce_str);
304
305
306
307 string sign = getsign(sParams, key);
308
309 Logger.WriteAppLog("签名:" + sign);
310
311 order.sign = sign;
312
313
314 sParams.Add("sign", order.sign);
315
316
317
318 //拼接成XML请求数据
319 StringBuilder sbPay = new StringBuilder();
320
321 foreach (KeyValuePair k in sParams.Reverse().Reverse())
322 {
323 //if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
324 //{
325 // sbPay.Append("<" + k.Key + ">");
326 //}
327 //else
328 //{
329 // sbPay.Append("<" + k.Key + ">" + k.Value + "");
330 // }
331
332
333 if (k.Key == "sign")
334 {
335 sbPay.Append("<" + k.Key + ">");
336 }
337 else
338 {
339 sbPay.Append("<" + k.Key + ">" + k.Value + "");
340 }
341 }
342 return_string = string.Format("{0}", sbPay.ToString());
343 byte[] byteArray = Encoding.UTF8.GetBytes(return_string);
344 return_string = Encoding.GetEncoding("UTF-8").GetString(byteArray);
345
346 Logger.WriteAppLog("拼接成XML请求数据:" + return_string);
347 return return_string;
348
349 }
350
351 ///
352 /// 微信订单查询接口XML参数整理
353 ///
354 ///微信订单查询参数实例
355 ///密钥
356 ///
357 protected string getQueryOrderXml(QueryOrder queryorder, string key)
358 {
359 string return_string = string.Empty;
360 SortedDictionary sParams = new SortedDictionary();
361 sParams.Add("appid", queryorder.appid);
362 sParams.Add("mch_id", queryorder.mch_id);
363 sParams.Add("transaction_id", queryorder.transaction_id);
364 sParams.Add("out_trade_no", queryorder.out_trade_no);
365 sParams.Add("nonce_str", queryorder.nonce_str);
366 queryorder.sign = getsign(sParams, key);
367 sParams.Add("sign", queryorder.sign);
368
369 //拼接成XML请求数据
370 StringBuilder sbPay = new StringBuilder();
371 foreach (KeyValuePair k in sParams)
372 {
373 if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
374 {
375 sbPay.Append("<" + k.Key + ">");
376 }
377 else
378 {
379 sbPay.Append("<" + k.Key + ">" + k.Value + "");
380 }
381 }
382 return_string = string.Format("{0}", sbPay.ToString().TrimEnd(','));
383 return return_string;
384 }
385 }
386 }