zoukankan      html  css  js  c++  java
  • MVC 微信扫码支付

    微信扫码支付有两种模式,

    模式一和模式二,

    两者具体的区别可参考官网文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4

    微信官方的文档,这个扫码支付(NativePay)分为两种,一种是“生成扫描支付模式”,另外一种是“生成直接支付url,支付url有效期为2小时”,

    具体适用什么场景请自行定义。

    首先是申请微信支付,操作流程按照官方指引即可

     

    申请成功后,官方会发送你一封关于商户平台信息的Email

    接下来,我们就开始讲讲实际例子,

    首先下载官方Demo,Demo地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

    环境准备工作:

    然后将Demo的照搬到MVC工程中即可

    然后就是配置lib文件夹里的Config文件,基本很多信息,在Email中都有包括

    至于证书和商户支付密匙,则需要使用Emial的账户和密码去到微信商户平台去设置

    配置完成后即可开始测试

    如何生成:

    模式一:

    string url1 = nativePay.GetPrePayUrl("123456",ref out_trade_no,UserId.ToString());
                ViewBag.TradeNo = out_trade_no;
                ViewBag.QRCode = "/WxMakeQRCode?data=" + HttpUtility.UrlEncode(url1);

    模式二:

      string url2 = nativePay.GetPayUrl("123456", Money,ref out_trade_no,UserId.ToString());
                ViewBag.TradeNo = out_trade_no;
                ViewBag.QRCode = "/WxMakeQRCode?data=" + HttpUtility.UrlEncode(url2);
            public FileResult WxMakeQRCode(string data)
            {
                if (string.IsNullOrEmpty(data))
                    throw new ArgumentException("data");
    
                //初始化二维码生成工具
                QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
                qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
                qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
                qrCodeEncoder.QRCodeVersion = 0;
                qrCodeEncoder.QRCodeScale = 4;
    
                //将字符串生成二维码图片
                Bitmap image = qrCodeEncoder.Encode(data, Encoding.Default);
    
                //保存为PNG到内存流  
                MemoryStream ms = new MemoryStream();
                image.Save(ms, ImageFormat.Jpeg);
    
                return File(ms.ToArray(), "image/jpeg");
            }

     

    主要注意的地方是,在第一种模式中,必须设定回调路径

    模式二的回调路径是在Config中配置的

    回调方法:

    模式一:

    public class NativeNotifyController : Controller
        {
            // GET: NativeNotify
            public ActionResult Index()
            {
                string strData = ProcessNotify();
                Response.Write(strData);
                return View();
            }
    
    
            public string ProcessNotify()
            {
                WxPayData notifyData = GetNotifyData();
    
                //检查openid和product_id是否返回
                if (!notifyData.IsSet("openid") || !notifyData.IsSet("product_id"))
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "回调数据异常");
                    return res.ToXml();
                }
    
                //调统一下单接口,获得下单结果
                string openid = notifyData.GetValue("openid").ToString();
                string product_id = notifyData.GetValue("product_id").ToString();
                WxPayData unifiedOrderResult = new WxPayData();
                try
                {
                    unifiedOrderResult = UnifiedOrder(openid, product_id);
                }
                catch (Exception ex)//若在调统一下单接口时抛异常,立即返回结果给微信支付后台
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "统一下单失败");
                    return res.ToXml();
                }
    
                //若下单失败,则立即返回结果给微信支付后台
                if (!unifiedOrderResult.IsSet("appid") || !unifiedOrderResult.IsSet("mch_id") || !unifiedOrderResult.IsSet("prepay_id"))
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "统一下单失败");
                    return res.ToXml();
                }
    
                //统一下单成功,则返回成功结果给微信支付后台
                WxPayData data = new WxPayData();
                data.SetValue("return_code", "SUCCESS");
                data.SetValue("return_msg", "OK");
                data.SetValue("appid", WxPayConfig.APPID);
                data.SetValue("mch_id", WxPayConfig.MCHID);
                data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());
                data.SetValue("prepay_id", unifiedOrderResult.GetValue("prepay_id"));
                data.SetValue("result_code", "SUCCESS");
                data.SetValue("err_code_des", "OK");
                data.SetValue("sign", data.MakeSign());
                return data.ToXml();
            }
    
    
            /// <summary>
            /// 接收从微信支付后台发送过来的数据并验证签名
            /// </summary>
            /// <returns>微信支付后台返回的数据</returns>
            public WxPayData GetNotifyData()
            {
                //接收从微信后台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);
                }
    
                return data;
            }
    
            private WxPayData UnifiedOrder(string openId, string productId)
            {
                //统一下单
                WxPayData req = new WxPayData();
                req.SetValue("body", "OBOT");
                req.SetValue("attach", "附加信息,用于后台或者存入数据库,做自己的判断");
                req.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());
                req.SetValue("total_fee", 1);
                req.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));
                req.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));
                req.SetValue("goods_tag", "商品的备忘,可以自定义");
                req.SetValue("trade_type", "NATIVE");
                req.SetValue("openid", openId);
                req.SetValue("product_id", productId);
                WxPayData result = WxPayApi.UnifiedOrder(req);
                return result;
            }
        }

    模式二:

     public class ResultNotifyController : Controller
        {
            // GET: ResultNotify
            public ActionResult Index()
            {
                string strData = ProcessNotify();
                Response.Write(strData);
                return View();
            }
    
    
            public string ProcessNotify()
            {
                WxPayData notifyData = GetNotifyData();
    
                //检查支付结果中transaction_id是否存在
                if (!notifyData.IsSet("transaction_id"))
                {
                    //若transaction_id不存在,则立即返回结果给微信支付后台
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "支付结果中微信订单号不存在");
                    return res.ToXml();
                }
    
                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", "订单查询失败");
                    return res.ToXml();
                }
                //查询订单成功
                else
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "SUCCESS");
                    res.SetValue("return_msg", "OK");
                    Log.Info(this.GetType().ToString(), "order query success : " + res.ToXml());
                    string strXml = res.ToXml();
                    return res.ToXml();//如果我们走到这一步了,那就代表,用户已经支付成功了,所以,该干嘛干嘛了。
                }
            }
    
    
            /// <summary>
            /// 接收从微信支付后台发送过来的数据并验证签名
            /// </summary>
            /// <returns>微信支付后台返回的数据</returns>
            public WxPayData GetNotifyData()
            {
                //接收从微信后台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();
    
                Log.Info(this.GetType().ToString(), "Receive data from WeChat : " + builder.ToString());
    
                //转换数据格式并验证签名
                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);
                    Log.Error(this.GetType().ToString(), "Sign check error : " + res.ToXml());
                    return res;
                }
                
                return data;
            }
    
            //查询订单
            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;
                }
            }
        }

    最终效果:

  • 相关阅读:
    架构优秀文章汇总
    SpringCloud-Hystrix 注解配置Hystrix && 和FeignClient集成 (转)
    SpringCloud-Hystrix(服务熔断,服务降级)(1)
    java 锁 -乐观锁、悲观锁  Volatile
    JS OOP -02 深入认识JS中的函数
    JS OOP -01 面向对象的基础
    JS OOP 概述
    拆表策略
    双重检查加锁机制(并发insert情况下数据重复插入问题的解决方案)
    C# 理解lock
  • 原文地址:https://www.cnblogs.com/fanxingthink/p/6185840.html
Copyright © 2011-2022 走看看