千家信息网

.NET如何实现微信公众号开发之5.0微信支付功能

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要为大家展示了".NET如何实现微信公众号开发之5.0微信支付功能",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下".NET如何实现微信公众号开发之
千家信息网最后更新 2026年11月04日.NET如何实现微信公众号开发之5.0微信支付功能

这篇文章主要为大家展示了".NET如何实现微信公众号开发之5.0微信支付功能",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下".NET如何实现微信公众号开发之5.0微信支付功能"这篇文章吧。

一.前言

在开始做这个功能之前,我们要做的第一件事情就是思考,如何做这个微信支付,从哪里开始,从哪里入手,官方的sdk说明什么的,有没有什么官方的demo,还有就是老板给我的一些资料齐全不,那些要申请的接 口什么的都有没有。

二.开发前准备。

1.0微信支付官方开发者文档

2.0官方demo下载 我们用c#所以选择.net版本 不过这个官方的demo根本跑步起来

3.0官方demo运行起来解决方案

4.0微信支付官方.net版之坑你没商量

5.0开发前的微信公众平台的一些配置,请务必认真检查配置.

三.编码

做好了这些准备工作之后,我们知道微信支付有两种,1.原生态的,2.jsapi直接调用的,我项目中用到的是第二种

经过自己的一些业务逻辑处理,来到了我们的订单详情页面,现在需要去点击我们的支付按钮去支付,支付页面pay.aspx代码如下,

前台页面:

    




  您确认付款元...

需要注意的是:

微信JS API只能在微信内置浏览器中使用,其他浏览器调用无效。微信提供getBrandWCPayRequest接口供商户前端网页调用,调用之前微信会鉴定商户支付权限,若商户具有调起支付的权限,则将开始支付流程。 这里主要介绍支付前的接口调用规则,支付状态消息通知机制请参加下文。接口需要注意:所有传入参数都是字符串类型!

getBrandWCPayRequest参数如表6-5所示。

参数

名称

必填

格式

说明

appId

公众号id

是

字符串类型

商户注册具有支付权限的公众号成功后即可获得;

timeStamp

时间戳

是

字符串类型,32个字节以下

商户生成,从1970年1月1日00:00:00至今的秒数,即当前的时间,且最终需要转换为字符串形式;

nonceStr

随机字符串

是

字符串类型,32个字节以下

商户生成的随机字符串;

package

订单详情扩展字符串

是

字符串类型,4096个字节以下

商户将订单信息组成该字符串,具体组成方案参见接口使用说明中package组包帮劣;由商户按照规范拼接后传入;

signType

签名方式

是

字符串类型,参数取值"SHA1"

按照文档中所示填入,目前仅支持SHA1;

paySign

签名

是

字符串类型

商户将接口列表中的参数按照指定方式迚行签名,签名方式使用signType中标示的签名方式,具体签名方案参见接口使用说明中签名帮劣;由商户按照规范签名后传入;

表6-5 getBrandWCPayRequest参数

getBrandWCPayRequest返回值如表6-6所示。

返回值

说明

err_msg

get_brand_wcpay_request:ok 支付成功
get_brand_wcpay_request:cancel 支付过程中用户取消
get_brand_wcpay_request:fail 支付失败

表6-6 getBrandWCPayRequest返回值

JS API的返回结果 get_brand_wcpay_request:ok 仅在用户成功完成支付时返回。由于前端交互复杂,get_brand_wcpay_request:cancel 或者 get_brand_wcpay_request:fail 可以统一处理为用户遇到错误或者 主动放弃,不必细化区分。

