三沣开发知识 购物 网址 游戏 小说 歌词 地图 快照 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 开发 租车 短信 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题
autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml
html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> C# -> 【移动支付】.NET微信扫码支付接入(模式二 -> 正文阅读
 

[C#]【移动支付】.NET微信扫码支付接入(模式二

【移动支付】.NET微信扫码支付接入(模式二 一、前言
      经过两三天的琢磨总算完成了微信扫码支付功能,不得不感叹几句:
微信提供的DEMO不错,直接复制粘贴就可以跑起来了; 微信的配置平台我真是服了。公众平台、商户平台、开放平台,一个平台一套账户密码,大写的恶心
       DEMO地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1
       .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;
            }
        }

三、结尾
      做完支付宝与微信扫码支付发现支付宝的接入要比微信方便很多,还有一个同步请求。而且吐槽个其它的,微信开放平台的审批速度要比支付宝的审批慢很多。还有微信支付最后上线前不需要非得用沙箱测试,做完之后直接一分钱一分钱测试即可。
  C# 最新文章
一个小时学会MySQL数据库
使用重绘项美化WinForm中的控件
c# Http下载文件
Autofac的简单使用
C#中的装箱(inboxing)和拆箱(unboxing)(简
C# Random 实现 long型随机数
委托与匿名委托
02、Win
C#最实用的快捷键
C#矩阵运算类库
上一篇文章           查看所有文章
加:2017-10-12 23:21:44  更:2017-10-12 23:21:59 
 
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2017年10日历
2017-10-22 7:06:06
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库