原文:微信原生支付 Native扫码支付( V3.3.7 版本)

[尊重别人的劳动成果,转载请注明出处:一缕晨光工作室,www.wispdawn.com]

前言

辛苦研究三天,遇到各种困难,最终还是克服了,把我的理解和思路分享给需要帮助的人,如果你觉的好,请帮我分享一下,谢谢。 在没有做之前,我以为和支付宝,以及银联一样,会在官网找到相应的demo,照葫芦画瓢即可,没有什么复杂的,真正去做的时候,发现各种错误,很多时候都莫名其妙找不到北, 在网上搜了不知道多少遍,有V3版的,不过都是js api版本的,没有找到原生扫码支付,下了几个V2版本的微信支付c#demo,感觉乱糟糟的。官网只提供了一个php版本的demo 研究了一天没有结果,第二天我决定从官网的php的原生扫码支付,根据他的逻辑,用c#写出来,下面就是所有思路及代码,文章最后我放上整个解决方案压缩包。

想实现扫码支付需要三大步骤

  1. 生成二维码,二维码包含产品ID
  2. 微信公众平台->微信支付->配置支付回调URL(自己开发回调页面)
  3. 开发支付成功后通知页面

最终效果如图

下面一步一步讲解

一.生成二维码

这步骤比较简单,根据官网文档 ,需要固定的参数,其中签名算法已经写好,如下代码

下图是用于生成二维码字符串,

