Asp.net Core 微信小程序支付


最近要做一個微信小程序支付的功能 在網上找了一下 .net Core做微信支付的博客 和 demo 幾乎沒有 

自己研究了好幾天 參考了 很多 大牛的博客 勉強做出來了  因為參數都沒有 比如 opid 小程序域名 所以只是簡單的測了一下 模擬了微信支付的回調請求 后續等項目上線 會回來填坑的 

第一次看小程序支付的api文檔 看得我一臉懵逼 現在簡單說一下吧 先上一個官方圖 

小程序支付的流程是這樣的 首先 用戶下單 然后后台生成訂單 調用統一支付api(注意這並不是支付 只是算一個預下單 通知下微信 我要掏錢了 你給我幾個參數)  然后 統一下單API回返回給你五個參數 把五個參數和簽名返回給前端 由前端來下單 

然后用戶確認支付之后 會有一個微信的異步回調

(此處調用統一下單需要用的opid 在微信登錄那一塊 不做贅述) 

關於統一下單

構造下單參數  -- 調用API接口 -- 處理返回結果 -- 返回給前端

首先 構造統一下單的所需要的參數

然后發送Http請求  接收返回的結果

然后將五個參數返回給前台。

 微信支付回調也是

拿到微信返回的支付數據 解析數據 處理業務

這里需要注意 core 的接收方式

ok 這里先總結一下 等到測試完 沒問題 回來填坑 並附上完整代碼

