微信支付(.NET版)
前段时间做了网页版微信支付,遇到很多问题,不过最终还是解决了,现在在这里记录下开发流程以及说明,给其他人一些参考。
一、准备工作






//判断是否网页授权,获取授权code,没有代表没有授权,构造网页授权获取code,并重新请求
if (string.IsNullOrEmpty(Request.QueryString["code"]))
{
string redirectUrl = _weChatPaySerivce.GetAuthorizeUrl(account.AppId, account.RedquestUrl,
"STATE" + "#wechat_redirect", "snsapi_base");
return Redirect(redirectUrl);
}
public string GetAuthorizeUrl(string appId, string redirectUrl, string state, string scope)
{
string url = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state={3}",
appId, HttpUtility.UrlEncode(redirectUrl), scope, state);
/* 这一步发送之后,客户会得到授权页面,无论同意或拒绝,都会返回redirectUrl页面。
* 如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。这里的code用于换取access_token(和通用接口的access_token不通用)
* 若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE
*/
AppLog.Write("获取到授权url:", AppLog.LogMessageType.Debug);
return url;
}
public Tuple<string, string> GetOpenidAndAccessTokenFromCode(string appId, string code, string appSecret)
{
Tuple<string, string> tuple = null;
try
{
string url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appId, appSecret, code);
string result = WeChatPayHelper.Get(url);
AppLog.Write("微信支付-获取openid和access_token 请求Url:" + url + "result:" + result, AppLog.LogMessageType.Debug);
if (!string.IsNullOrEmpty(result))
{
var jd=Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(result);
tuple = new Tuple<string, string>(jd["openid"],jd["access_token"]);
AppLog.Write("微信支付-获取openid和access_token成功", AppLog.LogMessageType.Debug);
}
}
catch (Exception ex)
{
AppLog.Write("微信支付:获取openid和access_tokenu异常", AppLog.LogMessageType.Debug,ex);
}
return tuple;
}
//创建支付应答对象
RequestHandler packageReqHandler = new RequestHandler(null);
//初始化
packageReqHandler.Init();
//时间戳
string timeStamp = TenPayUtil.GetTimestamp();
//随机字符串
string nonceStr = TenPayUtil.GetNoncestr();
//设置package订单参数 生成prepayId预支付Id
packageReqHandler.SetParameter("appid", account.AppId); //公众账号ID
packageReqHandler.SetParameter("mch_id", account.PartnertId); //商户号
packageReqHandler.SetParameter("nonce_str", nonceStr); //随机字符串
packageReqHandler.SetParameter("body", account.Body);
packageReqHandler.SetParameter("out_trade_no", account.OrderSerialId); //商家订单号
packageReqHandler.SetParameter("total_fee", account.TotalAmount); //商品金额,以分为单位(money * 100).ToString()
packageReqHandler.SetParameter("spbill_create_ip", account.RequestIp); //用户的公网ip,不是商户服务器IP
packageReqHandler.SetParameter("notify_url", account.NotifyUrl); //接收财付通通知的URL
packageReqHandler.SetParameter("trade_type", "JSAPI"); //交易类型
packageReqHandler.SetParameter("openid", account.OpenId); //用户的openId
string sign = packageReqHandler.CreateMd5Sign("key", account.PaySignKey);
packageReqHandler.SetParameter("sign", sign); //签名
string prepayId = string.Empty;
try
{
string data = packageReqHandler.ParseXML();
var result = TenPayV3.Unifiedorder(data);
MailHelp.SendMail("调用统一下单接口,下单结果:--"+result+"请求参数:"+data);
var res = XDocument.Parse(result);
prepayId = res.Element("xml").Element("prepay_id").Value;
AppLog.Write("调用统一下单接口获取预支付prepayId成功", AppLog.LogMessageType.Debug);
}
catch (Exception ex)
{
AppLog.Write("获取到openid和access_tokenu异常", AppLog.LogMessageType.Debug, ex);
MailHelp.SendMail("调用统一下单接口获取预支付prepayid异常:", ex);
return null;
}
//生成JsAPI支付参数
RequestHandler paySignReqHandler = new RequestHandler(null);
paySignReqHandler.SetParameter("appId", account.AppId);
paySignReqHandler.SetParameter("timeStamp", timeStamp);
paySignReqHandler.SetParameter("nonceStr", nonceStr);
paySignReqHandler.SetParameter("package", string.Format("prepay_id={0}", prepayId));
paySignReqHandler.SetParameter("signType", "MD5");
string paySign = paySignReqHandler.CreateMd5Sign("key", account.PaySignKey);
WeChatJsPayRequestModel resultModel = new WeChatJsPayRequestModel
{
AppId = account.AppId,
NonceStr = nonceStr,
TimeStamp = timeStamp,
Package = string.Format("prepay_id={0}", prepayId),
PaySign = paySign,
SignType = "MD5"
};
private string CreateWeixinJs(WeChatJsPayRequestModel model)
{
string js = @"<script type='text/javascript'>
callpay();
function jsApiCall(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
requestParam
},
function (res) {
if(res.err_msg == 'get_brand_wcpay_request:ok' ){
window.location.href = 'successUrl';
}else{
window.location.href = 'failUrl';
}
}
);
}
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();
}
}
</script>";
string requestParam = string.Format(@"'appId': '{0}','timeStamp': '{1}','nonceStr': '{2}','package': '{3}','signType': '{4}','paySign': '{5}'",
model.AppId, model.TimeStamp, model.NonceStr, model.Package, model.SignType, model.PaySign);
js = js.Replace("requestParam", requestParam)
.Replace("successUrl", model.JumpUrl + "&result=1")
.Replace("failUrl", model.JumpUrl + "&result=0");
AppLog.Write("生成可执行脚本成功", AppLog.LogMessageType.Debug);
return js;
}
ResponseHandler resHandler = new ResponseHandler(System.Web.HttpContext.Current);
bool isSuccess = _weChatPaySerivce.ProcessNotify(resHandler);
if (isSuccess)
{
string result = @"<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[支付成功]]></return_msg>
</xml>";
HttpContext.Response.Write(result);
HttpContext.Response.End();
}
return new EmptyResult();

