V3 微信支付-預支付C#

首先不得不吐槽下騰訊,升級微信支付爲毛不兼容V2版本呢?V2算是白研究了。


 

 V3預支付文檔幾個坑,不知道大家有沒有中招api

  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幫助類app

/// <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;
        }
    }
相關文章
相關標籤/搜索