微信扫码支付native 模式二支付完成回调页面问题

发布网友

我来回答

2个回答

懂视网

一、前言

      经过两三天的琢磨总算完成了微信扫码支付功能,不得不感叹几句:

微信提供的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 ProductQRCode");
 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;
 }
 }

三、结尾

      做完支付宝与微信扫码支付发现支付宝的接入要比微信方便很多,还有一个同步请求。而且吐槽个其它的,微信开放平台的审批速度要比支付宝的审批慢很多。还有微信支付最后上线前不需要非得用沙箱测试,做完之后直接一分钱一分钱测试即可。

热心网友

支付成功后要加判断,有个返回值取过来,成功就跳转页面,不成功就返回失败

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com