微信支付(.NET版)的更多相关文章
- 微信支付java版V3验证数据合法性
[TOC] 1. 微信支付java版V3验证数据合法性 概要:使用微信支付接口时,微信会返回或回调给商户XML数据,开发者需要验证微信返回的数据是否合法. 特别提醒:商户系统对于支付结果通知的内容一定 ...
- 微信支付.NET版开发总结(JS API),好多坑,适当精简
前2天,做一个手机网页的微信支付的项目,费了好些周折,记录一下.接下来,按照开发步骤,细数一下,我遇到的那些坑. [坑1]官方邮件中下载的demo只有PHP版本,其他版本没有给链接.可能让人误以为只有 ...
- 微信支付.NET版开发总结(JS API),好多坑,适当精简。
前2天,做一个手机网页的微信支付的项目,费了好些周折,记录一下.接下来,按照开发步骤,细数一下,我遇到的那些坑. [坑1]官方邮件中下载的demo只有PHP版本,其他版本没有给链接.可能让人误以为只有 ...
- Android微信支付V3版
由于公司需求做微信APP支付,在集成过程中也遇到各种问题,比如说签名错误,body编码必须为UTF-8.APP端无法调用支付页面直接到支付结果页面.结果为null,code=-1等等: 1.签名错误问 ...
- 微信支付 python版
需求: 微信打开商品列表页面-> 点击商品后直接显示付款页面-> 点击付款调用微信支付 说明 微信支付需要你申请了公众号(appid, key - 用于签名), 商户号(mch_id, A ...
- jsapi微信支付v3版
请看清楚你的微信支付是v2还是v3.在这里整理的是v3的,v2的同学请忽略! 前期准备须要用的是商户证书,用的是p12的.设置api密钥(在微信商户端中设置),还须要在微信公众号中设置jsapi授权文 ...
- 微信支付 V3版
本人小菜鸟一仅仅.为了自我学习和交流PHP(jquery,linux,lamp,shell,javascript,server)等一系列的知识,小菜鸟创建了一个群.希望光临本博客的人能够进来交流. 寻 ...
- 到处都是坑的微信支付V3
业务需要一个在微信上能付款的功能,于是乎想到了最普遍的支付宝,坑爹的是T与A是水火不容啊,默默的还是接微信支付吧,没想到从此掉进了连环坑…… 网上写微信支付接口的还是很多,PHP官方有(鄙视源码作者, ...
- ecshop微信支付(0923更新)商户支付密钥key的生成与设置
ECSHOP 微信支付(0923更新)商户支付密钥key的生成与设置 说明:新版微信支付,用户必须授权登录才能支付.需要商家自己设置商户号支付密钥. 申请微信支付手机版部分时需要填写的配置接口地址: ...
- 微信支付v3接口的 官方 Java SDK
啰嗦几句:微信支付v3版接口麻烦吗?在对接微信支付v3接口时,本来是一件很简单的事情,其实微信支付v3接口并不是很复杂,但是微信团队的管理很混乱,给我们开发者带来了巨大的麻烦. 微信支付v3版接口对接 ...
随机推荐
- Node基础篇(文件操作)
文件操作 相关模块 Node内核提供了很多与文件操作相关的模块,每个模块都提供了一些最基本的操作API,在NPM中也有社区提供的功能包 fs: 基础的文件操作 API path: 提供和路径相关的操作 ...
- Nginx反向代理部署指南
一.反向代理 我们都知道,80端口是web服务的默认端口,其他主机访问web服务器也是默认和80端口进行web交互,而一台服务器也只有一个80端口,这是约定俗成的标准. 我们来看下面两个场景: 1.服 ...
- apache.commons.io.IOUtils: 一个很方便的IO工具库(比如InputStream转String)
转换InputStream到String, 比如 //引入apache的io包 import org.apache.commons.io.IOUtils; ... ...String str = IO ...
- CentOS6.7搭建LNMP环境
1:查看环境: [root@localhost ~]# cat /etc/redhat-release 2:关掉防火墙 #重启后生效开启 [root@localhost ~]# chkconfig i ...
- 初识Servlet
1.创建DispatcherServlet package myservlet; import java.io.IOException; import javax.servlet.ServletExc ...
- js url.slice(star,end) url.lastIndexOf('/') + 1, -4
var url = '"http://60.195.252.25:15518/20151228/XXSX/作三角形的高.mp4")' document.title = url.sl ...
- 【H5疑难杂症】脱离文档流时的渲染BUG
BUG重现 最近机票团队在一个页面布局复杂的地方发现一个BUG,非常奇怪并且不好定位,这类问题一般最后都会到我这里,这个问题是,改变dom结构,页面却不渲染!!! 如图所示,我动态的改变了dom结构, ...
- 写给自己:修改配置文件一定要cp一个.bak
写给自己:修改配置文件一定要cp一个.bak 毕竟不是每次的修改都一定对,而且很多时候是在服务器上直接修改原文件,修改后重启服务才知道是否修改正确,如果不加备份修改,造成服务器动荡,将会造成不可挽回的 ...
- bitnami redmine版本由2.3.1升级至3.2.2过程
环境: 操作系统为ubuntu13.**版本,非长期支持版. 安装目录:/opt/redmine-2.3.1-0/ 所有者用户:root 安装过程: 1. 备份2.3.1数据库 sudo /opt/r ...
- MP3文件ID3信息编辑器代码开源 - 开源研究系列文章
上次把磁性窗体的源码开源了,这次就开源另一个程序源码:MP3文件ID3信息编辑器.这个源码也比较简单,关键在于获取和写入MP3文件的这个ID3的信息即可. 这个操作信息编辑的就封装在MP3ID3.ba ...