APP接入微信支付(三)-- 服务端集成


本文问主要介绍接入微信支付中服务端的代码集成过程,运用的开发工具为VS(Visual Studio)。我用的是微信支付之前的接口,不是V3的。Http请求方式为post,参数格式为xml(官网说明文档)

一、调用微信支付统一下单接口。在APP选择微信支付的接口中调用如下方法

        //微信支付
        public static string wxpay(string totalAmount, string simChargeMsg) {

            totalAmount = (float.Parse(totalAmount) * 100).ToString();//微信支付的金额单位为分,所以先将金额元转换为分
            //统一下单
            string WebUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";//换成接收方的URL
            //统一下单参数
            Dictionary dic = new Dictionary();
            dic.Add("appid", WXPay_APPID);//APPID
            dic.Add("attach", simChargeMsg); //支付信息
            dic.Add("body", "商品描述");
            dic.Add("mch_id", WXPay_MchID);//商户号
            dic.Add("nonce_str", CreatenNonce_str());//随机数生成
            dic.Add("notify_url", "https://pay.weixin.qq.com/wxpay/pay.action");//通知地址
            dic.Add("out_trade_no", DateTime.Now.ToString("yyyyMMddHHmmss"));//商户订单号 要求统一商户号下唯一,所以我设置为当前时间
            dic.Add("total_fee", totalAmount);//总金额 单位为分
            dic.Add("trade_type", "APP"); //交易类型 APP
            //根据当前添加的参数生成签名
            string signValue = GetSignature(dic);  
            //添加参数 签名
            dic.Add("sign", signValue);
            //网络请求
            string res = wxRequestUrl(WebUrl, wxGetXml(dic));//wxGetXml() 生成xml型参数
            
            var doc = new System.Xml.XmlDocument(); //实例化XmlDocument
            doc.LoadXml(res);//解析请求结果数据
            XmlNode xml_node = doc.SelectSingleNode("xml");


            if (xml_node != null  && xml_node.SelectSingleNode("result_code")!= null  && xml_node.SelectSingleNode("result_code").InnerText == "SUCCESS")
            {
                //请求成功时   将返回参数整理生成Json字符串传递给APP
                Dictionary dic01 = new Dictionary();
                dic01.Add("appid", xml_node.SelectSingleNode("appid").InnerText);//APPID
                dic01.Add("timestamp", CreatenTimestamp().ToString());//时间戳
                dic01.Add("noncestr", CreatenNonce_str());//随机字符串
                dic01.Add("prepayid", xml_node.SelectSingleNode("prepay_id").InnerText);//预支付交易会话id
                dic01.Add("partnerid", xml_node.SelectSingleNode("mch_id").InnerText);//商户号
                dic01.Add("package", "Sign=WXPay");

                dic01.Add("sign", GetSignature(dic01));//根据参数生成签名 并加入到参数中

                string json = JsonConvert.SerializeObject(dic01); //生成Json字符串
                return json;
            }
            return "微信支付失败";
        }

    其中的的随机数生成、时间戳、生成XML参数、发送网络请求、签名方法会在下面展示。参数说明

二、随机数生成

        private static string[] strs = new string[]
               {
                "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",
                "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"
               };
        //16位随机数生成
        public static string CreatenNonce_str()
        {
            Random r = new Random();
            var sb = new StringBuilder();
            var length = strs.Length;
            for (int i = 0; i < 16; i++)
            {
                sb.Append(strs[r.Next(length - 1)]);
            }
            return sb.ToString();
        }

三、时间戳

        //时间戳
        public static long CreatenTimestamp()
        {
            return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }

四、生成XML参数

        public static string wxGetXml(Dictionary dic)//要发送的XML
        {
            StringBuilder strBuilder = new StringBuilder();

            strBuilder.Append("");
            foreach (string key in dic.Keys)
            {
                strBuilder.Append("<" + key + ">" + dic[key] + "");
            }
            strBuilder.Append("");
            return strBuilder.ToString();
        }

五、发送网络请求

        public static string wxRequestUrl(string url, string data)
        {

            var request = WebRequest.Create(url);
            request.Method = "post";
            request.ContentType = "text/xml";
            request.Headers.Add("charset:utf-8");
            var encoding = Encoding.GetEncoding("utf-8");

            if (data != null)
            {
                byte[] buffer = encoding.GetBytes(data);
                request.ContentLength = buffer.Length;
                request.GetRequestStream().Write(buffer, 0, buffer.Length);
            }
            else
            {
                request.ContentLength = 0;
            }

            using (HttpWebResponse wr = request.GetResponse() as HttpWebResponse)
            {
                using (StreamReader reader = new StreamReader(wr.GetResponseStream(), encoding))
                {
                    return reader.ReadToEnd();
                }
            }
        }

六、签名

        //签名算法
        public static string GetSignature(Dictionary dic)
        {
            //第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序
            List list = new List();

            foreach (string key in dic.Keys)
            {
                list.Add(key + "=" + dic[key]);
            }

            list.Sort();
            String stringA = String.Join("&", list);
            //第二步:拼接API密钥,WXPay_V2Key是在微信商户平台上设置的API秘钥
            String stringSignTemp = stringA + "&key="+WXPay_V2Key;
            //第三步:MD5加密生成签名
            String sign = md5Password(stringSignTemp.ToString());
            return sign;
        }

        //MD5加密算法
        public static String md5Password(String key)
        {
            var md5 = MD5.Create();
            var bytValue = Encoding.UTF8.GetBytes(key);
            var bytHash = md5.ComputeHash(bytValue);
            var sb = new StringBuilder();
            foreach (var b in bytHash)
            {
                sb.Append(b.ToString("X2"));
            }
            return sb.ToString().ToUpper();//换成大写
        }

相关