c#版在pc端发起微信扫码支付的实例

时间:2022-03-31 07:51:52

等了好久,微信官方终于发布了.net的demo。c#版在pc端发起微信扫码支付的实例c#版在pc端发起微信扫码支付的实例

主要代码:

?
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;
  }

看我的调用例子:
c#版在pc端发起微信扫码支付的实例
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();

这个代码比较重要了。

再说说放置二维码的页面:

  1. <div class="g-body"
  2.  <div class="g-wrap"
  3.   <div class="m-weixin"
  4.    <div class="m-weixin-header"
  5.     <p><strong>请您及时付款,以便订单尽快处理!订单号:<asp:label id="trade_no" runat="server" text="label"></asp:label></strong></p> 
  6.     <p>请您在提交订单后1小时内支付,否则订单会自动取消。</p> 
  7.    </div> 
  8.    <div class="m-weixin-main"
  9.     <h1 class="m-weixin-title"
  10.      <img alt="微信支付" src="../images/wxlogo_pay.png"/> 
  11.     </h1> 
  12.     <p class="m-weixin-money"><font>扫一扫付款</font><br/><strong>¥<asp:label id="money" runat="server" text="label"></asp:label></strong></p> 
  13.     <p> 
  14.      <img id="payqrimg" width="260" height="260" class="m-weixin-code" style="position: absolute;" src="<%=imageurl %>" alt="二维码" style="border-width:0px;" /> 
  15.      <img class="m-weixin-demo" src="../images/wxwebpay_guide.png" alt="扫一扫" /> 
  16.      <img style="margin-top:300px;" src="../images/weixin_1.png" alt="请使用微信扫描二维码以完成支付" /> 
  17.     </p> 
  18.     <p id="we_ok" style="display:none;"
  19.      <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" /> 
  20.     </p> 
  21.    </div> 
  22.   </div> 
  23.  </div> 
  24. </div> 

写个js查单支付情况进行显示:

  1. $(function () { 
  2.   var success = "<%=success %>"
  3.   if (success == "error") { 
  4.    $(".g-body").hide(); 
  5.   } 
  6.  }) 
  7.  
  8.  var icount = setinterval(check, 2000); //每隔2秒执行一次check函数。 
  9.  
  10.  function check() { 
  11.   $.ajax({ 
  12.    contenttype: "application/json"
  13.    url: "/webservice/vinson.asmx/queryweixin"
  14.    data: "{orderid:'" + $("#trade_no").text() + "'}"
  15.    type: "post"
  16.    datatype: "json"
  17.    success: function (json) { 
  18.     json = eval("(" + json.d + ")"); 
  19.     if (json.success == "success") { 
  20.      clearinterval(icount); 
  21.      $(".m-weixin-money font").html("已成功付款"); 
  22.      $("#payqrimg").remove(); 
  23.      $(".m-weixin-demo").before('<img alt="" src="../images/wx_ok.jpg" width="200">'); 
  24.      $(".m-weixin-demo").next().remove(); 
  25.      $("#we_ok").show(); 
  26.     } 
  27.    }, 
  28.    error: function (err, ex) { 
  29.    } 
  30.   }); 
  31.  } 

是的,我又写了个给ajax使用的查单函数queryweixin。

我这里才是生成订单和二维码:c#版在pc端发起微信扫码支付的实例
恩,还有啥呢,恩,看看效果吧:c#版在pc端发起微信扫码支付的实例

支付成功后:c#版在pc端发起微信扫码支付的实例

原文链接:http://www.cnblogs.com/vinsonlu/p/5166214.html

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。