pay.aspx后台页面代码:

               wxJsApiParam { ; ; }           Money { ;   OrderId { ;   orderMoneySum { ; ; }          orderProductName { ; ; }          Page_Load( (!=  JsApiPay( total_fee = Request[                        orderMoneySum = ParkName = Request[= ParkName+= Request[ (.IsNullOrWhiteSpace(total_fee)||total_fee==  WxPayException( +  + =.Parse((Convert.ToDouble(total_fee)*= (Convert.ToDouble(jsApiPay.total_fee)/=                         (Common.OpenId ==   WxPayException(=== jsApiPay.GetJsApiParameters(); +  + ex.InnerException.Message +  +  + ex.Message +

在这里需要我们注意的是:jsApiPay.openid = common.GetOpenId();

在支付的时候,我们需要首先获取用户的openId,然而获取用户openId的这个过程我们首先要进行Oauth3认证,在官方的demo中提供了JsApiPay.cs这个核心类库,里面已经有这个GetOpenidAndAccessToken()方法 。我这里是拿过来写成了自己的一个公共帮助类。Common.cs

    ///     /// 公共帮助类    ///     public class Common    {        private  HttpContext Context { get; set; }        public static string OpenId = "Openid";        public static string access_token = "access_token";        #region 构造函数        ///         /// 构造函数        ///         ///         public Common(HttpContext context)        {            this.Context = context;        }         #endregion        #region 通过code换取AccessToken        ///         /// 通过code换取AccessToken        ///         public  void GetOpenidAndAccessToken()        {            if (!string.IsNullOrEmpty(Context.Request.QueryString["code"]))            {                //获取code码,以获取openid和access_token                string code = Context.Request.QueryString["code"];                GetOpenidAndAccessTokenFromCode(code);            }            else            {                //构造网页授权获取code的URL                string host = Context.Request.Url.Host;                string path = Context.Request.Path;                string redirect_uri = HttpUtility.UrlEncode("http://" + host + path);                WxPayData data = new WxPayData();                data.SetValue("appid", WxPayConfig.APPID);                data.SetValue("redirect_uri", redirect_uri);                data.SetValue("response_type", "code");                data.SetValue("scope", "snsapi_base");                data.SetValue("state", "STATE" + "#wechat_redirect");                string url = "https://open.weixin.qq.com/connect/oauth3/authorize?" + data.ToUrl();                try                {                    //触发微信返回code码                             Context.Response.Redirect(url);//Redirect函数会抛出ThreadAbortException异常,不用处理这个异常                }                catch (System.Threading.ThreadAbortException ex)                {                }            }        }                #endregion        #region 通过用户授权获取AccessToken和OpenId        ///         /// 通过用户授权获取AccessToken和OpenId        ///         ///         public  void GetOpenidAndAccessTokenFromCode(string code)        {            try            {                //构造获取openid及access_token的url                WxPayData data = new WxPayData();                data.SetValue("appid", WxPayConfig.APPID);                data.SetValue("secret", WxPayConfig.APPSECRET);                data.SetValue("code", code);                data.SetValue("grant_type", "authorization_code");                string url = "https://api.weixin.qq.com/sns/oauth3/access_token?" + data.ToUrl();                //请求url以获取数据                string result = HttpService.Get(url);                //保存access_token,用于收货地址获取                JsonData jd = JsonMapper.ToObject(result);                access_token = (string)jd["access_token"];                //获取用户openid                OpenId = (string)jd["openid"];            }            catch (Exception ex)            {                throw new WxPayException(ex.ToString());            }        }         #endregion        #region 获取OpenId        ///         /// 获取OpenId        ///         ///         ///         public string GetOpenId()        {                Common common = new Common(Context);                common.GetOpenidAndAccessToken();                return OpenId;        }         #endregion    }

 public class JsApiPay    {        ///         /// 保存页面对象,因为要在类的方法中使用Page的Request对象        ///         private Page page {get;set;}        ///         /// openid用于调用统一下单接口        ///         public string openid { get; set; }        ///         /// access_token用于获取收货地址js函数入口参数        ///         public string access_token { get; set; }        ///         /// 商品金额,用于统一下单        ///         public int total_fee { get; set; }        ///         /// 订单Id        ///         public string orderid { get; set; }        ///         /// 统一下单接口返回结果        ///         public WxPayData unifiedOrderResult { get; set; }         public JsApiPay(Page page)        {            this.page = page;        }        /**        *         * 网页授权获取用户基本信息的全部过程        * 详情请参看网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html        * 第一步:利用url跳转获取code        * 第二步:利用code去获取openid和access_token        *         */        public void GetOpenidAndAccessToken()        {            if (!string.IsNullOrEmpty(page.Request.QueryString["code"]))            {                //获取code码,以获取openid和access_token                string code = page.Request.QueryString["code"];                //Log.Debug(this.GetType().ToString(), "Get code : " + code);                GetOpenidAndAccessTokenFromCode(code);            }            else            {                //构造网页授权获取code的URL                string host = page.Request.Url.Host;                //Log.Debug(this.GetType().ToString(), "host" + host);                string path = page.Request.Path;                string redirect_uri = HttpUtility.UrlEncode("http://" + host + path);                                WxPayData data = new WxPayData();                data.SetValue("appid", WxPayConfig.APPID);                data.SetValue("redirect_uri", redirect_uri);                data.SetValue("response_type", "code");                data.SetValue("scope", "snsapi_base");                data.SetValue("state", "STATE" + "#wechat_redirect");                string url = "https://open.weixin.qq.com/connect/oauth3/authorize?" + data.ToUrl();                Log.Debug(this.GetType().ToString(), "Will Redirect to URL : " + url);                try                {                    //触发微信返回code码                             page.Response.Redirect(url);//Redirect函数会抛出ThreadAbortException异常,不用处理这个异常                }                catch(System.Threading.ThreadAbortException ex)                {                }            }        }        /**        *         * 通过code换取网页授权access_token和openid的返回数据,正确时返回的JSON数据包如下:        * {        *  "access_token":"ACCESS_TOKEN",        *  "expires_in":7200,        *  "refresh_token":"REFRESH_TOKEN",        *  "openid":"OPENID",        *  "scope":"SCOPE",        *  "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"        * }        * 其中access_token可用于获取共享收货地址        * openid是微信支付jsapi支付接口统一下单时必须的参数        * 更详细的说明请参考网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html        * @失败时抛异常WxPayException        */        public void GetOpenidAndAccessTokenFromCode(string code)        {            try            {                //构造获取openid及access_token的url                WxPayData data = new WxPayData();                data.SetValue("appid", WxPayConfig.APPID);                data.SetValue("secret", WxPayConfig.APPSECRET);                data.SetValue("code", code);                data.SetValue("grant_type", "authorization_code");                string url = "https://api.weixin.qq.com/sns/oauth3/access_token?" + data.ToUrl();                //请求url以获取数据                string result = HttpService.Get(url);                //Log.Debug(this.GetType().ToString(), "GetOpenidAndAccessTokenFromCode response : " + result);                //保存access_token,用于收货地址获取                JsonData jd = JsonMapper.ToObject(result);                access_token = (string)jd["access_token"];                //获取用户openid                openid = (string)jd["openid"];                //Log.Debug(this.GetType().ToString(), "Get openid : " + openid);                //Log.Debug(this.GetType().ToString(), "Get access_token : " + access_token);            }            catch (Exception ex)            {                Log.Error(this.GetType().ToString(), ex.ToString());                throw new WxPayException(ex.ToString());            }        }        /**         * 调用统一下单,获得下单结果         * @return 统一下单结果         * @失败时抛异常WxPayException         */        public WxPayData GetUnifiedOrderResult()        {            //统一下单            WxPayData data = new WxPayData();            data.SetValue("body", "test");            //data.SetValue("attach", "test");            data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());            data.SetValue("total_fee", total_fee);            data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));            data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));            //data.SetValue("goods_tag", "test");            data.SetValue("trade_type", "JSAPI");            data.SetValue("openid", openid);            data.SetValue("orderid", orderid);            WxPayData result = WxPayApi.UnifiedOrder(data);            if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")            {                Log.Error(this.GetType().ToString(), "UnifiedOrder response error!");                throw new WxPayException("UnifiedOrder response error!");            }            unifiedOrderResult = result;            return result;        }        public WxPayData GetUnifiedOrderResult(string body)        {            //统一下单            WxPayData data = new WxPayData();            data.SetValue("body", body);            //data.SetValue("attach", "test");            data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());            data.SetValue("total_fee", total_fee);            //data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));            //data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));            //data.SetValue("goods_tag", "test");            data.SetValue("trade_type", "JSAPI");            data.SetValue("openid", openid);            WxPayData result = WxPayApi.UnifiedOrder(data);            if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")            {                Log.Error(this.GetType().ToString(), "UnifiedOrder response error!");                throw new WxPayException("UnifiedOrder response error!");            }            unifiedOrderResult = result;            return result;        }        /**        *          * 从统一下单成功返回的数据中获取微信浏览器调起jsapi支付所需的参数,        * 微信浏览器调起JSAPI时的输入参数格式如下:        * {        *   "appId" : "wx2421b1c4370ec43b",     //公众号名称,由商户传入             *   "timeStamp":" 1395712654",         //时间戳,自1970年以来的秒数             *   "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串             *   "package" : "prepay_id=u802345jgfjsdfgsdg888",             *   "signType" : "MD5",         //微信签名方式:            *   "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名         * }        * @return string 微信浏览器调起JSAPI时的输入参数,json格式可以直接做参数用        * 更详细的说明请参考网页端调起支付API:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7        *         */        public string GetJsApiParameters()        {            WxPayData jsApiParam = new WxPayData();            jsApiParam.SetValue("appId", unifiedOrderResult.GetValue("appid"));            jsApiParam.SetValue("timeStamp", WxPayApi.GenerateTimeStamp());            jsApiParam.SetValue("nonceStr", WxPayApi.GenerateNonceStr());            jsApiParam.SetValue("package", "prepay_id=" + unifiedOrderResult.GetValue("prepay_id"));            jsApiParam.SetValue("signType", "MD5");            jsApiParam.SetValue("paySign", jsApiParam.MakeSign());            string parameters = jsApiParam.ToJson();            return parameters;        }        /**        *         * 获取收货地址js函数入口参数,详情请参考收货地址共享接口:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_9        * @return string 共享收货地址js函数需要的参数,json格式可以直接做参数使用        */        public string GetEditAddressParameters()        {            string parameter = "";            try            {                string host = page.Request.Url.Host;                string path = page.Request.Path;                string queryString = page.Request.Url.Query;                //这个地方要注意,参与签名的是网页授权获取用户信息时微信后台回传的完整url                string url = "http://" + host + path + queryString;                //构造需要用SHA1算法加密的数据                WxPayData signData = new WxPayData();                signData.SetValue("appid",WxPayConfig.APPID);                signData.SetValue("url", url);                signData.SetValue("timestamp",WxPayApi.GenerateTimeStamp());                signData.SetValue("noncestr",WxPayApi.GenerateNonceStr());                signData.SetValue("accesstoken",access_token);                string param = signData.ToUrl();                Log.Debug(this.GetType().ToString(), "SHA1 encrypt param : " + param);                //SHA1加密                string addrSign = FormsAuthentication.HashPasswordForStoringInConfigFile(param, "SHA1");                Log.Debug(this.GetType().ToString(), "SHA1 encrypt result : " + addrSign);                //获取收货地址js函数入口参数                WxPayData afterData = new WxPayData();                afterData.SetValue("appId",WxPayConfig.APPID);                afterData.SetValue("scope","jsapi_address");                afterData.SetValue("signType","sha1");                afterData.SetValue("addrSign",addrSign);                afterData.SetValue("timeStamp",signData.GetValue("timestamp"));                afterData.SetValue("nonceStr",signData.GetValue("noncestr"));                //转为json格式                parameter = afterData.ToJson();                Log.Debug(this.GetType().ToString(), "Get EditAddressParam : " + parameter);            }            catch (Exception ex)            {                Log.Error(this.GetType().ToString(), ex.ToString());                throw new WxPayException(ex.ToString());            }            return parameter;        }    }

JsApiPay

微信支付协议接口数据类WxPayData.cs官方都有相应的代码.

 ///     /// 微信支付协议接口数据类,所有的API接口通信都依赖这个数据结构,    /// 在调用接口之前先填充各个字段的值,然后进行接口通信,    /// 这样设计的好处是可扩展性强,用户可随意对协议进行更改而不用重新设计数据结构,    /// 还可以随意组合出不同的协议数据包,不用为每个协议设计一个数据包结构    ///     public class WxPayData    {        public WxPayData()        {        }        //采用排序的Dictionary的好处是方便对数据包进行签名,不用再签名之前再做一次排序        private SortedDictionary m_values = new SortedDictionary();        /**        * 设置某个字段的值        * @param key 字段名         * @param value 字段值        */        public void SetValue(string key, object value)        {            m_values[key] = value;        }        /**        * 根据字段名获取某个字段的值        * @param key 字段名         * @return key对应的字段值        */        public object GetValue(string key)        {            object o = null;            m_values.TryGetValue(key, out o);            return o;        }        /**         * 判断某个字段是否已设置         * @param key 字段名         * @return 若字段key已被设置,则返回true,否则返回false         */        public bool IsSet(string key)        {            object o = null;            m_values.TryGetValue(key, out o);            if (null != o)                return true;            else                return false;        }        /**        * @将Dictionary转成xml        * @return 经转换得到的xml串        * @throws WxPayException        **/        public string ToXml()        {            //数据为空时不能转化为xml格式            if (0 == m_values.Count)            {                Log.Error(this.GetType().ToString(), "WxPayData数据为空!");                throw new WxPayException("WxPayData数据为空!");            }            string xml = "";            foreach (KeyValuePair pair in m_values)            {                //字段值不能为null,会影响后续流程                if (pair.Value == null)                {                    Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!");                    throw new WxPayException("WxPayData内部含有值为null的字段!");                }                if (pair.Value.GetType() == typeof(int))                {                    xml += "<" + pair.Key + ">" + pair.Value + "";                }                else if (pair.Value.GetType() == typeof(string))                {                    xml += "<" + pair.Key + ">" + "";                }                else//除了string和int类型不能含有其他数据类型                {                    Log.Error(this.GetType().ToString(), "WxPayData字段数据类型错误!");                    throw new WxPayException("WxPayData字段数据类型错误!");                }            }            xml += "";            return xml;        }        /**        * @将xml转为WxPayData对象并返回对象内部的数据        * @param string 待转换的xml串        * @return 经转换得到的Dictionary        * @throws WxPayException        */        public SortedDictionary FromXml(string xml)        {            if (string.IsNullOrEmpty(xml))            {                Log.Error(this.GetType().ToString(), "将空的xml串转换为WxPayData不合法!");                throw new WxPayException("将空的xml串转换为WxPayData不合法!");            }            XmlDocument xmlDoc = new XmlDocument();            xmlDoc.LoadXml(xml);            XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点            XmlNodeList nodes = xmlNode.ChildNodes;            foreach (XmlNode xn in nodes)            {                XmlElement xe = (XmlElement)xn;                m_values[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中            }                        try            {                //2015-06-29 错误是没有签名                if(m_values["return_code"] != "SUCCESS")                {                    return m_values;                }                CheckSign();//验证签名,不通过会抛异常            }            catch(WxPayException ex)            {                throw new WxPayException(ex.Message);            }            return m_values;        }        /**        * @Dictionary格式转化成url参数格式        * @ return url格式串, 该串不包含sign字段值        */        public string ToUrl()        {            string buff = "";            foreach (KeyValuePair pair in m_values)            {                if (pair.Value == null)                {                    Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!");                    throw new WxPayException("WxPayData内部含有值为null的字段!");                }                if (pair.Key != "sign" && pair.Value.ToString() != "")                {                    buff += pair.Key + "=" + pair.Value + "&";                }            }            buff = buff.Trim('&');            return buff;        }        /**        * @Dictionary格式化成Json         * @return json串数据        */        public string ToJson()        {            string jsonStr = JsonMapper.ToJson(m_values);            return jsonStr;        }        /**        * @values格式化成能在Web页面上显示的结果(因为web页面上不能直接输出xml格式的字符串)        */        public string ToPrintStr()        {            string str = "";            foreach (KeyValuePair pair in m_values)            {                if (pair.Value == null)                {                    Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!");                    throw new WxPayException("WxPayData内部含有值为null的字段!");                }                str += string.Format("{0}={1}
", pair.Key, pair.Value.ToString()); } Log.Debug(this.GetType().ToString(), "Print in Web Page : " + str); return str; } /** * @生成签名,详见签名生成算法 * @return 签名, sign字段不参加签名 */ public string MakeSign() { //转url格式 string str = ToUrl(); //在string后加入API KEY str += "&key=" + WxPayConfig.KEY; //MD5加密 var md5 = MD5.Create(); var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); var sb = new StringBuilder(); foreach (byte b in bs) { sb.Append(b.ToString("x2")); } //所有字符转为大写 return sb.ToString().ToUpper(); } /** * * 检测签名是否正确 * 正确返回true,错误抛异常 */ public bool CheckSign() { //如果没有设置签名,则跳过检测 if (!IsSet("sign")) { Log.Error(this.GetType().ToString(), "WxPayData签名存在但不合法!"); throw new WxPayException("WxPayData签名存在但不合法!"); } //如果设置了签名但是签名为空,则抛异常 else if(GetValue("sign") == null || GetValue("sign").ToString() == "") { Log.Error(this.GetType().ToString(), "WxPayData签名存在但不合法!"); throw new WxPayException("WxPayData签名存在但不合法!"); } //获取接收到的签名 string return_sign = GetValue("sign").ToString(); //在本地计算新的签名 string cal_sign = MakeSign(); if (cal_sign == return_sign) { return true; } Log.Error(this.GetType().ToString(), "WxPayData签名验证错误!"); throw new WxPayException("WxPayData签名验证错误!"); } /** * @获取Dictionary */ public SortedDictionary GetValues() { return m_values; } }

WxPayData

配置文件信息

    /**    *     配置账号信息    */    public class WxPayConfig    {        //=======【基本信息设置】=====================================        /* 微信公众号信息配置        * APPID:绑定支付的APPID(必须配置)        * MCHID:商户号(必须配置)        * KEY:商户支付密钥,参考开户邮件设置(必须配置)        * APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置)        */        public const string APPID = "wx14e3e56f3";        public const string MCHID = "12352";        public const string KEY = "BB6BE71D7CED49A79409C9";        public const string APPSECRET = "76eb33f66129692da1624f1";        //=======【证书路径设置】=====================================         /* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要)        */        public const string SSLCERT_PATH = "cert/apiclient_cert.p12";        public const string SSLCERT_PASSWORD = "123502";        //=======【支付结果通知url】=====================================         /* 支付结果通知回调url,用于商户接收支付结果        */        public const string NOTIFY_URL = "http://www.baidu.com/ResultPay.aspx";        //=======【商户系统后台机器IP】=====================================         /* 此参数可手动配置也可在程序中自动获取        */        public const string IP = "150.24.91.151";        //=======【代理服务器设置】===================================        /* 默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置)        */        public const string PROXY_URL = "http://10.152.18.220:8080";        //=======【上报信息配置】===================================        /* 测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报        */        public const int REPORT_LEVENL = 1;        //=======【日志级别】===================================        /* 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息        */        public const int LOG_LEVENL =3;    }

WxPayConfig

接着我们在看2行关键的代码:

                            WxPayData unifiedOrderResult == jsApiPay.GetJsApiParameters();

此时如果wxJsApiParam变量能够顺利拿到值,那么我们前台页面的:<%=wxJsApiParam%>z这里就可以获取到我们要传递的参数,这时候就可以调用微信支付的接口,打开我们的付款页面如图所示:

               //调用微信JS api 支付               function jsApiCall()               {                   WeixinJSBridge.invoke(                   'getBrandWCPayRequest',                   <%=wxJsApiParam%>,//josn串                    function (res)                    {                      if (res.err_msg == "get_brand_wcpay_request:ok")                       {                           var OrderId=$("#OrderId").val();                           var orderProductName=$("#orderProductName").val();                           var orderMoneySum=$("#orderMoneySum").val();                             _window.location.href="http://www.baodu.com/PaySkip.aspx?OrderId="+OrderId+"&orderMoneySum="+orderMoneySum+"&orderProductName="+orderProductName;                        }else                        {                          WeixinJSBridge.call('closeWindow');                        }                                              }                    );               }

(JsApiPay.cs)得到下单结果:

        public WxPayData GetUnifiedOrderResult(string body)        {            //统一下单            WxPayData data = new WxPayData();            data.SetValue("body", body);            data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());            data.SetValue("total_fee", total_fee);            data.SetValue("trade_type", "JSAPI");            data.SetValue("openid", openid);            WxPayData result = WxPayApi.UnifiedOrder(data);            if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")            {                Log.Error(this.GetType().ToString(), "UnifiedOrder response error!");                throw new WxPayException("UnifiedOrder response error!");            }            unifiedOrderResult = result;            return result;        }

(WxPayApi.cs)统一下单接口:

        /**        *         * 统一下单        * @param WxPaydata inputObj 提交给统一下单API的参数        * @param int timeOut 超时时间        * @throws WxPayException        * @return 成功时返回,其他抛异常        */        public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 6)        {            string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";            //检测必填参数            if (!inputObj.IsSet("out_trade_no"))            {                throw new WxPayException("缺少统一支付接口必填参数out_trade_no!");            }            else if (!inputObj.IsSet("body"))            {                throw new WxPayException("缺少统一支付接口必填参数body!");            }            else if (!inputObj.IsSet("total_fee"))            {                throw new WxPayException("缺少统一支付接口必填参数total_fee!");            }            else if (!inputObj.IsSet("trade_type"))            {                throw new WxPayException("缺少统一支付接口必填参数trade_type!");            }            //关联参数            if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))            {                throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");            }            if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))            {                throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");            }            //异步通知url未设置,则使用配置文件中的url            if (!inputObj.IsSet("notify_url"))            {                inputObj.SetValue("notify_url", WxPayConfig.NOTIFY_URL);//异步通知url            }            inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID            inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号            inputObj.SetValue("spbill_create_ip", WxPayConfig.IP);//终端ip                          inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串            //签名            inputObj.SetValue("sign", inputObj.MakeSign());            string xml = inputObj.ToXml();            var start = DateTime.Now;            string response = HttpService.Post(xml, url, false, timeOut);            var end = DateTime.Now;            int timeCost = (int)((end - start).TotalMilliseconds);            WxPayData result = new WxPayData();            result.FromXml(response);            ReportCostTime(url, timeCost, result);//测速上报            return result;        }
四.最终开发的效果

以上是".NET如何实现微信公众号开发之5.0微信支付功能"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

支付 参数 接口 字段 数据 统一 商户 字符 字符串 用户 信息 格式 配置 类型 公众 页面 官方 结果 网页 错误 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳市人人互联网科技有限公司 山东特亿宝互联网科技有限公司 A股互联网金融科技公司 互联网科技卖菜 北京互联网科技 北京禾田雨橡互联网科技 时间互联网络科技 互联网金融 科技创新 天扬科技互联网广告 深圳互联网科技怎么样 互联网公司会议桌创意科技软装饰 团飞科技与伯堂互联网服务平台 重庆威客帮互联网科技 全球顶尖互联网科技公司 南平创想时代互联网科技有限公司 华夏恒生科技与互联网科技 深圳市罗太互联网科技有限公司 元气玛特互联网科技公司是外包吗 黑科技 体验场景 互联网大会 吉林省码上互联网科技电话 上海睿民互联网科技有限公司 湖南永感互联网科技有限公司 互联网科技公司税收优惠 融贸通互联网科技 顶级互联网科技成果有哪些 厦门比较好的科技互联网公司 广西互联网科技孵化中心 科技互联网的核心竞争力 东营紫格互联网科技 广州全民伙伴互联网科技有限公司
0