等了好久,微信官方終于發布了.net的demo。
主要代碼:
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
|
/** * 生成直接支付url,支付url有效期為2小時,模式二 * @param productid 商品id * @return 模式二url */ public string getpayurl( string productid, string body, string attach, int total_fee, string goods_tag) { log.info( this .gettype().tostring(), "native pay mode 2 url is producing..." ); wxpaydata data = new wxpaydata(); data.setvalue( "body" , body); //商品描述 data.setvalue( "attach" , attach); //附加數據 data.setvalue( "out_trade_no" , productid); //隨機字符串 data.setvalue( "total_fee" , total_fee); //總金額 data.setvalue( "time_start" , datetime.now.tostring( "yyyymmddhhmmss" )); //交易起始時間 data.setvalue( "time_expire" , datetime.now.addminutes(10).tostring( "yyyymmddhhmmss" )); //交易結束時間 data.setvalue( "goods_tag" , goods_tag); //商品標記 data.setvalue( "trade_type" , "native" ); //交易類型 data.setvalue( "product_id" , productid); //商品id wxpaydata result = wxpayapi.unifiedorder(data); //調用統一下單接口 string url = result.getvalue( "code_url" ).tostring(); //獲得統一下單接口返回的二維碼鏈接 log.info( this .gettype().tostring(), "get native pay mode 2 url : " + url); return url; } |
配置信息:
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
|
public class config { //=======【基本信息設置】===================================== /* 微信公眾號信息配置 * appid:綁定支付的appid(必須配置) * mchid:商戶號(必須配置) * key:商戶支付密鑰,參考開戶郵件設置(必須配置) * appsecret:公眾帳號secert(僅jsapi支付的時候需要配置) */ public const string appid = "你的微信公眾號appid" ; public const string mchid = "你的微信公眾號的商戶號" ; public const string key = "你的微信公眾號的商戶支付密鑰" ; public const string appsecret = "你的微信公眾號的appsecret" ; //=======【證書路徑設置】===================================== /* 證書路徑,注意應該填寫絕對路徑(僅退款、撤銷訂單時需要) */ public const string sslcert_path = "cert/apiclient_cert.p12" ; public const string sslcert_password = "1233410002" ; //=======【支付結果通知url】===================================== /* 支付結果通知回調url,用于商戶接收支付結果 */ public const string notify_url = "http://你的網站/pay/resultnotifypage.aspx" ; //=======【商戶系統后臺機器ip】===================================== /* 此參數可手動配置也可在程序中自動獲取 */ public const string ip = "你的服務器ip" ; //=======【代理服務器設置】=================================== /* 默認ip和端口號分別為0.0.0.0和0,此時不開啟代理(如有需要才設置) */ public const string proxy_url = "" ; //=======【上報信息配置】=================================== /* 測速上報等級,0.關閉上報; 1.僅錯誤時上報; 2.全量上報 */ public const int report_levenl = 1; //=======【日志級別】=================================== /* 日志等級,0.不輸出日志;1.只輸出錯誤信息; 2.輸出錯誤和正常信息; 3.輸出錯誤信息、正常信息和調試信息 */ public const int log_levenl = 0; } |
不使用代理要注釋httpservice.cs里面post和get方法的下面代碼:
1
2
3
4
|
//設置代理服務器 //webproxy proxy = new webproxy(); //定義一個網關對象 //proxy.address = new uri(config.proxy_url); //網關服務器端口:端口 //request.proxy = proxy; |
統一下單:
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
|
/** * * 統一下單 * @param wxpaydata inputobj 提交給統一下單api的參數 * @param int timeout 超時時間 * @throws wxpayexception * @return 成功時返回,其他拋異常 */ public static wxpaydata unifiedorder(wxpaydata inputobj, int timeout = 6) { string url = "https://api.mch.weixin.qq.com/pay/unifiedorder" ; //檢測必填參數 if (!inputobj.isset( "out_trade_no" )) { throw new wxpayexception( "缺少統一支付接口必填參數out_trade_no!" ); } else if (!inputobj.isset( "body" )) { throw new wxpayexception( "缺少統一支付接口必填參數body!" ); } else if (!inputobj.isset( "total_fee" )) { throw new wxpayexception( "缺少統一支付接口必填參數total_fee!" ); } else if (!inputobj.isset( "trade_type" )) { throw new wxpayexception( "缺少統一支付接口必填參數trade_type!" ); } //關聯參數 if (inputobj.getvalue( "trade_type" ).tostring() == "jsapi" && !inputobj.isset( "openid" )) { throw new wxpayexception( "統一支付接口中,缺少必填參數openid!trade_type為jsapi時,openid為必填參數!" ); } if (inputobj.getvalue( "trade_type" ).tostring() == "native" && !inputobj.isset( "product_id" )) { throw new wxpayexception( "統一支付接口中,缺少必填參數product_id!trade_type為jsapi時,product_id為必填參數!" ); } //異步通知url未設置,則使用配置文件中的url if (!inputobj.isset( "notify_url" )) { inputobj.setvalue( "notify_url" , config.notify_url); //異步通知url } inputobj.setvalue( "appid" , config.appid); //公眾賬號id inputobj.setvalue( "mch_id" , config.mchid); //商戶號 inputobj.setvalue( "spbill_create_ip" , config.ip); //終端ip inputobj.setvalue( "nonce_str" , generatenoncestr()); //隨機字符串 //簽名 inputobj.setvalue( "sign" , inputobj.makesign()); string xml = inputobj.toxml(); var start = datetime.now; log.debug( "wxpayapi" , "unfiedorder request : " + xml); string response = httpservice.post(xml, url, false , timeout); log.debug( "wxpayapi" , "unfiedorder response : " + response); var end = datetime.now; int timecost = ( int )((end - start).totalmilliseconds); wxpaydata result = new wxpaydata(); result.fromxml(response); reportcosttime(url, timecost, result); //測速上報 return result; } |
看我的調用例子:
makeqrcode.aspx頁面照抄:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public partial class pay_makeqrcode : system.web.ui.page { protected void page_load(object sender, eventargs e) { if (!string.isnullorempty(base.request.querystring[ "data" ])) { string str = base.request.querystring[ "data" ]; bitmap image = new qrcodeencoder { qrcodeencodemode = qrcodeencoder.encode_mode. byte , qrcodeerrorcorrect = qrcodeencoder.error_correction.m, qrcodeversion = 0 , qrcodescale = 4 }.encode(str, encoding. default ); memorystream ms = new memorystream(); image.save(ms, imageformat.png); base.response.binarywrite(ms.getbuffer()); base.response.end(); } } } |
這個頁面是用來生成二維碼的,需要引入thoughtworks.qrcode.dll組件。
我使用模式二,回調頁面是resultnotifypage.aspx,就是在配置信息那里填寫的那個回調頁面。
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
|
protected void page_load(object sender, eventargs e) { resultnotify resultnotify = new resultnotify( this ); wxpaydata res = resultnotify.processnotify2(); if (res.getvalue( "return_code" ) == "success" ) { //查詢微信訂單信息 string paysignkey = configurationmanager.appsettings[ "paysignkey" ].tostring(); string mch_id = configurationmanager.appsettings[ "mch_id" ].tostring(); string appid = configurationmanager.appsettings[ "appid" ].tostring(); queryorder queryorder = new queryorder(); queryorder.appid = appid; queryorder.mch_id = mch_id; queryorder.transaction_id = res.getvalue( "transaction_id" ).tostring(); queryorder.out_trade_no = "" ; queryorder.nonce_str = tenpayutil.getnoncestr(); tenpayutil tenpay = new tenpayutil(); orderdetail orderdeatil = tenpay.getorderdetail(queryorder, paysignkey); //寫微信記錄 ( new vinson()).writereturnwxdetail(orderdeatil); //寫充值記錄 filliedonline(orderdeatil.out_trade_no); } response.write(res.toxml()); response.end(); } |
掃碼支付成功后會異步到這個頁面執行代碼,我們自己的業務邏輯就要寫在這里。使用微信官方的processnotify()函數可不行,我們稍微修改下就好了。增加processnotify2函數:
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
|
public wxpaydata processnotify2() { wxpaydata notifydata = getnotifydata(); //檢查支付結果中transaction_id是否存在 if (!notifydata.isset( "transaction_id" )) { //若transaction_id不存在,則立即返回結果給微信支付后臺 wxpaydata res = new wxpaydata(); res.setvalue( "transaction_id" , "" ); res.setvalue( "return_code" , "fail" ); res.setvalue( "return_msg" , "支付結果中微信訂單號不存在" ); return res; } string transaction_id = notifydata.getvalue( "transaction_id" ).tostring(); //查詢訂單,判斷訂單真實性 if (!queryorder(transaction_id)) { //若訂單查詢失敗,則立即返回結果給微信支付后臺 wxpaydata res = new wxpaydata(); res.setvalue( "transaction_id" , transaction_id); res.setvalue( "return_code" , "fail" ); res.setvalue( "return_msg" , "訂單查詢失敗" ); return res; } //查詢訂單成功 else { wxpaydata res = new wxpaydata(); res.setvalue( "transaction_id" , transaction_id); res.setvalue( "return_code" , "success" ); res.setvalue( "return_msg" , "ok" ); return res; } } |
返回wxpaydata對象,這樣一判斷
1
|
if (res.getvalue( "return_code" ) == "success" ) |
表示支付成功,就可以進入我們的業務邏輯。
然后我們還要對當前訂單查單,獲取訂單的相關信息,之前微信未出demo的時候我自己寫了個查單的,就直接用了,關鍵wxpaydata對象會返回微信的訂單號:res.getvalue("transaction_id").tostring()。
完事后還要發送信息回給微信,通知微信后臺不要繼續發送異步請求了:
1
2
|
response.write(res.toxml()); response.end(); |
這個代碼比較重要了。
再說說放置二維碼的頁面:
- <div class="g-body">
- <div class="g-wrap">
- <div class="m-weixin">
- <div class="m-weixin-header">
- <p><strong>請您及時付款,以便訂單盡快處理!訂單號:<asp:label id="trade_no" runat="server" text="label"></asp:label></strong></p>
- <p>請您在提交訂單后1小時內支付,否則訂單會自動取消。</p>
- </div>
- <div class="m-weixin-main">
- <h1 class="m-weixin-title">
- <img alt="微信支付" src="../images/wxlogo_pay.png"/>
- </h1>
- <p class="m-weixin-money"><font>掃一掃付款</font><br/><strong>¥<asp:label id="money" runat="server" text="label"></asp:label></strong></p>
- <p>
- <img id="payqrimg" width="260" height="260" class="m-weixin-code" style="position: absolute;" src="<%=imageurl %>" alt="二維碼" style="border-width:0px;" />
- <img class="m-weixin-demo" src="../images/wxwebpay_guide.png" alt="掃一掃" />
- <img style="margin-top:300px;" src="../images/weixin_1.png" alt="請使用微信掃描二維碼以完成支付" />
- </p>
- <p id="we_ok" style="display:none;">
- <input value="完成" style="width: 300px; height: 50px; background: rgb(21, 164, 21) none repeat scroll 0% 0%; color: white; font-size: 30px; border: medium none; cursor: pointer;" type="button" />
- </p>
- </div>
- </div>
- </div>
- </div>
寫個js查單支付情況進行顯示:
- $(function () {
- var success = "<%=success %>";
- if (success == "error") {
- $(".g-body").hide();
- }
- })
- var icount = setinterval(check, 2000); //每隔2秒執行一次check函數。
- function check() {
- $.ajax({
- contenttype: "application/json",
- url: "/webservice/vinson.asmx/queryweixin",
- data: "{orderid:'" + $("#trade_no").text() + "'}",
- type: "post",
- datatype: "json",
- success: function (json) {
- json = eval("(" + json.d + ")");
- if (json.success == "success") {
- clearinterval(icount);
- $(".m-weixin-money font").html("已成功付款");
- $("#payqrimg").remove();
- $(".m-weixin-demo").before('<img alt="" src="../images/wx_ok.jpg" width="200">');
- $(".m-weixin-demo").next().remove();
- $("#we_ok").show();
- }
- },
- error: function (err, ex) {
- }
- });
- }
是的,我又寫了個給ajax使用的查單函數queryweixin。
我這里才是生成訂單和二維碼:
恩,還有啥呢,恩,看看效果吧:
支付成功后:
原文鏈接:http://www.cnblogs.com/vinsonlu/p/5166214.html
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。