首页 > 上网技巧 > 电脑小技巧 > C# 微信支付V3支付回调验签处理

C# 微信支付V3支付回调验签处理

时间:2018-04-20 09:18 作者:QQ地带 我要评论

微信支付完成后会有一个支付回调页面,处理支付完成后的事件,V3支付回调的数据形式为XML格式。
 
1、定义一个WxResponseHandlerV3类,处理一般构造函数,用于解析XML对象;
 
[csharp] view plain copy
//xmlMap  
private Hashtable xmlMap;  
[csharp] view plain copy
//解析回传参数,将带有指定键和值的元素添加到 System.Collections.Hashtable 中。  
        public WxResponseHandlerV3(HttpContext _httpContext)  
        {  
            xmlMap = new Hashtable();  
            this.httpContext = _httpContext;  
  
            Stream stream = this.httpContext.Request.InputStream;  
            if (stream.Length > 0)  
            {  
                XmlDocument xmlDoc = new XmlDocument();  
                StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);  
                string strInputStream = sr.ReadToEnd();  
                Tools.PublicConfig.log_Append("stream length:" + stream.Length.ToString()  
                    + "this.httpContext.Request.InputStream string: " + strInputStream, "Pay/Pay_WxV3", DateTime.Now.ToString("yyyyMMdd") + ".log");  
                xmlDoc.LoadXml(strInputStream);  
                XmlNode root = xmlDoc.SelectSingleNode("xml");  
                XmlNodeList xnl = root.ChildNodes;  
  
                foreach (XmlNode xnf in xnl)  
                {  
                    xmlMap.Add(xnf.Name, xnf.InnerText);  
                }  
            }  
            if (stream != null)  
            {  
                stream.Close();  
            }  
        }  
2、验签处理
 
[csharp] view plain copy
 /** V3支付返回notify签名:按参数名称a-z排序,遇到空值的参数不参加签名。  //全部是 xmlMap 参数 
       * @return boolean */  
        public virtual Boolean isNotifySign()  
        {  
            StringBuilder sb = new StringBuilder();  
  
            ArrayList akeys = new ArrayList(xmlMap.Keys);  
            akeys.Sort();  
  
            foreach (string k in akeys)  
            {  
                string v = (string)getXmlMap(k);  
                if (null != v && "".CompareTo(v) != 0  
                    && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)  
                {  
                    sb.Append(k + "=" + v + "&");  
                }  
            }  
  
            sb.Append("key=" + this.getPayKey());  
            string sign = Wxpay.MD5Util.MD5(sb.ToString()).ToUpper();  
            //debug信息  
            return getXmlMap("sign").ToUpper().Equals(sign);  
        }  
  
/** 获取xmlMap值 */  
        public string getXmlMap(string parameter)  
        {  
            string s = (string)xmlMap[parameter];  
            return (null == s) ? "" : s;  
        }  
  
/// <summary>  
        /// 设置V3 支付密钥  
        /// </summary>  
        /// <param name="key"></param>  
        public void setPayKey(string key)  
        {  
            this.paykey = key;  
        }  
        /** 获取V3支付密钥 */  
        public string getPayKey()  
        { return this.paykey; }  
MD5加密方法
 
[csharp] view plain copy
/// <summary>  
        /// 获得MD5加密字符串  
        /// </summary>  
        /// <param name="s">源字符串</param>  
        /// <returns>目标字符串</returns>  
        public static String MD5(String s)  
        {  
            char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };  
            try  
            {  
                byte[] btInput = System.Text.Encoding.UTF8.GetBytes(s);  
                // 获得MD5摘要算法的 MessageDigest 对象  
                MD5 mdInst = System.Security.Cryptography.MD5.Create();  
                // 使用指定的字节更新摘要  
                mdInst.ComputeHash(btInput);  
                // 获得密文  
                byte[] md = mdInst.Hash;  
                // 把密文转换成十六进制的字符串形式  
                int j = md.Length;  
                char[] str = new char[j * 2];  
                int k = 0;  
                for (int i = 0; i < j; i++)  
                {  
                    byte byte0 = md[i];  
                    str[k++] = hexDigits[(int)(((byte)byte0) >> 4) & 0xf];  
                    str[k++] = hexDigits[byte0 & 0xf];  
                }  
                return new string(str);  
            }  
            catch  
            {  
                // Console.Error.WriteLine(e.StackTrace);  
                return null;  
            }  
        }  
 
 
 
3、添加回调页面
 
[csharp] view plain copy
public ActionResult WxApplyPayNotify()  
        {  
            Response.ContentType = "text/xml";  
            Response.ContentEncoding = System.Text.Encoding.UTF8;  
            Response.CacheControl = "no-cache";  
            bool MyBusiness = false;  
            try  
            {  
                if (Request.InputStream.Length > 0)  
                {  
                    Wxpay.WxResponseHandlerV3 res = new Wxpay.WxResponseHandlerV3(System.Web.HttpContext.Current);  
                    res.setPayKey("sdjhfksdjhfksdjfhkkjhsdkfjh");//支付秘钥  
                    bool notifySign = res.isNotifySign();//验签  
                    if (notifySign)  
                    {  
                        //分期支付的out_trade_no是分期订单支付请求的requestNo  
                        string requestNo = res.getXmlMap("out_trade_no");  
                        //财付通订单号  
                        String transaction_id = res.getXmlMap("transaction_id");  
                        //金额,以分为单位  
                        String total_fee = res.getXmlMap("total_fee");  
                        // 是否关注公众账号is_subscribe 是String(1) 用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效  
                        string is_subscribe = res.getXmlMap("is_subscribe");  
                          
                        //判断签名及结果  
                        if ("SUCCESS".Equals(result_code.ToUpper()))  
                        {  
                            //支付成功,处理其他事物。。。  
  
                        }  
                        else  
                        {  
                            //支付失败处理。。。  
                            MyBusiness = true;  
                        }  
  
                        if (MyBusiness)  
                        {  
                            Response.Write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");  
                        }  
                        else  
                        {  
                            Response.Write("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[My Business error]]></return_msg></xml>");  
                        }  
  
                    }  
                    else  
                    {  
                        Response.Write("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名验证失败]]></return_msg></xml>");  
                    }  
                }  
  
            }  
            catch (Exception ex)  
            {  
  
                //系统异常  
            }  
            return View();  
        }  

标签: 微信 C#
顶一下
(0)
0%
踩一下
(0)
0%

Google提供的广告