微信支付----PC掃碼支付(查詢微信支付訂單判斷是否支付成功)

    提示------------------幾個狀態沒有加判斷--------如:微信返回訂單號不存在,微信系統異常。。。。
  
  
  
  c#webapi建議前端輪番查詢訂單狀態
    #region  查詢掃碼訂單狀態
        /// <summary>
        /// 查詢掃碼支付狀態
        /// </summary>
        /// <param name="out_trade_no">支付訂單號</param>
        /// <returns></returns>
        [HttpGet]
        public ResponseMessage PayMent_Result(string out_trade_no)
        {
            if (out_trade_no != null)
            {
                PayMent pay = new PayMent();
                OrderDetail detail = pay.geidingdan(out_trade_no);
                if (detail.trade_state == "SUCCESS")//支付成功
                {
                    try
                    {
                    自己的業務邏輯(數據庫等等操作)
                    }
                    catch (Exception ex)
                    {
                        return new ResponseMessage { Code = -1};//系統異常
                    }


                    return new ResponseMessage { Code = 1 };
                }
                else if (detail.trade_state == "USERPAYING")//用戶支付中 
                {
                    return new ResponseMessage { Code = 3 };
                    //return "3";

                }
                else if (detail.trade_state == "NOTPAY")//未支付 
                {
                    return new ResponseMessage { Code = 2 };
                    // return "2";

                }
                else if (detail.trade_state == "PAYERROR")//支付失敗
                {
                    return new ResponseMessage { Code = 4 };
                    //return "4"; ;

                } 
                else if (detail.err_code == "ORDERNOTEXIST")
                {
                    return new ResponseMessage { Code = -1, Message = detail.err_code_des }; //

                }
                else if (detail.err_code == "SYSTEMERROR")
                {

                    return new ResponseMessage { Code = -1, Message = detail.err_code_des }; //
                }
                else {

                    return new ResponseMessage { Code = 0 }; //其他狀態
                }
            }
            return new ResponseMessage { Code = -2 }; //支付訂單號不能爲空

        }
        #endregion
  
  #region 返回前端使用的code_url
  
  -----自己定義API接口
  -----調用NATIVEPayMent 方法傳入方法的參數,判斷返回結果如果爲""說明微信統一下單失敗了,可以在統一下單返回結果寫入日誌文件,查看失敗原因。
  
  #endregion
  
  
  
  ----------ENDAPI---------------------------------------------------------------------------------------------
  
  /// <summary>
        /// 微信掃碼支付
        /// </summary>
        /// <param name="appid">公衆號ID</param>
        /// <param name="boby">商品描述</param>
        /// <param name="mch_id">商戶號</param>
        /// <param name="spbill_create_ip">終端IP</param>
        /// <param name="total_fee">金額</param>
        /// <param name="out_trade_no">商戶訂單號</param>
        /// <param name="paysignkey">證書密匙</param>
        /// <param name="product_id">二維碼中包含的商品ID</param>
        /// <returns></returns>
        public string NATIVEPayMent (string boby, string spbill_create_ip, Double total_fee, string out_trade_no, string product_id)
       {
           UnifiedOrder order = new UnifiedOrder();
           order.appid = WXconfig.appid;
           order.attach = "服務費";
           order.body = boby;
           order.device_info = "";
           order.mch_id = WXconfig.mch_id;
           order.nonce_str = TenpayUtil.getNoncestr();
           order.notify_url = Wxconfig.url;
           order.out_trade_no = out_trade_no;
           order.product_id = product_id;
           order.trade_type = "NATIVE";
           order.spbill_create_ip = spbill_create_ip;
           order.total_fee = Convert.ToInt32((total_fee) * 100);
           TenpayUtil tenpay = new TenpayUtil();
           string paySignKey = WXconfig.paysignkey;       
           string code_url = tenpay.getcode_url(order, paySignKey);
           return code_url;
       }

        /// <summary>
        /// 查詢掃碼訂單情況
        /// </summary>
        /// <param name="out_trade_no">商戶訂單號</param>
        /// <returns></returns>
        public OrderDetail geidingdan(string out_trade_no)
        {
            TenpayUtil tenpay = new TenpayUtil();
            OrderDetail detail = tenpay.getOrderDetail(out_trade_no);

            return detail;
        }
        
        
         public    class TenpayUtil
    {
        #region url
        /// <summary>
        /// 統一支付接口
        /// </summary>
        const string UnifiedPayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";

        /// <summary>
        /// 網頁授權接口
        /// </summary>
        const string access_tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";

        /// <summary>
        /// 微信訂單查詢接口
        /// </summary>
        const string OrderQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";

        #endregion

        #region 隨機串,時間截
        /// <summary>
        /// 隨機串
        /// </summary>
        public static string getNoncestr()
        {
            Random random = new Random();
            return MD5Util.GetMD5(random.Next(1000).ToString(), "GBK").ToLower().Replace("s", "S");
        }


        /// <summary>
        /// 時間截,自1970年以來的秒數
        /// </summary>
        public static string getTimestamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }
        #endregion

        /// <summary>
        /// 網頁授權接口
        /// </summary>
        public static string getAccess_tokenUrl()
        {
            return access_tokenUrl;
        }


        #region 把微信掃碼支付的回調XML轉換集合
        public string GetXml(string xmlstring) {

            SortedDictionary < string, object> sd= GetInfoFromXml(xmlstring);
            string reslut = "";
            foreach (KeyValuePair<string, object> s in sd) {
                if (s.Key == "result_code") {
                    reslut= s.Value.ToString();
                }
            }
            return reslut;
        }
        #endregion

        #region 獲取微信簽名
        /// <summary>
        /// 獲取微信簽名
        /// </summary>
        /// <param name="sParams"></param>
        /// <returns></returns>
        public string getsign(SortedDictionary<string, object> sParams, string key)
        {
            int i = 0;
            string sign = string.Empty;
            StringBuilder sb = new StringBuilder();
            foreach (KeyValuePair<string, object> temp in sParams)
            {
                if (temp.Value.ToString() == "" || temp.Value == null || temp.Key.ToLower() == "sign")
                {
                    continue;
                }
                i++;
                sb.Append(temp.Key.Trim() + "=" + temp.Value.ToString() + "&");
            }
            sb.Append("key=" + key.Trim() + "");
            string signkey = sb.ToString();
            sign = MD5Util.GetMD5(signkey, "utf-8");
            //utf-8

            return sign;
        }

        #endregion

        #region post數據到指定接口並返回數據

        /// <summary>
        /// post數據到指定接口並返回數據
        /// </summary>
        public string PostXmlToUrl(string url, string postData,string type="")
        {
            string returnmsg = "";
            using (System.Net.WebClient wc = new System.Net.WebClient())
            {                      
                if (type != "") {
                     Encoding encoding = Encoding.UTF8;
                    wc.Encoding = System.Text.Encoding.GetEncoding("GB2312");
                    byte[] data = encoding.GetBytes(postData);
                    returnmsg = Encoding.UTF8.GetString(wc.UploadData(url, "POST", data));
                }
                else 
                 returnmsg = wc.UploadString(url, "POST", postData);
            }
            return returnmsg;
        }

        #endregion

        #region 獲取code_url
        /// <summary>
        /// 獲取code_url
        /// </summary>
        public string getcode_url(UnifiedOrder order, string key)
        {
            string code_url = "";

            string post_data = getUnifiedOrderXml(order, key);
            string request_data = PostXmlToUrl(UnifiedPayUrl, post_data);
            //string request_data = HttpRequestutil.RequestUrl(UnifiedPayUrl, post_data, "post");     

            SortedDictionary<string, object> requestXML = GetInfoFromXml(request_data);

            foreach (KeyValuePair<string, object> k in requestXML)
            {


                if (k.Key == "code_url")
                {
                    code_url = k.Value.ToString();
                    break;
                }
            }
            return code_url;
        }

        #endregion

        #region 獲取prepay_id

        /// <summary>
        /// 獲取prepay_id
        /// </summary>
        public string getPrepay_id(UnifiedOrder order, string key)
        {
            string prepay_id = "";
            
                string post_data = getUnifiedOrderXml(order, key);
                string request_data = PostXmlToUrl(UnifiedPayUrl, post_data);              

                SortedDictionary<string, object> requestXML = GetInfoFromXml(request_data);

                foreach (KeyValuePair<string, object> k in requestXML)
                {
               
                    
                    if (k.Key == "prepay_id")
                    {
                        prepay_id = k.Value.ToString();
                        break;
                    }
                }          
            return prepay_id;
        }

        #endregion

        #region 獲取微信訂單明細
        /// <summary>
        /// 獲取微信訂單明細
        /// </summary>
        public OrderDetail getOrderDetail(string out_trade_no)
        {
            string post_data = getQueryOrderXml(out_trade_no);
            string request_data = PostXmlToUrl(OrderQueryUrl, post_data,"1");
            OrderDetail orderdetail = new OrderDetail();
            SortedDictionary<string, object> requestXML = GetInfoFromXml(request_data);
            foreach (KeyValuePair<string, object> k in requestXML)
            {
                switch (k.Key)
                {
                    case "retuen_code":
                        orderdetail.result_code = k.Value.ToString();
                        break;
                    case "return_msg":
                        orderdetail.return_msg = k.Value.ToString();
                        break;
                    case "appid":
                        orderdetail.appid = k.Value.ToString();
                        break;
                    case "mch_id":
                        orderdetail.mch_id = k.Value.ToString();
                        break;
                    case "nonce_str":
                        orderdetail.nonce_str = k.Value.ToString();
                        break;
                    case "sign":
                        orderdetail.sign = k.Value.ToString();
                        break;
                    case "result_code":
                        orderdetail.result_code = k.Value.ToString();
                        break;
                    case "err_code":
                        orderdetail.err_code = k.Value.ToString();
                        break;
                    case "err_code_des":
                        orderdetail.err_code_des = k.Value.ToString();
                        break;
                    case "trade_state":
                        orderdetail.trade_state = k.Value.ToString();
                        break;
                    case "device_info":
                        orderdetail.device_info = k.Value.ToString();
                        break;
                    case "openid":
                        orderdetail.openid = k.Value.ToString();
                        break;
                    case "is_subscribe":
                        orderdetail.is_subscribe = k.Value.ToString();
                        break;
                    case "trade_type":
                        orderdetail.trade_type = k.Value.ToString();
                        break;
                    case "bank_type":
                        orderdetail.bank_type = k.Value.ToString();
                        break;
                    case "total_fee":
                        orderdetail.total_fee = k.Value.ToString();
                        break;
                    case "coupon_fee":
                        orderdetail.coupon_fee = k.Value.ToString();
                        break;
                    case "fee_type":
                        orderdetail.fee_type = k.Value.ToString();
                        break;
                    case "transaction_id":
                        orderdetail.transaction_id = k.Value.ToString();
                        break;
                    case "out_trade_no":
                        orderdetail.out_trade_no = k.Value.ToString();
                        break;
                    case "attach":
                        orderdetail.attach = k.Value.ToString();
                        break;
                    case "time_end":
                        orderdetail.time_end = k.Value.ToString();
                        break;
                    default:
                        break;
                }
            }
            return orderdetail;
        }
        #endregion

        #region 

        #region 把XML數據轉換爲SortedDictionary

        /// <summary>
        /// 把XML數據轉換爲SortedDictionary<string, string>集合
        /// </summary>
        /// <param name="strxml"></param>
        /// <returns></returns>
        protected SortedDictionary<string, object> GetInfoFromXml(string xmlstring)
        {
            SortedDictionary<string, object> sParams = new SortedDictionary<string, object>();
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xmlstring);
                XmlElement root = doc.DocumentElement;
                int len = root.ChildNodes.Count;
                for (int i = 0; i < len; i++)
                {
                    string name = root.ChildNodes[i].Name;
                    if (!sParams.ContainsKey(name))
                    {
                        sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
                    }
                }
            }
            catch(Exception ex ) {

            }
            return sParams;
        }

        #endregion

        #region 微信統一下單接口xml參數整理
        /// <summary>
        /// 微信統一下單接口xml參數整理
        /// </summary>
        /// <param name="order">微信支付參數實例</param>
        /// <param name="key">密鑰</param>
        /// <returns></returns>
        protected string getUnifiedOrderXml(UnifiedOrder order, string key)
        {
            string return_string = string.Empty;
            SortedDictionary<string, object> sParams = new SortedDictionary<string, object>();
            sParams.Add("appid", order.appid);
            sParams.Add("attach", order.attach);
            sParams.Add("body", order.body);
            sParams.Add("device_info", order.device_info);
            sParams.Add("mch_id", order.mch_id);
            sParams.Add("nonce_str", order.nonce_str);
            sParams.Add("notify_url", order.notify_url);
              //當 trade_type=JSAPI 時必輸入
            if (order.trade_type == "JSAPI")
            {
                sParams.Add("openid", order.openid);
            }
            else if (order.trade_type == "NATIVE")
            {
                //當 trade_type=NATIVE 時必輸入
                sParams.Add("product_id", order.product_id);
            }
            sParams.Add("out_trade_no", order.out_trade_no);
            sParams.Add("spbill_create_ip", order.spbill_create_ip);
            sParams.Add("total_fee", order.total_fee);
            sParams.Add("trade_type", order.trade_type);
            order.sign = getsign(sParams, key);
            sParams.Add("sign", order.sign);
           
            //拼接成XML請求數據
            StringBuilder sbPay = new StringBuilder();
            foreach (KeyValuePair<string, object> k in sParams)
            {
                if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
                {
                    sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">");
                }
                else
                {
                    sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">");
                }
            }
            return_string = string.Format("<xml>{0}</xml>", sbPay.ToString());
            byte[] byteArray = Encoding.UTF8.GetBytes(return_string);
            return_string = Encoding.GetEncoding("GBK").GetString(byteArray);
            Byte[] temp = Encoding.UTF8.GetBytes(return_string);
            string dataGBK = Encoding.GetEncoding("utf-8").GetString(temp);         
            return return_string;
            //  GBK
        }

        #endregion

        #region 微信訂單查詢接口XML參數整理
        /// <summary>
        /// 微信訂單查詢接口XML參數整理
        /// </summary>
        /// <param name="queryorder">微信訂單查詢參數實例</param>
        /// <param name="key">密鑰</param>
        /// <returns></returns>
        protected string getQueryOrderXml(string out_trade_no)
        {
            string return_string = string.Empty;
            SortedDictionary<string, object> sParams = new SortedDictionary<string, object>();
            sParams.Add("appid", WXconfig.appid);
            sParams.Add("mch_id", WXconfig.mch_id);
           // sParams.Add("transaction_id", queryorder.transaction_id);
            sParams.Add("out_trade_no", out_trade_no);
            sParams.Add("nonce_str", getNoncestr());
           string  sign = getsign(sParams, WXconfig.paysignkey);
            sParams.Add("sign", sign);

            //拼接成XML請求數據
            StringBuilder sbPay = new StringBuilder();
            foreach (KeyValuePair<string, object> k in sParams)
            {
                if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
                {
                    sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">");
                }
                else
                {
                    sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">");
                }
            }
            return_string = string.Format("<xml>{0}</xml>", sbPay.ToString().TrimEnd(','));
            return return_string;
        }
        #endregion 

        #endregion
    }
        
        public class MD5Util
    {

        public MD5Util() { 
         //
            // TODO: 在此處添加構造函數邏輯
            //
        }
        /// <summary>
        /// /** 獲取大寫的MD5簽名結果 */
        /// </summary>
        /// <param name="encypStr">數據</param>
        /// <param name="charset">編碼格式</param>
        /// <returns></returns>
 
        
        public static string GetMD5(string encypStr, string charset)
        {
            string retStr;
            MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();

            //創建md5對象
            byte[] inputBye;
            byte[] outputBye;

            //使用GB2312編碼方式把字符串轉化爲字節數組.
            try
            {
                inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
            }
            catch (Exception ex)
            {
                inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
            }
            outputBye = m5.ComputeHash(inputBye);

            retStr = System.BitConverter.ToString(outputBye);
            retStr = retStr.Replace("-", "").ToUpper();
            return retStr;
        }
        /// <summary>
        /// SHA1加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string sha1(string str)
        {
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "sha1").ToLower();
        }

       

    }



1.1   獲取掃碼支付的結果接口(建議輪番獲取狀態)

請求方式:http get

 

接口參數說明

名稱

類型

必填

說明

out_trade_no

String

支付訂單ID

 

 

返回結果: code :1//支付成功

返回結果: code :2//未支付

返回結果: code :3//用戶支付中

返回結果: code :4//支付失敗

返回結果: code :0//其他狀態

返回結果: code :-1,Message="錯誤信息"//系統異常

 返回結果: code :-2//訂單號不能爲空

備註:(code 不爲-11,-2的時候輪番調取接口,建議時間爲1s~2s,-1的時候,提示系統異常,聯繫管理員。爲1的時候跳到完成頁面。)


訂單查詢說明:微信支付雖然有回調(個人認爲比較坑),這裏我是用了自己支付訂單號去查詢微信支付的該訂單狀態。(微信文檔有說明,有2個方式,一個回調,一個用支付訂單查詢訂單狀態)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章