好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

等了好久,微信官方终于发布了.net的demo。

主要代码:

?

/**

   * 生成直接支付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;

   }

配置信息:

?

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方法的下面代码:
 

?

//设置代理服务器

     //webproxy proxy = new webproxy();       //定义一个网关对象

     //proxy.address = new uri(config.proxy_url);    //网关服务器端口:端口

     //request.proxy = proxy;

统一下单:

?

/**

   *

   * 统一下单

   * @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页面照抄:

?

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,就是在配置信息那里填写的那个回调页面。

?

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函数:
 

?

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对象,这样一判断

?

if (res.getvalue( "return_code" ) == "success" )

表示支付成功,就可以进入我们的业务逻辑。

然后我们还要对当前订单查单,获取订单的相关信息,之前微信未出demo的时候我自己写了个查单的,就直接用了,关键wxpaydata对象会返回微信的订单号:res.getvalue("transaction_id").tostring()。

完事后还要发送信息回给微信,通知微信后台不要继续发送异步请求了:

    

?

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

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

dy("nrwz");

查看更多关于c#版在pc端发起微信扫码支付的实例的详细内容...

  阅读:38次