c# 小程序微信支付


微信支付步驟:

1.小程序后台下單 生成訂單號

//獲取商品價格
                decimal shop_money = Convert.ToDecimal(shop_info.Rows[0]["money"]);
                //獲取商品名稱
                string title = shop_info.Rows[0]["title"].ToString();
                //計算訂單金額
                decimal money = shop_money * Convert.ToDecimal(shop_num);
                //獲取當前時間的時間戳
                DateTime time = DateTime.Now;
                double set_time = TimeHelper.ConvertDateTimeToS(time);
                //獲取商品id 
                int id = shop_id;
                //獲取訂單狀態
                int pay_state = Convert.ToInt32(0);
                Random ran = new Random();
                //訂單號
                string num = DateTime.Now.ToString("yyMMddHHmmssfff") + ran.Next(1000, 9999).ToString();
                //獲取商品類型
                int shop_type = Convert.ToInt32(shop_info.Rows[0]["shop_type"]);
                //獲取商品組合個數
                int gro_num = Convert.ToInt32(shop_info.Rows[0]["gro_num"]);
                //獲取商品名稱
                //添加訂單信息

  2.調用自定義方法  微信下單

 

 /// <summary>
        /// 微信下單
        /// </summary>
        /// <param name="title">商品名稱</param>
        /// <param name="num">訂單號</param>
        /// <param name="money">訂單金額</param>
        /// <param name="user_id">用戶id</param>
        /// <returns></returns>
        public DataTable wechat_payment(string title, string num, decimal money, int user_id)
        {
            string signType = "";
            string nonceStr = "";
            string timeStamp = "";
            string package = "";
            string appId = "";
            string paySign = "";
            DataTable aa = new DataTable();//可以給表創建一個名字,tb
            try
            {
                //根據id查詢用戶openid
                BLL.wx_yxt_user wx_yxt_user = new BLL.wx_yxt_user();
                DataTable user_info = wx_yxt_user.get_user_info(user_id);
                string openid =user_info.Rows[0]["wx_openid"].ToString(); //;


                //附加數據
                var _attach = "支付";
                //商品描述
                var _body = title;
                //隨機字符串
                random_number random = new random_number();
                var _nonce_str = random.Generate_nonce(15);
                //回調地址
                var _notify_url = wechatConfig.wx_asyn_call_url;
                //商戶訂單號
                var _out_trade_no = num;
                //終端IP
                var _spbill_create_ip = GetWebClientIp();
                //訂單金額
                var _total_fee = Convert.ToDouble(money);//元為單位             
                var _trade_type = "JSAPI";//交易類型
                                          //設備號
                var _scene_info = $@"{{""h5_info"": {{""type"":""Wap"",""wap_url"": ""{_notify_url}"",""wap_name"": ""{_body}""}}}}";
                //交易起始時間
                var _time_start = DateTime.Now.ToString("yyyyMMddHHmmss");
                //交易結束時間
                var _time_expire = DateTime.Now.AddHours(1).ToString("yyyyMMddHHmmss");
                var sign_type = "MD5";
                //下單
                var pre_order_httpResult = UnifiedOrder(_appid, _attach, _body, _mch_id, _nonce_str, _notify_url, _out_trade_no, _spbill_create_ip, _total_fee,
                    _trade_type, _scene_info, _time_start, _time_expire, sign_type, openid);
                var pre_order_resultStr = XElement.Parse(pre_order_httpResult);
                var pre_order_result_code = pre_order_resultStr.Element("return_code").Value;
                var pre_order_result_msg = pre_order_resultStr.Element("return_msg").Value;

                aa.Columns.Add("signType", typeof(System.String));//類型是可以變換的,比如System.Int32,System.Double..
                aa.Columns.Add("nonce_str", typeof(System.String));
                aa.Columns.Add("timeStamp", typeof(System.String));
                aa.Columns.Add("package", typeof(System.String));
                aa.Columns.Add("appId", typeof(System.String));
                aa.Columns.Add("paySign", typeof(System.String));
                if (pre_order_result_code == "SUCCESS")
                {
                    signType = "MD5";
                    nonceStr = pre_order_resultStr.Element("nonce_str").Value;
                    ///秒
                    TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                    string ts = Convert.ToInt64(t.TotalSeconds).ToString();
                    timeStamp = ts;
                    package = pre_order_resultStr.Element("prepay_id").Value;
                    appId = pre_order_resultStr.Element("appid").Value;
                    var stringADict = new Dictionary<string, string>();
                    stringADict.Add("signType", signType);
                    stringADict.Add("nonceStr", nonceStr);
                    stringADict.Add("timeStamp", timeStamp);
                    stringADict.Add("package", "prepay_id=" + package);
                    stringADict.Add("appId", appId);
                    paySign = Sign(stringADict, _partnerKey);
                    DataRow row = aa.NewRow();
                    row["signType"] = signType;
                    row["nonce_str"] = nonceStr;
                    row["timeStamp"] = timeStamp;
                    row["package"] = package;
                    row["appId"] = appId;
                    row["paySign"] = paySign;
                    aa.Rows.Add(row);
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error("WeChatIndex", ex);
            }

            return aa;
        }

  

  /// <summary>
        /// 下單
        /// </summary>
        /// <param name="appid">公眾賬號ID</param>
        /// <param name="attach">附加數據,在查詢API和支付通知中原樣返回,該字段主要用於商戶攜帶訂單的自定義數據</param>
        /// <param name="body">String(32) 商品描述 商品或支付單簡要描</param>
        /// <param name="mch_id">商戶號</param>
        /// <param name="nonce_str">隨機字符串</param>
        /// <param name="notify_url">接收微信支付異步通知回調地址,不可帶參,與下面的Notify對應,開發者可自定義其他url地址 </param>
        /// <param name="out_trade_no">商戶系統內部的訂單號,32個字符內、可包含字母</param>
        /// <param name="spbill_create_ip">終端ip</param>
        /// <param name="total_fee">收錢總額  分為單位 前台傳過來后需要處理成分</param>
        /// <param name="trade_type">交易類型H5支付的交易類型為MWEB</param>
        /// <param name="scene_info">場景信息 WAP網站應用{"h5_info": {"type":"Wap","wap_url": "https://pay.qq.com","wap_name": "騰訊充值"}}</param>
        /// <param name="time_start">交易起始時間</param>
        /// <param name="time_expire">交易結束時間</param>
        /// <returns></returns>
        static string UnifiedOrder(string appid, string attach, string body, string mch_id, string nonce_str, string notify_url, string out_trade_no,
            string spbill_create_ip, double total_fee, string trade_type, string scene_info, string time_start, string time_expire, string sign_type, string openid)
        {
            var pre_order_httpResult = "";
            try
            {
                var stringADict = new Dictionary<string, string>();
                stringADict.Add("appid", appid);
                stringADict.Add("attach", attach);
                stringADict.Add("body", body);
                stringADict.Add("mch_id", mch_id);
                stringADict.Add("nonce_str", nonce_str);
                stringADict.Add("notify_url", notify_url);
                stringADict.Add("out_trade_no", out_trade_no);
                stringADict.Add("openid", openid);
                stringADict.Add("spbill_create_ip", spbill_create_ip);
                stringADict.Add("total_fee", Math.Round(Convert.ToDecimal(total_fee) * 100, 0).ToString());//元轉分
                stringADict.Add("trade_type", trade_type);
                stringADict.Add("scene_info", scene_info);
                stringADict.Add("time_start", time_start);
                stringADict.Add("time_expire", time_expire);
                stringADict.Add("sign_type", sign_type);
                var sign = Sign(stringADict, _partnerKey);//生成簽名字符串  

                //組合xml內容
                StringBuilder strBuilder = new StringBuilder();
                strBuilder.Append("<xml>");
                strBuilder.Append($"<appid>{appid}</appid>");//公眾號id  
                strBuilder.Append($"<attach>{attach}</attach>");//附加數據
                strBuilder.Append($"<body>{body}</body>");//商品描述
                strBuilder.Append($"<mch_id>{mch_id}</mch_id>");//商戶號  
                strBuilder.Append($"<nonce_str>{nonce_str}</nonce_str>");//隨機字符串  
                strBuilder.Append($"<notify_url>{notify_url}</notify_url>");//接收微信支付異步通知回調地址,不可帶參,與下面的Notify對應,開發者可自定義其他url地址  
                strBuilder.Append($"<out_trade_no>{out_trade_no}</out_trade_no>");//商戶系統內部的訂單號,32個字符內、可包含字母   
                strBuilder.Append($"<openid>{openid}</openid>");
                strBuilder.Append($"<spbill_create_ip>{spbill_create_ip}</spbill_create_ip>");//終端ip  
                strBuilder.Append($"<total_fee>{Math.Round(Convert.ToDecimal(total_fee) * 100, 0).ToString()}</total_fee>");//收錢總額  分為單位 前台傳過來后需要處理成分  
                strBuilder.Append($"<trade_type>{trade_type}</trade_type>");//交易類型H5支付的交易類型為MWEB  
                strBuilder.Append($"<scene_info>{scene_info}</scene_info>");
                strBuilder.Append($"<time_start>{time_start}</time_start>");//交易起始時間
                strBuilder.Append($"<time_expire>{time_expire}</time_expire>");//交易結束時間
                strBuilder.Append($"<sign>{sign}</sign>");
                strBuilder.Append($"<sign_type>{sign_type}</sign_type>");
                strBuilder.Append("</xml>");

                //var url = _pre_order_url + "/sandboxnew/pay/unifiedorder";//沙箱
                var url = "https://api.mch.weixin.qq.com/" + "pay/unifiedorder";
                pre_order_httpResult = HttpPostRequestXml(url, strBuilder);
            }
            catch (Exception ex)
            {
                NLogHelper.Error("UnifiedOrder", ex);
            }

            return pre_order_httpResult;
        }

  3.向微信發送post xml文件請求 返回成功失敗提示

 /// <summary>
        /// 發送post xml文件請求
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="strBuilder"></param>
        /// <returns></returns>
        static string HttpPostRequestXml(string Url, StringBuilder strBuilder)
        {
            string result = string.Empty;
            try
            {
                string data = strBuilder.ToString();
                //進行utf-8編碼
                var encoding = Encoding.GetEncoding("utf-8");
                byte[] buffer = encoding.GetBytes(data);
                //根據webURL創建HttpWebRequest對象
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
                request.Method = "post";
                //request.Headers.Add("charset:utf-8");            
                request.ContentLength = buffer.Length;
                request.ContentType = "text/xml";

                StreamWriter myWriter = null;
                try
                {
                    myWriter = new StreamWriter(request.GetRequestStream());
                    myWriter.Write(data);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    myWriter.Close();
                }
                //讀取服務器返回的信息
                HttpWebResponse objResponse = (HttpWebResponse)request.GetResponse();
                using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
                {
                    result = sr.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error("HttpPostRequestXml", ex);
            }

            return result;
        }

  

自定義方法  獲取終端IP地址  

 /// <summary>  
        /// 獲取終端IP地址  
        /// </summary>  
        /// <returns></returns>  
        public static string GetWebClientIp()
        {
            string userIP = "";
            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 simone 090805  
                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;
        }

  自定義方法   生成簽名

 /// <summary>  
        /// 生成簽名  
        /// 簽名在線驗證工具:  
        /// http://mch.weixin.qq.com/wiki/tools/signverify/  
        /// </summary>  
        /// <param name="stringADict">參與簽名生成的參數列表</param>  
        /// <param name="partnerKey">商家私鑰</param>  
        /// <returns></returns>  
        public static string Sign(IDictionary<string, string> stringADict, string partnerKey)
        {
            var sign = "";
            try
            {
                var sb = new StringBuilder();
                foreach (var sA in stringADict.OrderBy(x => x.Key))//參數名ASCII碼從小到大排序(字典序);  
                {
                    if (string.IsNullOrEmpty(sA.Value)) continue;//參數的值為空不參與簽名;  
                    if (string.Compare(sA.Key, "sign", true) == 0) continue;    // 參數中為簽名的項,不參加計算  
                    sb.Append(sA.Key).Append("=").Append(sA.Value).Append("&");
                }
                var string1 = sb.ToString();
                string1 = string1.Remove(string1.Length - 1, 1);
                sb.Append("key=").Append(partnerKey);//在stringA最后拼接上key=(API密鑰的值)得到stringSignTemp字符串  
                var stringSignTemp = sb.ToString();
                // var sign = MD5Encrypt(stringSignTemp, "UTF-8").ToUpper();//對stringSignTemp進行MD5運算,再將得到的字符串所有字符轉換為大寫,得到sign值signValue。   
                sign = MD5Encrypt(stringSignTemp, "UTF-8").ToUpper();//對stringSignTemp進行MD5運算,再將得到的字符串所有字符轉換為大寫,得到sign值signValue。 
            }
            catch (Exception ex)
            {

                NLogHelper.Error("Sign", ex);
            }

            return sign;
        }

  

自定義方法  MD5加密

 

    /// <summary>
        /// 用MD5加密字符串
        /// </summary>
        /// <param name="password">待加密的字符串</param>
        /// <returns></returns>
        public static string MD5Encrypt(string password, string encoding)
        {
            MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
            byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(password));

            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }
            return sBuilder.ToString();
        }

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM