.NET微信扫码支付接入(模式二-NATIVE)
程序员文章站
2022-04-10 13:38:18
一、前言
经过两三天的琢磨总算完成了微信扫码支付功能,不得不感叹几句:
微信提供的demo不错,直接复制粘...
一、前言
经过两三天的琢磨总算完成了微信扫码支付功能,不得不感叹几句:
微信提供的demo不错,直接复制粘贴就可以跑起来了;
微信的配置平台我真是服了。公众平台、商户平台、开放平台,一个平台一套账户密码,大写的恶心
demo地址:
.net版demo中的lib文件夹是关键,直接复制到自己的代码里,或者打成dll随个人意愿。
二、正文
step1:肯定是产生商户订单号,然后传给微信后台,由微信去组成二维码字符串,然后返给你,你再把字符串做成图片;
/// <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来生成图片:
/// <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返回的是一个空页面
/// <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; } }
三、结尾
做完支付宝与微信扫码支付发现支付宝的接入要比微信方便很多,还有一个同步请求。而且吐槽个其它的,微信开放平台的审批速度要比支付宝的审批慢很多。还有微信支付最后上线前不需要非得用沙箱测试,做完之后直接一分钱一分钱测试即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。