asp.net core 微信公众号支付(扫码支付,H5支付,公众号支付,app支付)之3

  在微信公众号中访问手机网站,当需要调用支付时候无法使用H5支付,只有使用微信公众号支付,使用公众号支付用户必须关注该公众号同时该公众号必须开通公众号支付功能。

  1.获取用户的OpenId ,参考之前写的随笔 https://www.cnblogs.com/jomzhang/p/9209241.html

  2.微信公众号支付唤起需要一下几个参数

            //定义参数名
            string _appId = "appId";
            string _nonceStr = "nonceStr";
            string _package = "package";
            string _signType = "signType";
            string _timeStamp = "timeStamp";
            string _paySign = "paySign";        

  如果不使用工具类Senparc.Weixin.MP.TenPayLibV3.RequestHandler去生成签名的话需要注意生成签名时候字符串拼接的顺序

  3.微信公共号支付业务类方法

  

     /// <summary>
        /// 获取微信内置H5支付需要的信息,公众号支付返回的是个有序字典,利用字典的各个值调用jssdk获取微信内的公众号支付
        /// </summary>
        /// <param name="out_trade_no">订单号</param>
        /// <param name="body">描述</param>
        /// <param name="total_fee">总价</param>
        /// <param name="ip">客户IP</param>
        /// <param name="product_id">商品id</param>
        /// <param name="openid">openid</param>
        /// <returns></returns>
        public SortedDictionary<string, string> GetWxGZHPayInfo(string out_trade_no, string body, string total_fee, string ip, string product_id, string openid = "")
        {
            //定义参数名
            string _appId = "appId";
            string _nonceStr = "nonceStr";
            string _package = "package";
            string _signType = "signType";
            string _timeStamp = "timeStamp";
            string _paySign = "paySign";

            //构造返回参数字典
            SortedDictionary<string, string> dicResult = new SortedDictionary<string, string>();
            dicResult.Add(_appId, wxPayConfig.appid);
            dicResult.Add(_timeStamp, Senparc.Weixin.Helpers.DateTimeHelper.GetWeixinDateTime(DateTime.Now)+ "");
            dicResult.Add(_nonceStr, Senparc.Weixin.MP.TenPayLibV3.TenPayV3Util.GetNoncestr());
            dicResult.Add(_package, "");
            dicResult.Add(_signType, "MD5");
            dicResult.Add(_paySign, "");
            
            //构造请求参数
            Senparc.Weixin.MP.TenPayLibV3.RequestHandler packageReqHandler = new Senparc.Weixin.MP.TenPayLibV3.RequestHandler();

            #region 构造请求参数
            packageReqHandler.SetParameter("appid", wxPayConfig.appid);//APPID
            packageReqHandler.SetParameter("mch_id", wxPayConfig.mchid);//商户号
            packageReqHandler.SetParameter("nonce_str", Senparc.Weixin.MP.TenPayLibV3.TenPayV3Util.GetNoncestr());//随机串
            packageReqHandler.SetParameter("body", body);
            packageReqHandler.SetParameter("out_trade_no", out_trade_no);//订单号
            packageReqHandler.SetParameter("total_fee", (int)(Convert.ToDecimal(total_fee) * 100) + ""); //金额,以分为单位
            packageReqHandler.SetParameter("spbill_create_ip", ip);//IP
            packageReqHandler.SetParameter("notify_url", wxPayConfig.notify_url); //回调地址
            packageReqHandler.SetParameter("trade_type", "JSAPI");//公共号支付
            packageReqHandler.SetParameter("product_id", product_id);//商品ID
            packageReqHandler.SetParameter("openid", openid);//OPENID
            packageReqHandler.SetParameter("sign", packageReqHandler.CreateMd5Sign("key", wxPayConfig.key));//商户API密钥(签名) 
            #endregion

            //将参数转为xml字符串
            string data = packageReqHandler.ParseXML(); //发起post异步请求,获取返回的内容
             var result = PostWithStringFile(wxPayConfig.api_url, data);

            Log.Info("【GetWxGZHPayInfo】订单:" + out_trade_no + ",请求得到的xml:" + result, "微信支付");

            var res = System.Xml.Linq.XDocument.Parse(result);//解析xml,为了填充prepay_id参数和_paySign参数。
            try
            {
                //填充prepay_id参数
                string prepay_id = res.Element("xml").Element("prepay_id").Value;
                Log.Info("【GetWxGZHPayInfo】订单:" + out_trade_no + ",请求得到的prepay_id:" + prepay_id, "微信支付");
                dicResult[_package] = "prepay_id=" + prepay_id;

                //获取MD5签名字符串,注意顺序不能错
                string _stringSignTemp = "appId=" + dicResult[_appId] + "&nonceStr=" + dicResult[_nonceStr] + "&package=" + dicResult[_package] + "&signType=" + dicResult[_signType] + "&timeStamp=" + dicResult[_timeStamp] + "&key=" + wxPayConfig.key;
                Log.Info("【GetWxGZHPayInfo】_stringSignTemp=" + _stringSignTemp, "微信支付");

                //填充_paySign参数
                string _sign = Senparc.Weixin.Helpers.EncryptHelper.GetMD5(_stringSignTemp);
                dicResult[_paySign] = _sign;
                return dicResult;
            }
            catch (Exception ex)
            {
                Log.Info($"【GetWxGZHPayInfo】订单:{out_trade_no },异常:{ ex.ToString()}", "微信支付");
                return dicResult;
            }
        }

  方法内容为构造一个返回字典dicResult,但package和paySign参数需要请求微信api去获取,构造请求工具类packageReqHandler,请求微信api获取得到xml文件解析得到prepay_id参数,将内容"prepay_id=" + prepay_id填充到package参数。最后就剩下签名字段,构造签名字符串_stringSignTemp(一定注意拼接顺序,微信开发接口有提供签名校验,网址:https://pay.weixin.qq.com/wiki/tools/signverify/),使用md5签名得到paysign,最后返回字典给控制器传给前端即可。注(PostWithStringFile方法和wxPayConfig类在扫码支付篇有贴出)

posted @ 2018-06-21 16:00  jomz  阅读(960)  评论(0编辑  收藏  举报