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

模式一和模式二,

两者具体的区别可参考官网文档: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("",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 = ;
qrCodeEncoder.QRCodeScale = ; //将字符串生成二维码图片
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 = ;
byte[] buffer = new byte[];
StringBuilder builder = new StringBuilder();
while ((count = s.Read(buffer, , )) > )
{
builder.Append(Encoding.UTF8.GetString(buffer, , 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", );
req.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));
req.SetValue("time_expire", DateTime.Now.AddMinutes().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 = ;
byte[] buffer = new byte[];
StringBuilder builder = new StringBuilder();
while ((count = s.Read(buffer, , )) > )
{
builder.Append(Encoding.UTF8.GetString(buffer, , 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;
}
}
}

最终效果:

MVC 微信扫码支付的更多相关文章

  1. Net MVC微信扫码支付

    微信扫码支付+Asp.Net MVC 这里的扫码支付指的是PC网站上面使用微信支付,也就是官方的模式二,网站是Asp.net MVC,整理如下. 一.准备工作 使用的微信API中的统一下单方法,关键的 ...

  2. C# MVC微信扫码支付

    项目需求:学校学生网上缴费项目,刚来公司实习网上百度了各种资料,感谢很多大神避免了很多大坑. 本次扫码支付为:电脑生成二维码,手机微信扫码进行付款.建议开发前下载官方demo熟悉及后续有用到里面代码: ...

  3. .NET MVC结构框架下的微信扫码支付模式二 API接口开发测试

    直接上干货 ,我们的宗旨就是为人民服务.授人以鱼不如授人以渔.不吹毛求疵.不浮夸.不虚伪.不忽悠.一切都是为了社会共同进步,繁荣昌盛,小程序猿.大程序猿.老程序猿还是嫩程序猿,希望这个社会不要太急功近 ...

  4. ASP.NET Core Web 支付功能接入 微信-扫码支付篇

    这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入微信-扫码支付及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET Core SDK ...

  5. 【转载】ASP.NET Core Web 支付功能接入 微信-扫码支付篇

    转自:http://www.cnblogs.com/essenroc/p/8630730.html 这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入微信-扫码支付及异步 ...

  6. asp.net core 微信扫码支付(扫码支付,H5支付,公众号支付,app支付)之1

    2018-08-13更新生成二维码的方法 在做微信支付前,首先要了解你需要什么方式的微信支付,目前本人做过的支付包含扫码支付.H5支付.公众号支付.App支付等,本人使用的是asp.net mvc c ...

  7. 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付

    在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...

  8. JAVA微信扫码支付模式二功能实现完整例子

    概述 本例子实现微信扫码支付模式二的支付功能,应用场景是,web网站微信扫码支付.实现从点击付费按钮.到弹出二维码.到用户用手机微信扫码支付.到手机上用户付费成功.web网页再自动调整到支付成功后的页 ...

  9. ASP.NET Core Web 支付功能接入 微信-扫码支付篇(转)

    原文 https://www.cnblogs.com/essenroc/p/8630730.html // 随着版本更迭,新版本可能无法完全适用,请参考仓库内的示例. 这篇文章将介绍ASP.NET C ...

随机推荐

  1. VBA_Excel_教程:单元格颜色

    Sub SetCellColor() '设置单元格颜色 Sheet1.Cells(, ).Interior.ColorIndex = End Sub

  2. python 赋值、表达式

    赋值的特性 赋值语句建立对象引用 变量名在首次赋值时会被创建 变量名在引用前必须先赋值 赋值语句的形式 序列赋值 >>> A, B = 1, 2 >>> print ...

  3. 项目中遇到的各种bug和踩过的坑

    zepto 赋值时单位转换问题 zepto 的 animate 方法移动某个元素的位置时,例如修改某个绝对定位的元素的 left 值,要与修改前的值单位一致,修改前如果是像素值,修改后也要是像素值,否 ...

  4. C语言Notebook

    int *pointer=NULL    /*指针变量一定要赋初值*/pritnf("Pointer' address is:%p",&pointer);  /*打印指针变 ...

  5. 常用的dos命令

    cd 进入一个目录 cd .. 返回上一个目录 dir 遍历目录 上下键 查找输入过的命令 Tab键 命令自动补齐

  6. for..in遍历,枚举器

    #pragma mark ------------for循环遍历集合中的元素------ //创建一个数组,包含5个字符串对象,倒序取出数组中的所有元素,并存储到另一可变数组中 NSArray *ar ...

  7. vi常用命令

    哎,看书上vi命令那么多,真是记不住.记几个常用的备忘吧. 在一般模式下(不可编辑),比如用vi命令打开或创建一个文件,常用的命令如下: 按键 作用 h或← 光标左移动一个字符 j或↓ 光标下移动一个 ...

  8. Web前端安全问题

    1.XXS跨站脚本攻击(Cross Site Scripting) 1)通过<script> 举个例子:通过QQ群,或者通过群发垃圾邮件,来让其他人点击这个地址: book.com/sea ...

  9. ubuntu14.04下安装cudnn5.1.3,opencv3.0,编译caffe及配置matlab和python接口过程记录

    已有条件: ubuntu14.04+cuda7.5+anaconda2(即python2.7)+matlabR2014a 上述已经装好了,开始搭建caffe环境. 1. 装cudnn5.1.3,参照: ...

  10. java多线程的几种实现方式记录

    传统的实现线程的方式为三种,分别为继承Thread类,重写run()方法:实现Runable接口,重写run()方法:实现callable接口,重写call()方法:下面来记录一下最基本的三种编码实现 ...