C# MVC微信扫码支付
项目需求:学校学生网上缴费项目,刚来公司实习网上百度了各种资料,感谢很多大神避免了很多大坑。
本次扫码支付为:电脑生成二维码,手机微信扫码进行付款。建议开发前下载官方demo熟悉及后续有用到里面代码:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
1.微信公众平台→支付配置→支付授权目录(授权目录就是指你要进行支付的目录)添加你的项目发布文件网址,手上暂无公司微信公众平台账号,百度上下有什么详细说明就不再说明了。
2.新建MVC项目→新建文件夹Resources将官方demo中的business和lib文件夹复制过来
3.打开lib文件夹里的config,在这里配置基础信息和支付回调地址
4.新建WxPay页面,此页面展示付款二维码,采用了jquery.qrcode.min.js生成二维码,贴部分重要代码
<script language="javascript">
$(function () {
GetWXQRCode();
}); function GetWXQRCode() {
//$('#QRCode').css('display', ''); //去除隐藏
//$('#paytitle').html('微信支付');
$('#tradeno').html('');
$('#paymoney').html('');
$.ajax({
type: "post",
url: "/StudentIndex/GetWXQRCode",
data: {
time: new Date(),
productId: "考试费用",
idcard: '@ViewBag.idcard',
},
success: function (json) {
if (json.result) {
$("#QRCode").qrcode(json.str); //生成二维码
$("#tradeno").html(json.no); //订单编号
$('#paymoney').html(json.money);
}
else {
$("#QRCode").html("二维码生成失败");
}
},
error: function (json) {
$("#QRCode").html("二维码生成错误");
}
})
} <div class="i_ma">
<div class="i_name">
微信支付
<p>WeChat Payment</p>
</div>
<div class="space_hx"> </div> <div>订单编号:<p id="tradeno"></p></div>
<div>考试费用:<p id="paymoney"></p></div>
<div id="QRCode">
</div> </div> <div class="space_hx"> </div>
5.控制器内添加生成二维码方法,这里面的idcard是学生身份证,添加到附加数据内便于后面查询订单时判断是谁缴了费
//生成微信支付二维码
[HttpPost]
public ActionResult GetWXQRCode(string idcard)
{
object objResult = "";
string tradeno;
string paymoney;
string strProductID = Request.Form["productId"]; //商品ID
string strQRCodeStr = GetWXPayUrl(strProductID, idcard, out tradeno, out paymoney);
//Session["outtradeno"] = outtradeno;
if (!string.IsNullOrWhiteSpace(strProductID))
{
objResult = new { result = true, str = strQRCodeStr, no = tradeno, money = paymoney };
}
else
{
objResult = new { result = false };
} return Json(objResult);
} //生成直接微信支付url,支付url有效期为10分钟,模式二
public string GetWXPayUrl(string productId, string idcard, out string out_trade_no, out string money)
{
WxPayData data = new WxPayData();
data.SetValue("body", "分类考试学费");//商品描述
data.SetValue("attach", idcard);//附加数据
out_trade_no = WxPayApi.GenerateOutTradeNo();
//Session["out_trade_no"] = out_trade_no;
data.SetValue("out_trade_no", out_trade_no);//随机字符串
string total = Convert.ToInt32((context.receiptInfoModel.OrderBy(x => x.ID).FirstOrDefault().PayMoney * )).ToString();
money = context.receiptInfoModel.OrderBy(x => x.ID).FirstOrDefault().PayMoney + "元";
data.SetValue("total_fee", total);//总金额
data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始时间
data.SetValue("time_expire", DateTime.Now.AddMinutes().ToString("yyyyMMddHHmmss"));//交易结束时间
data.SetValue("goods_tag", "商品的备忘,可以自定义");//商品标记
data.SetValue("trade_type", "NATIVE");//交易类型
data.SetValue("product_id", productId);//商品ID
WxPayData result = WxPayApi.UnifiedOrder(data);//调用统一下单接口
string url = result.GetValue("code_url").ToString();//获得统一下单接口返回的二维码链接
PreWxPayOrder(idcard, out_trade_no);
return url;
} //生成二维码同时,生成预支付订单
public void PreWxPayOrder(string idcard, string out_trade_no)
{
WxPayOrderModel model = new WxPayOrderModel();
model.StudentCard = idcard;
model.OrderNo = out_trade_no;
model.OrderTime = DateTime.Now;
model.Status = ;
model.OrderType = "微信";
context.wxpayOrderModel.Add(model);
context.SaveChanges();
//Log.Info("生成预支付订单","订单号:"+out_trade_no);
}
6.新建wxpayok页面(此页面是config里配置的支付回调url),视图不需要改动,在控制器里添加接收微信返回的数据
//接收微信返回信息
public ActionResult WxPayOK()
{
//接收从微信后台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);
Log.Error("签名错误", "Sign check error : " + res.ToXml());
Response.Write(res.ToXml());
Response.End();
} ProcessNotify(data); return View();
} //微信支付后台返回的数据
public void ProcessNotify(WxPayData data)
{
WxPayData notifyData = data; //检查支付结果中transaction_id是否存在
if (!notifyData.IsSet("transaction_id"))
{
WxPayData res = new WxPayData();
res.SetValue("return_code", "FAIL");
res.SetValue("return_msg", "支付结果中微信订单号不存在");
Log.Error("ERROR", "订单号不存在");
Response.Write(res.ToXml());
Response.End();
}
else
{
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", "订单查询失败");
Log.Error("ERROR", "订单查询失败");
Response.Write(res.ToXml());
Response.End();
}
else
{
WxPayData res = new WxPayData();
res.SetValue("return_code", "SUCCESS");
res.SetValue("return_msg", "OK");
//Log.Info("success", "支付成功");
AddWayPayRecord(data.GetValue("out_trade_no").ToString(), data.GetValue("transaction_id").ToString(), data.GetValue("attach").ToString());
Response.Write(res.ToXml());
Response.End();
}
}
} //查询订单
public 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;
}
} //微信支付完成添加记录 tradeno:订单号
public void AddWayPayRecord(string tradeno, string tranid, string idcard)
{
lock (wxlock)//线程同步
{
WxPayOrderModel wxpayOrderModel = context.wxpayOrderModel.FirstOrDefault(x => x.OrderNo == tradeno && x.OrderType == "微信" && x.StudentCard == idcard && x.Status == );
if (wxpayOrderModel != null)
{
wxpayOrderModel.Status = ;
context.Entry(wxpayOrderModel).State = System.Data.EntityState.Modified;
context.SaveChanges(); StudentModel studentModel = context.studentModel.Where(a => a.identityCard == wxpayOrderModel.StudentCard).FirstOrDefault();
PayModel payModel = context.payModel.FirstOrDefault(x => x.studentid == studentModel.candidateNum);
Random rd = new Random(); if (payModel == null)
{
PayModel paymodel = new PayModel();
paymodel.paycount = context.receiptInfoModel.OrderBy(x => x.ID).FirstOrDefault().PayMoney;
paymodel.ordernumber = tradeno;
paymodel.paytime = DateTime.Now;
paymodel.PayOddNum = tranid;
context.payModel.Add(paymodel);
context.SaveChanges();
}
}
}
}
7.这时候页面也接收到微信返回的数据同时也添加到数据库中,页面上得给用户一个友好提示,告诉他支付成功了。在wxpay页面里加个ajax实时轮询数据库
$(function () {
setInterval(GetWxPayResult, );
function GetWxPayResult() {
var no = $("#tradeno").text();
$.ajax({
url: "/StudentIndex/WxPayResult",
type: "post",
data: {
idcard: '@ViewBag.idcard',
tradeno:no,
},
success: function (json) {
if (json.result) {
document.location.href = "/StudentIndex/WxPayisOK?idcard=@ViewBag.idcard"+"&&tradeno="+no;
}
else {
}
},
error: function (json) {
alert("错误");
}
})
}
})
同时控制器里需要加上对应的方法,判断支付成功后跳转到一个新的页面wxpayisok
//ajax轮询支付结果
public ActionResult WxPayResult(string idcard, string tradeno)
{
object data = "";
StudentModel studentModel = context.studentModel.FirstOrDefault(x => x.identityCard == idcard);
PayModel model = context.payModel.FirstOrDefault(x => x.studentid == studentModel.candidateNum);
if (model != null)
{
data = new { result = true };
}
return Json(data);
} //支付完成
public ActionResult WxPayisOK(string idcard, string tradeno)
{
StudentModel studentModel = context.studentModel.FirstOrDefault(x => x.identityCard == idcard);
PayModel model = context.payModel.FirstOrDefault(x => x.studentid == studentModel.candidateNum); if (model != null)
{
return Content("<Script>alert('缴费成功!');window.location.href='/StudentIndex/StudentIndex';</Script>");
}
else
{
return Content("<Script>alert('缴费失败!请保留好支付凭证前往缴费处申请退款');window.location.href='/StudentIndex/StudentIndex';</Script>");
}
}
结尾:第一次写博客有些乱,微信支付安全性还需要提高,项目部署也没经过大批量测试,就直接上线。
到现在也经历过两次几千人的缴费,一分钟缴费好几次,也碰到过网络延迟问题缴费成功后没及时更新数据库和一个浏览器打开两次微信支付界面导致两次缴费只算一次的各种问题。
C# MVC微信扫码支付的更多相关文章
- MVC 微信扫码支付
微信扫码支付有两种模式, 模式一和模式二, 两者具体的区别可参考官网文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4 微 ...
- Net MVC微信扫码支付
微信扫码支付+Asp.Net MVC 这里的扫码支付指的是PC网站上面使用微信支付,也就是官方的模式二,网站是Asp.net MVC,整理如下. 一.准备工作 使用的微信API中的统一下单方法,关键的 ...
- .NET MVC结构框架下的微信扫码支付模式二 API接口开发测试
直接上干货 ,我们的宗旨就是为人民服务.授人以鱼不如授人以渔.不吹毛求疵.不浮夸.不虚伪.不忽悠.一切都是为了社会共同进步,繁荣昌盛,小程序猿.大程序猿.老程序猿还是嫩程序猿,希望这个社会不要太急功近 ...
- ASP.NET Core Web 支付功能接入 微信-扫码支付篇
这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入微信-扫码支付及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET Core SDK ...
- 【转载】ASP.NET Core Web 支付功能接入 微信-扫码支付篇
转自:http://www.cnblogs.com/essenroc/p/8630730.html 这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入微信-扫码支付及异步 ...
- asp.net core 微信扫码支付(扫码支付,H5支付,公众号支付,app支付)之1
2018-08-13更新生成二维码的方法 在做微信支付前,首先要了解你需要什么方式的微信支付,目前本人做过的支付包含扫码支付.H5支付.公众号支付.App支付等,本人使用的是asp.net mvc c ...
- 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付
在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...
- JAVA微信扫码支付模式二功能实现完整例子
概述 本例子实现微信扫码支付模式二的支付功能,应用场景是,web网站微信扫码支付.实现从点击付费按钮.到弹出二维码.到用户用手机微信扫码支付.到手机上用户付费成功.web网页再自动调整到支付成功后的页 ...
- ASP.NET Core Web 支付功能接入 微信-扫码支付篇(转)
原文 https://www.cnblogs.com/essenroc/p/8630730.html // 随着版本更迭,新版本可能无法完全适用,请参考仓库内的示例. 这篇文章将介绍ASP.NET C ...
随机推荐
- leetcode198
public class Solution { public int Rob(int[] nums) { ; ; ; k < nums.Length; k++) { int tmp = i; i ...
- error: ‘kEmptyString’ is not a member of ‘google::protobuf::internal’
最近安装caffe,突然报这个错: .build_release/src/caffe/proto/caffe.pb.h: In member function ‘void caffe::ImageDa ...
- CentOS内网机器利用iptables共享公网IP上网
公司有个业务是2B的以及日活不大,所以两台服务器搞定,一个6M EIP.两台机器都是CentOS7系统EIP为 xxx.xxx.xxx.xxx绑在 内网ip为 172.18.30.175的服务器上,内 ...
- 简单定时器的Java实现
这两个类使用起来非常方便,可以完成我们对定时器的绝大多数需求 Timer类是用来执行任务的类,它接受一个TimerTask做参数 Timer有两种执行任务的模式,最常用的是schedule,它可以以两 ...
- Java的学习05
今天学习了,Java中的LinkedList类.这个类需要用到链表的知识,以前一直以为,只有c/c++有链表.今天才知道,原来其他语言.也有链表,而且还是双向链表. /** * 自定义一个链表 * @ ...
- python的执行过程
1,解释器找到代码文件 2,将代码字符串按照文件头或者解释器默认的编码格式加载待内存,转为unicode格式 3,将代码字符串按照语法规则解释 4,转为二进制语言 5,进行执行
- pytorch入门之安装和配置
pytorch是一种python接口的深度学习框架,其他的框架还有caffe,tensorflow等等. 1,pytorch目前支持linux和OSX两种系统.支持的Python版本有2.7,3.5, ...
- AI大道理头尾标识
标题 点击上方“AI大道理”,选择“置顶”公众号 重磅干货,深入讲解AI大道理 —————— 正文 —————— 浅谈则止,深入理解AI大道理 扫描下方“AI大道理”,选择“关注”公众号 欢迎加入!
- 100-days: twelve
Title: Mark Zuckerberg wants Facebook's to emulate China's WeChat, but can it? emulate v.效仿,模仿 As ...
- react组件回顶部
在挂载更新里面判断滚动条的距离(滚动条不能overflow: auto 踩坑) componentDidMount(){ window.addEventListener('scroll' , ()=& ...