一、前言
經過兩三天的琢磨總算完成了微信掃碼支付功能,不得不感嘆幾句:
微信提供的DEMO不錯,直接復制粘貼就可以跑起來了;
微信的配置平臺我真是服了。公眾平臺、商戶平臺、開放平臺,一個平臺一套賬戶密碼,大寫的惡心
DEMO地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1
.NET版DEMO中的Lib文件夾是關鍵,直接復制到自己的代碼里,或者打成dll隨個人意愿。
二、正文
Step1:肯定是產生商戶訂單號,然后傳給微信后臺,由微信去組成二維碼字符串,然后返給你,你再把字符串做成圖片;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/// <summary> /// 獲取二維碼 /// </summary> /// <param name="orderNumber"></param> /// <returns></returns> public string GetCodeUrl( string orderNumber) { var result = string .Empty; if (! string .IsNullOrEmpty(orderNumber)) { var matchedItem = db.OrderInfoForProducts.FirstOrDefault(x => x.OrderNumber == orderNumber); if (matchedItem != null && matchedItem.IsPaid == false ) { WxPayData data = new WxPayData(); data.SetValue( "body" , "productBody" ); //商品描述 data.SetValue( "attach" , "attach data" ); //附加數據 data.SetValue( "out_trade_no" , WxPayApi.GenerateOutTradeNo()); //隨機字符串 data.SetValue( "total_fee" , price); //總金額 data.SetValue( "time_start" , DateTime.Now.ToString( "yyyyMMddHHmmss" )); //交易起始時間 data.SetValue( "time_expire" , DateTime.Now.AddMinutes(10).ToString( "yyyyMMddHHmmss" )); //交易結束時間 data.SetValue( "goods_tag" , "tag" ); //商品標記 data.SetValue( "trade_type" , "NATIVE" ); //交易類型 data.SetValue( "product_id" , WxPayApi.GenerateOutTradeNo()); //商品ID result = WxPayApi.UnifiedOrder(data).GetValue( "code_url" ).ToString(); //調用統一下單接口 } } return result; } |
在這里,我是把公司的商戶訂單號放在了attach字段上,因為公司的商戶訂單號比較長,超過了32位。out_trade_no與product_id字段最多32位,請慎重!
微信中的價格不能帶小數,所以0.01元要寫成100。
Step2: 成功返回二維碼字符串之后就可以在生成圖片了,我這邊使用了ThoughtWorks.QRCode.dll來生成圖片:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
/// <summary> /// 根據字符串得到相應的二維碼 /// </summary> /// <param name="qrInfo"></param> /// <param name="productName"></param> /// <param name="version"></param> /// <returns></returns> public static Image CreateQRCodeImage( string qrInfo, string productName, string version) { try { if (! string .IsNullOrEmpty(qrInfo)) { QRCodeEncoder encoder = new QRCodeEncoder { QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE, QRCodeScale = 4, QRCodeVersion = 0, QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M }; //編碼方式(注意:BYTE能支持中文,ALPHA_NUMERIC掃描出來的都是數字) //大小(值越大生成的二維碼圖片像素越高) //版本(注意:設置為0主要是防止編碼的字符串太長時發生錯誤) //錯誤效驗、錯誤更正(有4個等級) Image image = encoder.Encode(qrInfo, Encoding.GetEncoding( "utf-8" )); string filename = $ "{productName}_{version}.png" ; var userLocalPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); var docPath = Path.Combine(userLocalPath, @"Your Product\QRCode" ); if (!Directory.Exists(docPath)) { Directory.CreateDirectory(docPath); } string filepath = Path.Combine(docPath, filename); using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write)) { image.Save(fs, System.Drawing.Imaging.ImageFormat.Png); fs.Close(); image.Dispose(); } return image; } } catch (Exception) { return null ; } return null ; } |
Step3: 當用戶掃完二維碼之后,微信會發起回調,這時候我們就可以處理自己的業務邏輯了。這里我的UpdatePayStatus返回的是一個空頁面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/// <summary> /// 回調函數 /// </summary> public ActionResult UpdatePayStatus() { //接收從微信后臺POST過來的數據 System.IO.Stream s = Request.InputStream; int count = 0; byte [] buffer = new byte [1024]; StringBuilder builder = new StringBuilder(); while ((count = s.Read(buffer, 0, 1024)) > 0) { builder.Append(Encoding.UTF8.GetString(buffer, 0, count)); } s.Flush(); s.Close(); s.Dispose(); //轉換數據格式并驗證簽名 WxPayData data = new WxPayData(); try { data.FromXml(builder.ToString()); } catch (WxPayException ex) { //若簽名錯誤,則立即返回結果給微信支付后臺 WxPayData res = new WxPayData(); res.SetValue( "return_code" , "FAIL" ); res.SetValue( "return_msg" , ex.Message); LogEntity signErrorLog = new LogEntity(); signErrorLog.errorMessage = ex.Message; LogHelper.WriteLog(signErrorLog, null ); Response.Write(res.ToXml()); Response.End(); } ProcessNotify(data); return View(); } /// <summary> /// 處理回調數據 /// </summary> /// <param name="data"></param> public void ProcessNotify(WxPayData data) { WxPayData notifyData = data; //檢查支付結果中transaction_id是否存在 if (!notifyData.IsSet( "transaction_id" )) { //若transaction_id不存在,則立即返回結果給微信支付后臺 WxPayData res = new WxPayData(); res.SetValue( "return_code" , "FAIL" ); res.SetValue( "return_msg" , "支付結果中微信訂單號不存在" ); LogEntity orderLog = new LogEntity(); orderLog.errorMessage = "支付結果中微信訂單號不存在" ; LogHelper.WriteLog(orderLog, null ); Response.Write(res.ToXml()); Response.End(); } string transaction_id = notifyData.GetValue( "transaction_id" ).ToString(); //查詢訂單,判斷訂單真實性 if (!QueryOrder(transaction_id)) { //若訂單查詢失敗,則立即返回結果給微信支付后臺 WxPayData res = new WxPayData(); res.SetValue( "return_code" , "FAIL" ); res.SetValue( "return_msg" , "訂單查詢失敗" ); LogEntity orderqueryLog = new LogEntity(); orderqueryLog.errorMessage = "訂單查詢失敗" ; LogHelper.WriteLog(orderqueryLog, null ); Response.Write(res.ToXml()); Response.End(); } //查詢訂單成功 else { WxPayData res = new WxPayData(); res.SetValue( "return_code" , "SUCCESS" ); res.SetValue( "return_msg" , "OK" ); SetPaymentResult(data); //這里的參數是 data !!! 不是 res !!! Response.Write(res.ToXml()); Response.End(); } } /// <summary> /// 商戶后臺更新 /// </summary> /// <param name="res"></param> private void SetPaymentResult(WxPayData res) { var isSucessFlagOne = res.GetValue( "return_code" ).ToString(); var isSuccessFlagTwo = res.GetValue( "result_code" ).ToString(); if (isSucessFlagOne == "SUCCESS" && isSuccessFlagTwo == "SUCCESS" ) { //自己的業務邏輯 !!!! } } //查詢訂單 private bool QueryOrder( string transaction_id) { WxPayData req = new WxPayData(); req.SetValue( "transaction_id" , transaction_id); WxPayData res = WxPayApi.OrderQuery(req); if (res.GetValue( "return_code" ).ToString() == "SUCCESS" && res.GetValue( "result_code" ).ToString() == "SUCCESS" ) { return true ; } else { return false ; } } |
三、結尾
做完支付寶與微信掃碼支付發現支付寶的接入要比微信方便很多,還有一個同步請求。而且吐槽個其它的,微信開放平臺的審批速度要比支付寶的審批慢很多。還有微信支付最后上線前不需要非得用沙箱測試,做完之后直接一分錢一分錢測試即可。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/lovecsharp094/archive/2017/10/12/7650112.html