等了好久,微信官方终于发布了.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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。