public string CreateQRCodeUrl(string productid){Dictionary<string, string> dic = new Dictionary<string, string>();dic.Add("appid", helper.GetAppId);dic.Add("mch_id", helper.GetMch_Id);dic.Add("nonce_str", TenpayUtil.getNoncestr());dic.Add("product_id", productid);dic.Add("time_stamp", TenpayUtil.getTimestamp());dic.Add("sign",helper.GetSign(dic));string url = WxPayHelper.FormatBizQueryParaMap(dic, false);//这里不要url编码return "weixin://wxpay/bizpayurl?" + url;}

生成微信二维码字符串

最终生成的url

weixin://wxpay/bizpayurl?appid=wxed94e****9b4bc&mch_id=122468****&nonce_str=877A9BA7A98F75B90A9D49F53F15A858& product_id=1&sign=B2A03B1B6583972FF67C8AD3D7414DD1&time_stamp=1420466744

有了文本想生成二维码就简单了,起初我是采用ThoughtWorks.QRCode.dll,后来发现一值报错,超出数组范围,估计是字符串太长了,最后选择使用一个开源项目 Gma.QrCodeNet.Encoding.dll,速度很快。

代码如下

 WxPayHelper helper = new WxPayHelper();public void ProcessRequest(HttpContext context){         if (context.Request["buynum"]!=null){string proId ="1";//示例代码写死了,自己根据业务处理string qrurl = CreateQRCodeUrl(proId);QrEncoder qrEncoder = new QrEncoder(ErrorCorrectionLevel.H);Gma.QrCodeNet.Encoding.QrCode qrCode = new Gma.QrCodeNet.Encoding.QrCode();qrEncoder.TryEncode(qrurl, out qrCode);using (MemoryStream ms = new MemoryStream()){var renderer = new GraphicsRenderer(new FixedModuleSize(4, QuietZoneModules.Two));renderer.WriteToStream(qrCode.Matrix, ImageFormat.Png, ms);context.Response.ContentType = "image/png";context.Response.OutputStream.Write(ms.GetBuffer(), 0, (int)ms.Length);}}          }

生成二维码

前台js调用

$(function () {$("#txtKey").keyup(function () {               var num=$(this).val();//这里设置购买数量$("#qrDiv").html("<img src=QrCode.ashx?buynum="+num+" height=200 width=200 /> ");});});

二、写回调页面,本程序是NativeCallBack.aspx

这个页面主要任务是当扫码二维码的时候,微信向这个页面post XML数据,其中包含产品id,即二维码上的产品id ,我们需要根据产品id,查询产品名称,总价格,以及一些附属信息, 我们需要再次把这些参数post给微信统一支付接口,如果数据正确,微信会给我们生成一个prepay_id 预支付id,我们再次把prepay_id post给微信,整个流程即是这样子的,其实产品id就相当于一个订单号,唯一性,当然你也可以根据产品id,在这个页面里面下单,业务根据自己需要处理。

页面代码如下

log4net.ILog logger = WxV3.Helper.LogHelper.GetInstance().Log;WxV3.Helper.WxPayHelper helper = new Helper.WxPayHelper();protected void Page_Load(object sender, EventArgs e){//1.接受微信平台post 过来的XML信息//2.验证签名,从XML中获取ProductID,获取产品信息//2.1设置out_trade_no,total_fee,notify_url,trade_type,product_id 参数,提交统一接口         //3.提交统一接口后获取PrepayId//4.将PrepayId 和return 根据参数拼接生xml信息(其中包含生成的package参数)输出if (Request.RequestType == "POST"){try{StreamReader reader = new StreamReader(Request.InputStream);String xmlData = reader.ReadToEnd();helper.ReceivePostXmlData(xmlData);logger.Info("接收post来的xmlData=" + xmlData);if (helper.CheckSign()){logger.Info("签名验证通过");string proId = helper.GetProductId();logger.Info("产品id=" + proId);switch (proId){case "1":#region 业务处理helper.SetParameter("body", "一缕晨光CMS系统");helper.SetParameter("out_trade_no", DateTime.Now.ToString("yyyyMMddHHmmss") + CommonUtil.BuildRandomStr(4));helper.SetParameter("total_fee", "88800");//这里单位是分helper.SetParameter("notify_url", "http://www.wispdawn.com/WxV3/NativeNotify.aspx");helper.SetParameter("trade_type", "NATIVE");string prepay_id = helper.GetPrepayId();logger.Info("prepay_id=" + prepay_id);if (!string.IsNullOrEmpty(prepay_id)){helper.SetReturnParameter("return_code", "SUCCESS");helper.SetReturnParameter("result_code", "SUCCESS");helper.SetReturnParameter("prepay_id", prepay_id);helper.SetReturnParameter("appid", helper.GetAppId);helper.SetReturnParameter("mch_id", helper.GetMch_Id);helper.SetReturnParameter("nonce_str", TenpayUtil.getNoncestr());}else{helper.SetReturnParameter("return_code", "SUCCESS");//返回状态码helper.SetReturnParameter("result_code", "FAIL");//业务结果helper.SetReturnParameter("err_code_des", "预订单生产失败");}#endregionbreak;default:helper.SetReturnParameter("return_code", "SUCCESS");//返回状态码helper.SetReturnParameter("result_code", "FAIL");//业务结果helper.SetReturnParameter("err_code_des", "此商品无效");//业务结果break;}}else{helper.SetReturnParameter("return_code", "FAIL");helper.SetReturnParameter("return_msg", "签名失败");logger.Info("签名验证没有通过");}string xmlStr = helper.GetReturnXml();logger.Info("返回xml=" + xmlStr);Response.ContentType = "text/xml";Response.Clear();Response.Write(xmlStr);Response.End();}catch (Exception ex){logger.Error("异常了", ex);}}}

NativeCallBack代码

三、支付通知页面,本程序 NativeNotify.aspx

这个页面用来处理成功通知的,微信把交易的结果依xml形式post该页面,当你收到消息后,如果成功了,你可以根据此来修改数据库,或者更新状态,等等。我做到这步时候,需要实现扫码二维码,支付成功后,3秒后调整, 实现思路是这样的,在二维码页面,setinterval get后台数据库是否已经支付,如果已经支付则执行settimeout 3秒后调整到成功页面。目前我是这样实现的,不知道别人怎么实现的。

通知代码如下。

  log4net.ILog logger = WxV3.Helper.LogHelper.GetInstance().Log;WxV3.Helper.WxPayHelper helper = new Helper.WxPayHelper();protected void Page_Load(object sender, EventArgs e){if (Request.RequestType == "POST"){try{StreamReader reader = new StreamReader(Request.InputStream);String xmlData = reader.ReadToEnd();helper.ReceivePostXmlData(xmlData);logger.Info("Notify_接收post来的xmlData=" + xmlData);if (helper.CheckSign()){Dictionary<string, string> dicBack = helper.GetParameter();//获取所有参数if (dicBack!=null&&dicBack.Keys.Contains("return_code")){if (dicBack["return_code"] == "SUCCESS"){logger.Info("return_code=SUCCESS");if (dicBack["result_code"]=="SUCCESS"){logger.Info("result_code=SUCCESS");                                  string out_trade_no = dicBack["out_trade_no"];//商户订单号logger.Info("out_trade_no="+out_trade_no);//1.验证商户订单号是否被处理//2.处理过直接返回成功,否则返回//此处根据out_trade_no 处理业务数据//处理业务数据结束
logger.Info("Notify_验证签名成功");helper.SetReturnParameter("return_code", "SUCCESS");helper.SetReturnParameter("return_msg", "");   }    }if (dicBack["return_code"]=="FAIL"){logger.Info("Notify_验证签名成功");helper.SetReturnParameter("return_code", "SUCCESS");helper.SetReturnParameter("return_msg", dicBack["return_msg"]);    }}}else{logger.Info("Notify_验证签名失败");helper.SetReturnParameter("return_code", "FAIL");helper.SetReturnParameter("return_msg", "签名失败");     }string xmlStr = helper.GetReturnXml();logger.Info("Notify_返回xml=" + xmlStr);Response.ContentType = "text/xml";Response.Clear();Response.Write(xmlStr);Response.End();}catch (Exception ex){logger.Error("Notify_异常了", ex);}}}

NativeNotify页面代码

如果你也是需要扫描原生支付,可以直接下载本解决方案,只需要把 WxPayHelper构造函数中的参数修改下即可使用

 public WxPayHelper(){this.parameters = new Dictionary<string, string>();this.returnParameter = new Dictionary<string, string>();this.appid = "wxed94e6985d29****";//appidthis.mch_id = "122468****";      //微信支付商户号         this.PartnerKey = "ASD2Ssaghh3df4570erdssd4we33****";//这里是商户的partnerkey  }

本文主要讲解整个思路,详细请看代码,点击下载本解决方案

尊重别人的劳动成功,转载请注明出处:一缕晨光工作室,www.wispdawn.com

微信原生支付 Native扫码支付( V3.3.7 版本)相关推荐

  1. thinkphp3.2 微信 Native扫码支付功能

    Native 扫码支付之模式二 (模式一好像是不再支持了) 准备工作 认证过的服务号  商户号  业务域名 WxPay.Config.php 目录下面的这个文件记得要配置appid 这些 注意: 扫码 ...

  2. Java 微信native扫码支付 亲测有用

    最近在网上总结了spring cloud 微信扫码支付的流程, 本人是刚入行的小白,有不对的地方请大家指出 也欢迎大家来多多交流 我的商户APPID和秘钥的一些配置信息,是公司的 这些需要微信的商户认 ...

  3. ThinkPHP整合微信支付之Native 扫码支付 模式二

    大家好,这篇文章是继微信支付之Native 扫码支付 模式一之后的微信支付系列教程第三篇:扫码支付之模式二 介绍下扫码支付目前有两种模式,模式一比模式二稍微复杂点,至于模式一与模式二的具体内容,流程, ...

  4. ThinkPHP整合微信支付之Native 扫码支付 模式一

    大家好,这篇文章是继微信支付jsapi篇之后的微信支付系列教程第二篇:扫码支付之模式一 介绍下扫码支付目前有两种模式,模式一比模式二稍微复杂点,至于模式一与模式二的具体内容,流程,微信开发文档都有详细 ...

  5. php接入微信支付,扫码支付和H5支付(非微信浏览器),基于thinkPHP框架 WeChatDeveloper支付类包 踩坑指南

    此文章入选<PHP领域内容榜>第4名 文章介绍 本文主要介绍通过thinkPHP5和第三方支付类包(WeChatDeveloper)实现快速接入微信扫码支付和微信H5手机网站支付(非微信浏 ...

  6. 微信支付之扫码支付与小程序支付

    微信支付之扫码支付与小程序支付 前言:最近的需求中,频繁出现微信支付功能的开发,于是研读了微信官方开发文档以及相关代码做了以下总结,并记录在此,以备不时之需.如有不足之处,欢迎批评指正. 微信官方开发 ...

  7. 第三篇、记录微信统一支付、扫码支付开发

    项目中使用了微信的统一支付以及扫码支付,记录下学习记录 目录 项目中使用了微信的统一支付以及扫码支付,记录下学习记录 1.配置wechat4j.properties 文件 2.编写支付工具类 3.统一 ...

  8. 微信和支付宝H5扫码支付开发记录

    微信和支付宝H5扫码支付开发记录 微信支付 支付宝支付 简单前端实现的一下方法,服务端方法未记录: 微信支付 微信流程步骤简介 1.获取用户code 2.拉起微信支付 支付宝支付 支付宝流程步骤简介: ...

  9. 手机H5支付和扫码支付的区别是什么?

    H5支付就是网页发起的微信.支付宝唤醒,通过微信自带的微信浏览器内jssdk发起的微信支付.支付宝也可以拉起手机浏览器唤醒支付宝发起支付宝支付. 扫码支付即通过手机app进行扫码付款,最常用的软件如微 ...

  10. 支付宝支付之扫码支付(电脑网站支付)、H5支付(手机网站支付)相关业务流程分析总结

    前言 在上一篇文章<微信支付之扫码支付.公众号支付.H5支付.小程序支付相关业务流程分析总结>中,分析和总结了微信支付相关支付类型的业务流程,这里作为与微信支付平起平坐不相伯仲的支付宝支付 ...

最新文章

  1. centos安装mysql wsl_在 Windows Linux 子系统中安装 CentOS
  2. iOS开发之用到的几种锁整理
  3. 2_vuex状态管理器
  4. linux模拟树莓派,树莓派使用入门:树莓派上的模拟器和原生 Linux 游戏
  5. C++ Set常用用法
  6. 四张图揭秘中国AI人才现状
  7. spring cloud使用hystrix实现断路保护机制
  8. Dockerfile指令详解:ONBUILD 为他人作嫁衣裳
  9. 通过js 判断当前应用是什么浏览器【借鉴转载】
  10. java 分贝_java11教程--jhsdb命令
  11. 6.824 MapReduce lab1 2020(一)
  12. 构建一个文本搜索系统
  13. Sublime 解决目录显示为方块的问题
  14. 530并行日:用超算更省心
  15. WHEREIS(1)
  16. 值得看的hadoop书籍
  17. python自定义变量名标识符,【python】3 标识符和关键字
  18. 如何删除C++容器中的值
  19. 郭宏志的android无线点餐系统,Android无线点餐系统--含代码.doc
  20. 金融数据分析期末报告:基于时间序列的回归模型及其应用

热门文章

  1. paip.消除 Java 的冗长try/catch/finally
  2. 阿里云 DNS 运维服务的演进和实践
  3. Kafka从上手到实践 - 庖丁解牛:Consumer | 凌云时刻
  4. 疫期免费 “零接触”云迁移~工具替代人力! 人不聚,活儿继续!
  5. 2019上海开源峰会炉边会谈纪要
  6. 【优化选址】基于matlab蚁群算法求解电动汽车充电站与换电站选址优化问题【含Matlab源码 1182期】
  7. 【TWVRP】基于matlab遗传和模拟退火算法求解带时间窗的取送货问题【含Matlab源码 1139期】
  8. SPSS 相关分析(图文+数据集)【SPSS 023期】
  9. php数据库数据分割,使用PHP将分隔的值文件导入数据库时??,...
  10. python:使用strip()去掉首尾空格