项目需求:学校学生网上缴费项目,刚来公司实习网上百度了各种资料,感谢很多大神避免了很多大坑。

本次扫码支付为:电脑生成二维码,手机微信扫码进行付款。建议开发前下载官方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">&nbsp;</div> <div>订单编号:<p id="tradeno"></p></div>
<div>考试费用:<p id="paymoney"></p></div>
<div id="QRCode">
</div> </div> <div class="space_hx">&nbsp;</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微信扫码支付的更多相关文章

  1. MVC 微信扫码支付

    微信扫码支付有两种模式, 模式一和模式二, 两者具体的区别可参考官网文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4 微 ...

  2. Net MVC微信扫码支付

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

  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. python学习笔记_week28

    heap import heapq import random heap = [] data = list(range(10000)) random.shuffle(data) # for num i ...

  2. linux上用route添加/删除路由

    1. 查看 route -n 2. 添加 route add -net 9.123.0.0 netmask 255.255.0.0 gw 9.123.0.1 3. 删除 route del -net ...

  3. 1 CRM

    一.crm介绍 CRM,客户关系管理系统(Customer Relationship Management).企业用CRM技术来管理与客户之间的关系,以求提升企业成功的管理方式,其目的是协助企业管理销 ...

  4. ExecutorService——shutdown方法和awaitTermination方法

    ExecutorService的关闭shutdown和awaitTermination为接口ExecutorService定义的两个方法,一般情况配合使用来关闭线程池. 方法简介shutdown方法: ...

  5. Spark 基础之SQL 快速上手

    知识点 SQL 基本概念 SQL Context 的生成和使用 1.6 版本新API:Datasets 常用 Spark SQL 数学和统计函数 SQL 语句 Spark DataFrame 文件保存 ...

  6. 深入浅出PF 学习笔记---TypeConverter

    StringToHumanTypeConverter类(从TypeConverter继承 using System; using System.Collections.Generic; using S ...

  7. 关于EL表达式随笔记录

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  8. Python人工智能之路 - 第三篇 : PyAudio 实现录音 自动化交互实现问答

    Python 很强大其原因就是因为它庞大的三方库 , 资源是非常的丰富 , 当然也不会缺少关于音频的库 关于音频, PyAudio 这个库, 可以实现开启麦克风录音, 可以播放音频文件等等,此刻我们不 ...

  9. 10.13 新版本go on~

    上午1.5 终审 and 排期 合同管理那边又是切换选项时各种联动,我第一想法是 好麻烦,不想做这个...第二想法才是给我做吧 锻炼锻炼我 然后 分任务的时候 分给我了,,哈哈 开心 虽然我没想躲 但 ...

  10. 2017-2018-2 20165315 实验四《Android程序设计》实验报告

    2017-2018-2 20165315 实验四<Android程序设计>实验报告 第24章:初识Android Android Studio项目的目录树 1 build:该目录包含了自动 ...