zoukankan      html  css  js  c++  java
  • 微信公众号支付

    1.获取用户open_id

    /// <summary>
            /// 获取openid 并返回视图
            /// </summary>
            /// <param name="Code"></param>
            /// <param name="OrderGuid"></param>
            /// <returns></returns>
            public ActionResult VisaPay(string Code, Guid OrderGuid)
            {
                try
                {
                    var appid = "wxxxxxxxxxxxxxxxxxxxxxxx";
                    var secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
                    if (string.IsNullOrEmpty(Code))
                    {
                        //向微信发送请求 获取code
                        string url1 = UrlEncode("http://wechat.yimalx.com/WeChatSite/WeChatPay/VisaPay?orderGuid=" + OrderGuid);
                        var url = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect", appid, url1);
                        return Redirect(url);
                    }
                    else
                    {
                        //获取token
                        var client = new System.Net.WebClient();
                        client.Encoding = System.Text.Encoding.UTF8;
    
                        var url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appid, secret, Code);
                        var data = client.DownloadString(url);
                        var serializer = new JavaScriptSerializer();
                        var obj = serializer.Deserialize<Dictionary<string, string>>(data);
                        string accessToken;
                        if (!obj.TryGetValue("access_token", out accessToken))
                            return Redirect("404");
    
                        var opentid = obj["openid"];
    
                        var model = OrderInfoManager.Instance.GetById(OrderGuid);
                        ViewData["PayAmount"] = model.PayAmount;
                        ViewData["OrderGuid"] = OrderGuid;
                        string str = WeChatPayHelper.GoToWeCharJSPay(OrderGuid, opentid);
                        CreateLog.SaveLogs("str==============================" + str + "=================================", 1);
                        var codeId = new XmlDocument();
                        codeId.LoadXml(str);
                        var info = new WeChatInfo();
                        //8.读取xml节点的值
                        info.return_code = codeId.SelectSingleNode("xml/return_code").InnerText;
                        info.return_msg = codeId.SelectSingleNode("xml/return_msg").InnerText;
                        info.appid = codeId.SelectSingleNode("xml/appid").InnerText;
                        info.mch_id = codeId.SelectSingleNode("xml/mch_id").InnerText;
                        info.nonce_str = codeId.SelectSingleNode("xml/nonce_str").InnerText;
                        info.openid = opentid;
                        info.sign = codeId.SelectSingleNode("xml/sign").InnerText;
                        info.result_code = codeId.SelectSingleNode("xml/result_code").InnerText;
                        info.prepay_id = codeId.SelectSingleNode("xml/prepay_id").InnerText;
                        info.trade_type = codeId.SelectSingleNode("xml/trade_type").InnerText;
    
                        string timestamp = WeChatPayHelper.GetTimeStamp();
                        var res = new Dictionary<string, object>
                        {
                            {"appId", info.appid },
                            {"nonceStr", info.nonce_str},
                            {"timeStamp",timestamp},
                            {"signType","MD5"},
                            {"package","prepay_id="+info.prepay_id}
                        };
                        info.sign = WeChatPayHelper.GetSignString(res);
    
                        info.timeStamp = timestamp;
                        return View(info);
                    }
                }
                catch (Exception e)
                {
                    CreateLog.SaveLogs(e.Message, 0);
                    return Redirect("WeChatSite/WeChatPay/VisaPay?OrderGuid=" + OrderGuid);
                }
    
            }
    GetOpen_id

    2.调用统一下单接口生成预付款单

    /// <summary>
            /// 微信客户端内部提交支付申请
            /// </summary>
            /// <param name="orderGuid"></param>
            /// <returns></returns>
            [HttpGet]
            public static  string GoToWeCharJSPay(Guid orderGuid, string token)
            {
                var weCharUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
                var model = OrderInfoManager.Instance.GetById(orderGuid);
                unifiedorder unOrder = new unifiedorder();
                unOrder.appid = ConfigurationManager.AppSettings["wx_appid"];
                unOrder.mch_id = ConfigurationManager.AppSettings["wx_mch_id"];
                unOrder.nonce_str = Guid.NewGuid().ToString().Replace("-", "");
                unOrder.sign = "";
                unOrder.body = model.ProductName;
                unOrder.out_trade_no = model.OrderCode;
                //payAmountmodel.PayAmount
                unOrder.total_fee = Convert.ToInt32(model.PayAmount * 100);
                unOrder.spbill_create_ip = GetWebClientIp();
                unOrder.notify_url = ConfigurationManager.AppSettings["wechatUrl"] + "WeChatSite/WeChatPay/ProcessingCallback";
                unOrder.trade_type = "JSAPI";
                unOrder.openid = token;
                unOrder.device_info = "WEB";
                var dc = new Dictionary<string, object>()
                {
                    {"appid",unOrder.appid},
                    {"mch_id",unOrder.mch_id},
                    {"total_fee",unOrder.total_fee}, 
                    {"out_trade_no",unOrder.out_trade_no},
                    {"body",unOrder.body},
                    {"notify_url",unOrder.notify_url},
                    {"trade_type",unOrder.trade_type},
                    {"nonce_str",unOrder.nonce_str},
                    {"spbill_create_ip",unOrder.spbill_create_ip},
                    {"openid",unOrder.openid},
                    //{"scene_info","h5_info"}
                };
                dc.Add("sign", GetSignString(dc));//签名
                //2.将参数转换为xml格式
                var sb = new StringBuilder();
                sb.Append("<xml>");
                foreach (var d in dc)
                {
    
                    sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
    
                }
                sb.Append("</xml>");
                //应用场景信息
                //1.创建请求连接
                var request = (HttpWebRequest)WebRequest.Create(weCharUrl);
                //2.设置参数
    
                var data = Encoding.UTF8.GetBytes(sb.ToString());
                //4.设置属性
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                //5.将转换后的参数以文件流的形式写入到请求中
                using (var stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
                //6.声明变量,获取响应
                var response = (HttpWebResponse)request.GetResponse();
                //7.以文件流的方式读取响应结果
                var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
                //
                return responseString;
            }
    GoToWeCharJSPay

    3.回调

      1).同步回调:前端拉起微信支付界面,判断支付结果

     <script>
            function onBridgeReady() {
                WeixinJSBridge.invoke(
                    'getBrandWCPayRequest', {
                        "appId": "@Model.appid",     //公众号名称,由商户传入
                        "timeStamp": "@Model.timeStamp",         //时间戳,自1970年以来的秒数
                        "nonceStr": "@Model.nonce_str", //随机串
                        "package": "prepay_id=@Model.prepay_id",
                        "signType": "MD5",         //微信签名方式:
                        "paySign": "@Model.sign" //微信签名
                    },
                    function (res) {
                        // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。
                        if (res.err_msg == "get_brand_wcpay_request:ok") {
                            alert("支付成功");
                            window.location.href = "/WeChatSite/Home/Index";
                        } else if (res.err_msg == "get_brand_wcpay_request:cancel") {
                            alert("支付过程中用户取消");
                        } else if (res.err_msg == "get_brand_wcpay_request:fail") {
                            alert("支付失败");
                        }
    
                    }
                );
            }
            $(".immediate_payment").click(function () {
                if (typeof WeixinJSBridge == "undefined") {
                    if (document.addEventListener) {
                        document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
                    } else if (document.attachEvent) {
                        document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
                        document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
                    }
                } else {
                    onBridgeReady();
                }
            });
        </script>
    View Code

      2)异步:获取微信回台一步返回的结果,(方法地址:请求统一下单API的notify_url字段)

        { 1.获取异步返回的文件流

         2.读取文件流并解析文件流,判断执行结果,如果成功则需要验证签名是否正确,

         3.签名验证成功执行数据操作,更改本地支付信息。

      /// <summary>
            /// 处理回调数据
            /// </summary>
            public ActionResult ProcessingCallback()
            {
                //1.获取微信支付回调信息
                string XmlData = getPostStr();
                //判断数据是否为空
                if (XmlData.IsNotNullOrEmpty())
                {
                    DataSet ds = new DataSet();
                    StringReader sr = new StringReader(XmlData);
                    XmlTextReader dataReader = new XmlTextReader(sr);
                    ds.ReadXml(dataReader);
                    CreateLog.SaveLogs("--------------------XMLData&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" + XmlData + "&&&&&&&&&&&&&&&&&&&", 1);
                    if (ds.Tables[0].Rows[0]["return_code"].ToString() == "SUCCESS")
                    {
                        #region 解析ds获取对象
                        //将dataset转换为对象
                        WeChatPaymentReturn wcpr = new WeChatPaymentReturn()
                        {
                            appid = ds.Tables[0].Rows[0]["appid"].ToString(),
                            bank_type = ds.Tables[0].Rows[0]["bank_type"].ToString(),
                            cash_fee = ds.Tables[0].Rows[0]["cash_fee"].ToString(),
                            fee_type = ds.Tables[0].Rows[0]["fee_type"].ToString(),
                            is_subscribe = ds.Tables[0].Rows[0]["is_subscribe"].ToString(),
                            mch_id = ds.Tables[0].Rows[0]["mch_id"].ToString(),
                            nonce_str = ds.Tables[0].Rows[0]["nonce_str"].ToString(),
                            openid = ds.Tables[0].Rows[0]["openid"].ToString(),
                            out_trade_no = ds.Tables[0].Rows[0]["out_trade_no"].ToString(),
                            result_code = ds.Tables[0].Rows[0]["result_code"].ToString(),
                            return_code = ds.Tables[0].Rows[0]["return_code"].ToString(),
                            time_end = ds.Tables[0].Rows[0]["time_end"].ToString(),
                            total_fee = ds.Tables[0].Rows[0]["total_fee"].ToString(),
                            trade_type = ds.Tables[0].Rows[0]["trade_type"].ToString(),
                            transaction_id = ds.Tables[0].Rows[0]["transaction_id"].ToString(),
                            sign = ds.Tables[0].Rows[0]["sign"].ToString(),
                        };
    
                        #endregion
                        //4.支付成功之后验证Sign
                        var againSign = new Dictionary<string, object>();
                        againSign.Add("appid", wcpr.appid);
                        againSign.Add("bank_type", wcpr.bank_type);
                        againSign.Add("cash_fee", wcpr.cash_fee);
                        againSign.Add("fee_type", wcpr.fee_type);
                        againSign.Add("is_subscribe", wcpr.is_subscribe);
                        againSign.Add("mch_id", wcpr.mch_id);
                        againSign.Add("nonce_str", wcpr.nonce_str);
                        againSign.Add("openid", wcpr.openid);
                        againSign.Add("out_trade_no", wcpr.out_trade_no);
                        againSign.Add("result_code", wcpr.result_code);
                        againSign.Add("return_code", wcpr.return_code);
                        againSign.Add("time_end", wcpr.time_end);
                        againSign.Add("total_fee", wcpr.total_fee);
                        againSign.Add("trade_type", wcpr.trade_type);
                        againSign.Add("transaction_id", wcpr.transaction_id);
                        string againSignStr = WeChatPayHelper.GetSignString(againSign);
                        if (wcpr.sign.ToUpper() == againSignStr.ToUpper())
                        {
                            CreateLog.SaveLogs("####签名验证成功againSignStr######" + againSignStr + "-------sign-------------" + wcpr.sign, 1);
    
                            #region 处理数据逻辑
                            //更新订单信息
                            //添加支付信息
                            CreateLog.SaveLogs("开始付款", 1);
                            //签名正确   处理订单操作逻辑
                            var oderInfo = OrderInfoManager.Instance.GetByField("OrderCode", wcpr.out_trade_no).FirstOrDefault();
                            if (oderInfo.OrderState != (int)OrderState.代付款)
                            {
                                CreateLog.SaveLogs("支付成功!但是在此发出请求", 1);
                                return null;
                            }
                            if (oderInfo != null)
                            {
                                try
                                {
                                    OrderInfoManager.Instance.UpdataStatus(oderInfo.Guid, (int) OrderState.已付款);
                                    CreateLog.SaveLogs("状态修改结束", 1);
                                    PaymentInfo info = new PaymentInfo()
                                    {
                                        OrderGuid = oderInfo.Guid,
                                        PayState = 1,
                                        PayMethod = (int)PayMethod.微信支付,
                                        Guid = Guid.NewGuid(),
                                        Mark = (int)DataMark.正常,
                                        PayDateTime = DateTime.Now,
                                        PayMoney = Convert.ToDecimal(wcpr.total_fee) / 100,
                                        Qid = wcpr.transaction_id
                                    };
                                    PaymentInfoManager.Instance.Insert(info);
                                    CreateLog.SaveLogs("支付信息添加成功", 1);
                                }
                                catch (Exception e)
                                {
                                    CreateLog.SaveLogs("-----Exception" + e,1);
                                    throw;
                                }
    
                            }
                            //CreateLog.SaveLogs("状态修改结束", 1);
                            #endregion
                        }
                        else
                        {
                            CreateLog.SaveLogs("####签名验证失败againSignStr######" + againSignStr + "-------sign-------------" + wcpr.sign, 1);
                        }
    
                    }
                    else
                    {
                        // 返回信息,如非空,为错误原因  签名失败 参数格式校验错误
                        string return_msg = ds.Tables[0].Rows[0]["return_msg"].ToString();
                        CreateLog.SaveLogs("支付失败", 1);
    
                    }
                }
                return View();
            }
            //getPostStr
            /// <summary>
            /// 获取微信支付毁掉的数据;
            /// </summary>
            /// <returns></returns>
            public string getPostStr()
            {
                Int32 intLen = Convert.ToInt32(Request.InputStream.Length);
                byte[] b = new byte[intLen];
                Request.InputStream.Read(b, 0, intLen);
                return System.Text.Encoding.UTF8.GetString(b);
            }
    ProcessingCallback

        }

    微信支付辅助方法

            /// <summary>
            /// 获取客户端ip
            /// </summary>
            /// <returns>返回客户端IP地址</returns>
            public static string GetWebClientIp()
            {
                HttpRequest request = HttpContext.Current.Request;
                string result = request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                string a = request.UserHostAddress;
                if (String.IsNullOrEmpty(result))
                {
                    result = request.ServerVariables["REMOTE_ADDR"];
                }
                if (String.IsNullOrEmpty(result))
                {
                    result = request.UserHostAddress;
                }
                if (String.IsNullOrEmpty(result))
                {
                    result = "0.0.0.0";
                }
                return result;
    
    
    
                //string userIP = "IP";
    
                //try
                //{
                //    if (System.Web.HttpContext.Current == null
                //|| System.Web.HttpContext.Current.Request == null
                //|| System.Web.HttpContext.Current.Request.ServerVariables == null)
                //        return "";
    
                //    string CustomerIP = "";
    
                //    //CDN加速后取到的IP   
                //    CustomerIP = System.Web.HttpContext.Current.Request.Headers["Cdn-Src-Ip"];
                //    if (!string.IsNullOrEmpty(CustomerIP))
                //    {
                //        return CustomerIP;
                //    }
    
                //    CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    
    
                //    if (!String.IsNullOrEmpty(CustomerIP))
                //        return CustomerIP;
    
                //    if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
                //    {
                //        CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                //        if (CustomerIP == null)
                //            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                //    }
                //    else
                //    {
                //        CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
    
                //    }
    
                //    if (string.Compare(CustomerIP, "unknown", true) == 0)
                //        return System.Web.HttpContext.Current.Request.UserHostAddress;
                //    return CustomerIP;
                //}
                //catch { }
    
                //return userIP;
                string user_IP;
    
                if (HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
                {
    
                    user_IP = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
    
                }
    
                else
                {
    
                    user_IP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString();
    
                }
                return user_IP;
            }
            /// <summary>
            /// 获取Sign签名
            /// </summary>
            /// <param name="dic">键值对集合</param>
            /// <returns>字符串类型的签名</returns>
            public static string GetSignString(Dictionary<string, object> dic)
            {
                string key = WebConfigurationManager.AppSettings["wx_key"].ToString(); ;//商户平台 API安全里面设置的KEY  32位长度
                //排序
                dic = dic.OrderBy(d => d.Key).ToDictionary(d => d.Key, d => d.Value);
                //连接字段
                var sign = dic.Aggregate("", (current, d) => current + (d.Key + "=" + d.Value + "&"));
                sign += "key=" + key;
                //MD5
                sign = FormsAuthentication.HashPasswordForStoringInConfigFile(sign, "MD5").ToUpper();
    
                return sign;
            }
            /// <summary>
            /// 时间格式化
            /// </summary>
            /// <param name="date"></param>
            /// <returns></returns>
            public static string Format(DateTime date)
            {
                var dates = "";
                dates += date.Year;
                dates += date.Month;
                dates += date.Date;
                dates += date.Hour;
                dates += date.Minute;
                dates += date.Second;
                return dates;
    
            }
            /// <summary>
            /// 获取时间戳
            /// </summary>
            /// <returns></returns>
            public static string GetTimeStamp()
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
    weChatHelper

    微信支付实体类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Travel.WeChat.ViewModel.WeiPay
    {
        public class unifiedorder
        {
            /// <summary>
            /// 公众账号ID
            /// </summary>
            public string appid { get; set; } 
            /// <summary>
            /// 商户号
            /// </summary>
            public string mch_id { get; set; }
            /// <summary>
            /// 设备号
            /// </summary>
            public string device_info { get; set; }
            /// <summary>
            /// 随机字符串
            /// </summary>
            public string nonce_str { get; set; }
            /// <summary>
            /// 签名
            /// </summary>
            public string sign { get; set; } 
            public string sign_type { get; set; }
            /// <summary>
            /// 商品描述
            /// </summary>
            public string body { get; set; }
            public string detail { get; set; }
            public string attach { get; set; }
            /// <summary>
            /// 商户订单号
            /// </summary>
            public string out_trade_no { get; set; }
            public string fee_type { get; set; }
            /// <summary>
            /// 总金额
            /// </summary>
            public int    total_fee { get; set; }
            /// <summary>
            /// 终端IP
            /// </summary>
            public string spbill_create_ip { get; set; }
            public string time_start { get; set; }
            public string time_expire { get; set; }
            public string goods_tag { get; set; }
            /// <summary>
            /// 通知地址
            /// </summary>
            public string notify_url { get; set; }
            /// <summary>
            /// 交易类型
            /// </summary>
            public string trade_type { get; set; }
            public string product_id { get; set; }
            public string limit_pay { get; set; }
            public string openid { get; set; }
            public List<h5_info> scene_info { get; set; }
        }
    }
    1.unifiedorder
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Travel.WeChat.ViewModel.WeiPay
    {
        public class WeChatInfo
        {
            //统一下单接口返回值
            public string return_code { get; set; }
            public string return_msg { get; set; }
            public string appid { get; set; }
            public string mch_id { get; set; }
            public string nonce_str { get; set; }
            public string openid { get; set; }
            public string sign { get; set; }
            public string result_code { get; set; }
            public string prepay_id { get; set; }
            public string trade_type { get; set; }
            public string timeStamp { get; set; }
        }
    }
    2.WeChatInfo
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Travel.WeChat.ViewModel.WeiPay
    {
        public class WeChatPaymentReturn
        {
    //异步回调的返回信息
            public string appid { get; set; }
            public string bank_type { get; set; }
            public string cash_fee { get; set; }
            public string fee_type { get; set; }
            public string is_subscribe { get; set; }
            public string mch_id { get; set; }
            public string nonce_str { get; set; }
            public string openid{ get; set; }
            public string out_trade_no{ get; set; }
            public string result_code{ get; set; }
            public string return_code{ get; set; }
            public string sign{ get; set; }
            public string time_end{ get; set; }
            public string total_fee{ get; set; }
            public string trade_type{ get; set; }
            public string transaction_id{ get; set; }
        }
    }
    3.WeChatPaymentReturn
  • 相关阅读:
    《神经网络的梯度推导与代码验证》之vanilla RNN的前向传播和反向梯度推导
    《神经网络的梯度推导与代码验证》之CNN(卷积神经网络)前向和反向传播过程的代码验证
    《神经网络的梯度推导与代码验证》之CNN(卷积神经网络)的前向传播和反向梯度推导
    《神经网络的梯度推导与代码验证》之FNN(DNN)前向和反向传播过程的代码验证
    《神经网络的梯度推导与代码验证》之FNN(DNN)的前向传播和反向梯度推导
    《神经网络的梯度推导与代码验证》之数学基础篇:矩阵微分与求导
    《神经网络的梯度推导与代码验证》系列介绍
    手把手撸套框架-关于2.0的一些畅想
    手把手撸套框架-Victory.Core工具集
    手把手撸套框架-Victory框架1.1 详解
  • 原文地址:https://www.cnblogs.com/JueXiaoQiang/p/7905402.html
Copyright © 2011-2022 走看看