V3 微信支付-预支付C#

首先不得不吐槽下腾讯,升级微信支付为毛不兼容V2版本呢?V2算是白研究了。


 

 V3预支付文档几个坑,不知道你们有没有中招

  1. 商户号 mch_id 是 String(32) 微信支付分配的商户号   其实是邮件的“微信支付商户号(接口文档中的商户号MCHID)” ,我一直都以为是商户号。
  2. 预支付提交的xml节点值都必须带有<![CDATA[]]>,如果根据文档开发只带部分。那么你就开心了,一直都是sign签名错误。

回到正文,以下为实现代码

public class PaymentHandler : RequestHandler

    {



        public PaymentHandler(HttpContext context)

            : base(context, WX_V3_CONFIG.config.PartnerKey)

        {



        }



        /// <summary>

        /// 获取预支付订单号

        /// </summary>

        /// <returns></returns>

        public string GetUnifiedOrder(string body, string openid, string trade_type)

        {



            base.setParameter("appid", WX_V3_CONFIG.config.AppID);

            base.setParameter("mch_id", WX_V3_CONFIG.config.MCHID);

            base.setParameter("nonce_str", TenpayUtil.getNoncestr());

            base.setParameter("body", body);

            base.setParameter("out_trade_no", TenpayUtil.getOrderNo());

            base.setParameter("total_fee", "1");

            base.setParameter("spbill_create_ip", "192.168.1.1");//base.httpContext.Request.UserHostAddress);

            base.setParameter("notify_url", "www.111.com");

            base.setParameter("trade_type", "JSAPI");

            base.setParameter("openid", openid);

            base.createSign();



            string s = HttpHelper.OpenReadWithHttps("https://api.mch.weixin.qq.com/pay/unifiedorder", base.parseXML());//post请求



            return "";

        }

    }

RequestHandler帮助类

/// <summary>

    /// RequestHandler 的摘要说明。

    /// </summary>

    public class RequestHandler

    {



        public RequestHandler(HttpContext httpContext, string key)

        {

            parameters = new Hashtable();

            this.key = key;

            this.httpContext = httpContext;



        }

        /**  密钥 */

        private string key;



        protected HttpContext httpContext;



        /** 请求的参数 */

        protected Hashtable parameters;



        /** debug信息 */

        private string debugInfo;



        /** 初始化函数 */

        public virtual void init()

        {

        }

        /** 获取debug信息 */

        public String getDebugInfo()

        {

            return debugInfo;

        }

        /** 获取密钥 */

        public String getKey()

        {

            return key;

        }



        /** 设置密钥 */

        public void setKey(string key)

        {

            this.key = key;

        }



        /** 设置参数值 */

        public void setParameter(string parameter, string parameterValue)

        {

            if (parameter != null && parameter != "")

            {

                if (parameters.Contains(parameter))

                {

                    parameters.Remove(parameter);

                }



                parameters.Add(parameter, parameterValue);

            }

        }



        /** 获取参数值 */

        public string getParameter(string parameter)

        {

            string s = (string)parameters[parameter];

            return (null == s) ? "" : s;

        }



        //获取package带参数的签名包

        public string getRequestURL()

        {

            this.createSign();

            StringBuilder sb = new StringBuilder();

            ArrayList akeys = new ArrayList(parameters.Keys);

            akeys.Sort();

            foreach (string k in akeys)

            {

                string v = (string)parameters[k];

                if (null != v && "key".CompareTo(k) != 0)

                {

                    sb.Append(k + "=" + TenpayUtil.UrlEncode(v, getCharset()) + "&");

                }

            }



            //去掉最后一个&

            if (sb.Length > 0)

            {

                sb.Remove(sb.Length - 1, 1);

            }





            return sb.ToString();



        }





        //创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。



        protected virtual void createSign()

        {

            StringBuilder sb = new StringBuilder();



            ArrayList akeys = new ArrayList(parameters.Keys);

            akeys.Sort();



            foreach (string k in akeys)

            {

                string v = (string)parameters[k];

                if (null != v && "".CompareTo(v) != 0

                    && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)

                {

                    sb.Append(k + "=" + v + "&");

                }

            }



            sb.Append("key=" + this.getKey());

            string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper();



            this.setParameter("sign", sign);



            //debug信息

            this.setDebugInfo(sb.ToString() + " => sign:" + sign);

        }





        //创建package签名

        public virtual string createMd5Sign()

        {

            StringBuilder sb = new StringBuilder();

            ArrayList akeys = new ArrayList(parameters.Keys);

            akeys.Sort();



            foreach (string k in akeys)

            {

                string v = (string)parameters[k];

                if (null != v && "".CompareTo(v) != 0

                    && "sign".CompareTo(k) != 0 && "".CompareTo(v) != 0)

                {

                    sb.Append(k + "=" + v + "&");

                }

            }

            string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToLower();



            this.setParameter("sign", sign);

            return sign;

        }





        //创建sha1签名

        public string createSHA1Sign()

        {

            StringBuilder sb = new StringBuilder();

            ArrayList akeys = new ArrayList(parameters.Keys);

            akeys.Sort();



            foreach (string k in akeys)

            {

                string v = (string)parameters[k];

                if (null != v && "".CompareTo(v) != 0

                       && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)

                {

                    if (sb.Length == 0)

                    {

                        sb.Append(k + "=" + v);

                    }

                    else

                    {

                        sb.Append("&" + k + "=" + v);

                    }

                }

            }

            string paySign = SHA1Util.getSha1(sb.ToString()).ToString().ToLower();



            //debug信息

            this.setDebugInfo(sb.ToString() + " => sign:" + paySign);

            return paySign;

        }





        //输出XML

        public string parseXML()

        {

            StringBuilder sb = new StringBuilder();

            sb.Append("<xml>");

            foreach (string k in parameters.Keys)

            {

                string v = (string)parameters[k];

                if (Regex.IsMatch(v, @"^[0-9.]$"))

                {



                    sb.Append("<" + k + ">" + v + "</" + k + ">");

                }

                else

                {

                    sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");

                }



            }

            sb.Append("</xml>");

            return sb.ToString();

        }







        /** 设置debug信息 */

        public void setDebugInfo(String debugInfo)

        {

            this.debugInfo = debugInfo;

        }



        public Hashtable getAllParameters()

        {

            return this.parameters;

        }



        protected virtual string getCharset()

        {

            return this.httpContext.Request.ContentEncoding.BodyName;

        }

    }

 

你可能感兴趣的:(C#)