一、微信第三方登录
通过微信打开链接:http://www.hzm.com/Entry/Login
微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:
  . 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;   . 通过code参数加上AppID和AppSecret等,通过API换取access_token;   . 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。
.控制器中代码
public ActionResult Login()
{
//若已经登录,直接跳到首页
if (HttpContext.User.Identity.IsAuthenticated)
{
return RedirectToAction("Index", "Entry");
}
//微信登录
//1.获取code
if (string.IsNullOrEmpty(Request.QueryString["code"]))
{
//从定向到微信,微信再重定向到当前函数(进入第1步获取code)
return RedirectToWeixin();
}
//2.获取openID
//通过code获取openID
string openID = "";
try
{
openID = GetOpenID(Request.QueryString["code"]);
}
catch(Exception e)
{
Log.Debug("GetOpenID Exception", e.StackTrace);
return Redirect("/Entry/Login");
}
//3.查找或存储用户信息
User user = new User();
user = db.Users.SingleOrDefault(p => p.OpenID == openID);
if (user == null)
{
//添加用户
user = new User();
user.OpenID = openID;
db.Users.Add(user);
db.SaveChanges();
}
//登录成功
FormsAuthentication.SetAuthCookie(user.ID.ToString(), false);//记录登录凭证
return RedirectToAction("Index", "Entry");
}
1.1.获取code
private ActionResult RedirectToWeixin()
{
JsApiPay jsApiPay = new JsApiPay(this);
var redirect_url = jsApiPay.GetRedirectToWeixinUrlForCode();//将回调stata参数值设为awardUserID
return Redirect(redirect_url);//调回:/Entry/Login
}
1.2.通过code获取openID和access_token
private string GetOpenID(string code)
{
JsApiPay jsApiPay = new JsApiPay(this);
//如果code有值
if (!string.IsNullOrEmpty(code))
{
Log.Debug(" GetOpenID code", code);
//去获取OpenID
jsApiPay.GetOpenidAndAccessTokenFromCode(code);
}
Log.Debug("GetOpenidAndAccessTokenFromCode openid", jsApiPay.openid.ToString());
return jsApiPay.openid.ToString();
}
二、微信支付
2.1.生成业务订单和微信交易号Out_trade_no
public ActionResult CreateOrder(int entryID, PayMode payMode)
{
//一个报名只应对应一个订单
//判断订单是否已经存在,则直接进入详情页
if (db.Orders.Any(p => p.EntryID == entryID))
{
return Redirect("/Entry/Detail?out_trade_no=" + db.Orders.SingleOrDefault(p => p.EntryID == entryID).Out_trade_no);
}
Entry entry = db.Entrys.Include("Event").SingleOrDefault(p => p.ID == entryID);
Order order = new Order();
order.EntryID = entry.ID;
order.Amount = GetDiscount(entry.Event);
order.PayMode = payMode;
order.State = OrderSatet.Unpaid;
order.SubmitTime = DateTime.Now;
order.Body = entry.Event.Theme;
order.Out_trade_no = WxPayApi.GenerateOutTradeNo();
db.Orders.Add(order);
db.SaveChanges();
if (payMode == PayMode.Remittance)
{
return RedirectToAction("Detail", new { out_trade_no = order.Out_trade_no });
}
return RedirectToAction("Pay", new { orderID = order.ID });
}
2.2.微信支付
public ActionResult Pay(int orderID)
{
//获取订单
Order order = db.Orders.SingleOrDefault(p => p.ID == orderID); //修改支付方式
order.PayMode = PayMode.Weixin;
db.SaveChanges(); //微信openID
Entry entry = db.Entrys.Include("Event").SingleOrDefault(p => p.ID == order.EntryID);
User user = db.Users.SingleOrDefault(p => p.ID == entry.UserID);
Log.Debug("openID", user.OpenID);
Log.Debug("entry.UserID", entry.UserID.ToString());
Log.Debug("HttpContext.User.Identity.Name", HttpContext.User.Identity.Name);
//当前订单的商户系统的订单号
ViewData["out_trade_no"] = order.Out_trade_no;
//支付费用
decimal totalFee = GetDiscount(entry.Event);
Log.Debug("totalFee", "100.00");
JsApiPay jsApiPay = new JsApiPay(this);
try
{
//若传递了相关参数,则调统一下单接口,获得后续相关接口的入口参数
jsApiPay.openid = user.OpenID; jsApiPay.total_fee = Convert.ToInt32(totalFee * );//支持两位小数,如0.01
Log.Debug(this.GetType().ToString(), "参数赋值成功1");
//JSAPI支付预处理
Log.Debug(this.GetType().ToString(), "参数赋值成功2");
WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult(entry.Name + "的" + entry.Event.Theme, "报名", order.Out_trade_no); Log.Debug(this.GetType().ToString(), "预支付订单生成成功");
//获取H5调起JS API参数
var wxJsApiParam = jsApiPay.GetJsApiParameters();
ViewData["wxJsApiParam"] = wxJsApiParam; Log.Debug(this.GetType().ToString(), "wxJsApiParam参数获取成功");
//预支付订单号
var prepay_id = jsApiPay.unifiedOrderResult.GetValue("prepay_id").ToString();
ViewData["prepay_id"] = prepay_id;
Log.Debug(this.GetType().ToString(), "prepay_id参数获取成功");
/*###################################*/
Log.Debug(this.GetType().ToString(), "wxJsApiParam : " + wxJsApiParam);
}
catch (Exception ex)
{
Response.Write("<span style='color:#FF0000;font-size:20px'>" + "下单失败,请返回重试" + "</span>");
Log.Debug("Award-ConfirmPayPage", ex.Message + ex.StackTrace);
Log.Debug("Award-ConfirmPayPage", "预支付订单生成或保存异常");
} return View(); }
2.3.页面中调起微信支付接口(Pay.html)
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>支付页面</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<script type="text/javascript">
var wxJsApiParam=@Html.Raw(ViewData["wxJsApiParam"].ToString());
//调用微信JS api 支付 function jsApiCall() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
wxJsApiParam,
function (res)
{
WeixinJSBridge.log(res.err_msg); //alert(res.err_code + res.err_desc + res.err_msg); if(res.err_msg=="get_brand_wcpay_request:ok"){
location.href ="/Entry/Detail?out_trade_no=@ViewData["out_trade_no"]";
}else
{
location.href ="/Entry/Detail?out_trade_no=@ViewData["out_trade_no"]";
} //alert(res.err_msg);
}
);
} function callpay()
{
if (typeof WeixinJSBridge == "undefined")
{
if (document.addEventListener)
{
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
}
else if (document.attachEvent)
{
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
}
else
{
jsApiCall();
}
}
callpay();
</script>
</head>
<body>
</body>
</html>
2.4.支付成功后微信发送支付成功异步通知(post方式,通知地址在Config.cs中配置的NOTIFY_URL,在这里添加订单处理业务逻辑)
public ActionResult Notify()
{
ResultNotify notify = new ResultNotify(this);
WxPayData data = notify.GetNotifyData();
Log.Debug("return_code", data.GetValue("return_code").ToString());
Log.Debug("return_msg", data.GetValue("return_code").ToString());
if (data.GetValue("return_code").ToString() == "SUCCESS")
{
Log.Debug("out_trade_no", data.GetValue("out_trade_no").ToString());
var out_trade_no = data.GetValue("out_trade_no").ToString(); Order order = db.Orders.SingleOrDefault(p => p.Out_trade_no == out_trade_no);
Log.Debug("orderID", order.ID.ToString()); order.State = OrderSatet.Paid;
var time_end = data.GetValue("time_end").ToString();
order.PayTime = DateTime.ParseExact(time_end, "yyyyMMddHHmmss", CultureInfo.CurrentCulture);
order.TransactionID = data.GetValue("transaction_id").ToString();
order.OpenID = data.GetValue("openid").ToString();
db.SaveChanges(); }
notify.ProcessNotify(); return View();
}
2.5.支付成功后跳转到(Pay.html页面设置的地址)
如:location.href ="/Entry/Detail?out_trade_no=@ViewData["out_trade_no"]";
微信支付官方文档地址:
1.App微信支付:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3

.net mvc 微信支付的更多相关文章

  1. 【原创分享·微信支付】C# MVC 微信支付教程系列之现金红包

            微信支付教程系列之现金红包           最近最弄这个微信支付的功能,然后扫码.公众号支付,这些都做了,闲着无聊,就看了看微信支付的其他功能,发现还有一个叫“现金红包”的玩意,想 ...

  2. 【原创分享·微信支付】 C# MVC 微信支付教程系列之扫码支付

    微信支付教程系列之扫码支付                  今天,我们来一起探讨一下这个微信扫码支付.何为扫码支付呢?这里面,扫的码就是二维码了,就是我们经常扫一扫的那种二维码图片,例如,我们自己添 ...

  3. 【原创分享·微信支付】 C# MVC 微信支付教程系列之公众号支付

    微信支付教程系列之公众号支付         今天,我们接着讲微信支付的系列教程,前面,我们讲了这个微信红包和扫码支付.现在,我们讲讲这个公众号支付.公众号支付的应用环境常见的用户通过公众号,然后再通 ...

  4. 【原创分享·微信支付】C# MVC 微信支付之微信模板消息推送

    微信支付之微信模板消息推送                    今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐.原因在哪?就是因为它是依赖微信生存的呀,所以他能不 ...

  5. C# MVC 微信支付教程系列之公众号支付

    微信支付教程系列之公众号支付           今天,我们接着讲微信支付的系列教程,前面,我们讲了这个微信红包和扫码支付.现在,我们讲讲这个公众号支付.公众号支付的应用环境常见的用户通过公众号,然后 ...

  6. 【分享·微信支付】 C# MVC 微信支付教程系列之公众号支付

    微信支付教程系列之公众号支付           今天,我们接着讲微信支付的系列教程,前面,我们讲了这个微信红包和扫码支付.现在,我们讲讲这个公众号支付.公众号支付的应用环境常见的用户通过公众号,然后 ...

  7. C# MVC 微信支付之微信模板消息推送

    微信支付之微信模板消息推送                    今天我要跟大家分享的是"模板消息"的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐.原因在哪?就是因为它是依赖微信 ...

  8. MVC 微信支付

    微信支付方式有好几种,俺研究了跟自己需要的两种,即:JS API网页支付和Native原生支付,这两个名词实在是有目的难懂.JS API网页支付:我的理解是在微信浏览器里面可以调用微信支付控件的支付方 ...

  9. asp.net mvc 微信支付代码分析(根据沐雪微信平台3.1商城业务来分析)

    开发微信应用,微信支付是永远要面对的.现在的微信支付相对以往已经很稳定,很少出现诡异情况.再加上无数人开发的经验分享,现在开发微信支付已经没什么难度了. 我这次主要是想基于沐雪微信平台的微商城业务来分 ...

随机推荐

  1. HTML 全局属性_02

    New : HTML5 新属性. 属性 描述 accesskey 设置访问元素的键盘快捷键. class 规定元素的类名(classname) contenteditableNew 规定是否可编辑元素 ...

  2. [家里蹲大学数学杂志]第235期$L^p$ 调和函数恒为零

    设 $u$ 是 $\bbR^n$ 上的调和函数, 且 $$\bex \sen{u}_{L^p}=\sex{\int_{\bbR^n}|u(y)|^p\rd y}^{1/p}<\infty. \e ...

  3. Spring AOP 完成日志记录

    Spring AOP 完成日志记录 http://hotstrong.iteye.com/blog/1330046

  4. yum 部署nginx

    第一步,在/etc/yum.repos.d/目录下创建一个源配置文件nginx.repo: cd /etc/yum.repos.d/ vim nginx.repo   填写如下内容:   [nginx ...

  5. oracle10g在rh6上安装缺少libXtst*的包导致不能出OUI

    由于测试需要,今天在linux6.0上装了下oracle10g,确实是知道oracle10g已经不支持redhat5.0以后的版本了,但是根据自己以往在redhat5.0上装oracle的经验就鲁莽下 ...

  6. Arch命令行与安装包

    >>mkfs.vfat                                                                     # pacman -S do ...

  7. Android插件化开发

    客户端开发给人的印象往往是小巧,快速奔跑.但随着产品的发展,目前产生了大量的门户型客户端.功能模块持续集成,开发人员迅速增长.不同的开发小组开发不同的功能模块,甚至还有其他客户端集成进入.能做到功能模 ...

  8. 自动化脚本过程中出现This element neither has attached source nor attached Javadoc...的解决方法

    This element neither has attached source nor attached Javadoc and hence no Javadoc could be found Ec ...

  9. dll 导出函数名的那些事

    dll 导出函数名的那些事 关键字: VC++  DLL  导出函数 经常使用VC6的Dependency或者是Depends工具查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导 ...

  10. 【转】用Python实现各种排序算法

    以下代码均为python3版本的代码 # 冒泡排序 # 比较相邻的元素大小,将小的前移,大的后移,就像水中的气泡一样,最小的元素经过几次移动,会最终浮到水面上. def bubbleSort(list ...