完成代碼

 public class WeChatPayHelper
    {
        private static readonly Logger _logger = LogManager.GetCurrentClassLogger();

        public PayRequesEntity Unifiedorder(string openid, string totalfee, string orderNo)
        {
            //var PayUrl = AppSetting.Load().WechatPayStrings.FirstOrDefault().UnifiedorderURL;
            //獲取統一下單參數
            var param = GetUnifiedOrderParam(openid, orderNo, totalfee);
            _logger.Info(() => "微信支付統一下單 發送參數為 "+param+"");
            //統一下單后拿到的xml結果
            var payResXML = HttpMethods.Post(AppSetting.Load().WechatPayStrings.FirstOrDefault().UnifiedorderURL, param);
            _logger.Info(() => "微信支付統一下單 返回參數為 " + payResXML + "");
            var payRes = XDocument.Parse(payResXML);
            var root = payRes.Element("xml");
            var res = GetPayRequestParam(root);
            _logger.Info(() => "微信支付統一下單 參數實體為 " + JsonConvert.SerializeObject(res) + "");
            return res;
        }


        /// <summary>
        /// 取統一下單的請求參數
        /// </summary>
        /// <param name="openid"></param>
        /// <returns></returns>
        private string GetUnifiedOrderParam(string openid,string orderNo, string totalfee)
        {
            string appid = AppSetting.Load().WechatStrings.FirstOrDefault().APPID;
            string secret = AppSetting.Load().WechatStrings.FirstOrDefault().SECRET;
            string mch_id = AppSetting.Load().WechatPayStrings.FirstOrDefault().Mch_ID;
            string ip = AppSetting.Load().Configurations.FirstOrDefault().IP;
            string PayResulturl = AppSetting.Load().WechatPayStrings.FirstOrDefault().PayResulturl;

            string strcode = "益謙文化小程序-微信支付購買";////商品描述交易字段格式根據不同的應用場景按照以下格式:APP——需傳入應用市場上的APP名字-實際商品名稱,天天愛消除-游戲充值。
            byte[] buffer = Encoding.UTF8.GetBytes(strcode);
            string body = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            System.Random Random = new System.Random();
            var dic = new Dictionary<string, string>
                {
                    {"appid", appid},
                    {"mch_id", mch_id},
                    {"nonce_str", GetRandomString(20)/*Random.Next().ToString()*/},
                    {"body",body},
                    {"out_trade_no",orderNo},//商戶自己的訂單號碼
                    {"total_fee",totalfee},
                    {"spbill_create_ip",ip},//服務器的IP地址
                    {"notify_url",PayResulturl},//異步通知的地址,不能帶參數
                    {"trade_type","JSAPI" },
                    {"openid",openid}
                };
            //加入簽名
            dic.Add("sign", GetSignString(dic));

            var sb = new StringBuilder();
            sb.Append("<xml>");
            foreach (var d in dic)
            {
                sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
            }
            sb.Append("</xml>");
            return sb.ToString();
        }


        /// <summary>
        /// 獲取返回給小程序的支付參數
        /// </summary>
        /// <param name="root"></param>
        /// <param name="appid"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        private PayRequesEntity GetPayRequestParam(XElement root)
        {           
            string appid = AppSetting.Load().WechatStrings.FirstOrDefault().APPID;
            //當return_code 和result_code都為SUCCESS時才有我們要的prepay_id
            if (root.Element("return_code").Value == "SUCCESS" && root.Element("result_code").Value == "SUCCESS")
            {
                var res = new Dictionary<string, string>
                {
                    {"appId", appid},
                    {"timeStamp", Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds).ToString()},
                    {"nonceStr", GetRandomString(20)},
                    {"package",  "prepay_id=" + root.Element("prepay_id").Value},
                    {"signType", "MD5"}
                };
                //在服務器上簽名
                res.Add("paySign", GetSignString(res));

                var payEntity = new PayRequesEntity
                {
                    package = res["package"],
                    nonceStr = res["nonceStr"],
                    paySign = res["paySign"],
                    signType = res["signType"],
                    timeStamp = res["timeStamp"]
                };
                return payEntity;
            }

            return new PayRequesEntity();
        }


        /// <summary>
        /// 從字符串里隨機得到,規定個數的字符串.
        /// </summary>
        /// <param name="allChar"></param>
        /// <param name="CodeCount"></param>
        /// <returns></returns>
        private static string GetRandomString(int CodeCount)
        {
            string allChar = "1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,i,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
            string[] allCharArray = allChar.Split(',');
            string RandomCode = "";
            int temp = -1;
            Random rand = new Random();
            for (int i = 0; i < CodeCount; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(temp * i * ((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(allCharArray.Length - 1);
                while (temp == t)
                {
                    t = rand.Next(allCharArray.Length - 1);
                }
                temp = t;
                RandomCode += allCharArray[t];
            }

            return RandomCode;
        }


        private string GetSignString(Dictionary<string, string> dic)
        {
            string key = AppSetting.Load().WechatPayStrings.FirstOrDefault().WxPayKey;//商戶平台 API安全里面設置的KEY  32位長度                                                                                                            
            dic = dic.OrderBy(d => d.Key).ToDictionary(d => d.Key, d => d.Value);//排序
            //連接字段
            var sign = dic.Aggregate("", (current, d) => current + (d.Key + "=" + d.Value + "&"));
            sign += "key=" + key;
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
            sign = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(sign))).Replace("-", null);
            return sign;
        }



        private static Object PostUnifiedOrder(string payUrl, string para)
        {
            string result = string.Empty;
            try
            {
                HttpClient client = new HttpClient();
                HttpContent httpContent = new StringContent(para);
                httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                httpContent.Headers.ContentType.CharSet = "utf-8";
                HttpResponseMessage hrm = client.PostAsync(payUrl, httpContent).Result;
                return hrm;
            }
            catch (Exception e)
            {
                result = e.Message;
            }
            return result;
        }
}

 

public class PayRequesEntity
    {
        /// <summary>
        /// 時間戳從1970年1月1日00:00:00至今的秒數,即當前的時間
        /// </summary>
        public string timeStamp { get; set; }

        /// <summary>
        /// 隨機字符串,長度為32個字符以下。
        /// </summary>
        public string nonceStr { get; set; }

        /// <summary>
        /// 統一下單接口返回的 prepay_id 參數值
        /// </summary>
        public string package { get; set; }

        /// <summary>
        /// 簽名算法
        /// </summary>
        public string signType { get; set; }

        /// <summary>
        /// 簽名
        /// </summary>
        public string paySign { get; set; }
    }

 


免責聲明!

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



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