/// <summary>
        /// 退款
        /// </summary>
        /// <param name="key">商户API key</param>
        /// <param name="cert_subjectName">商户证书主体名</param>
        /// <returns></returns>
        public async Task <bool> GetRefund(string key, string cert_subjectName)
        {
            var dicProperties = ToDicHelper.GetPropertiesFromObj(this);

            dicProperties.Remove(nameof(timeStamp));
            //拼接成XML请求数据
            StringBuilder sbPay = new StringBuilder();

            foreach (KeyValuePair <string, string> k in dicProperties)
            {
                sbPay.Append($"<{ k.Key }><![CDATA[{ k.Value }]]></{ k.Key }>");
            }
            sbPay.Append($"<sign>{GetSign(dicProperties, key)}</sign>");
            string post_string = string.Format($"<xml>{sbPay.ToString()}</xml>");
            var    handler     = new HttpClientHandler
            {
                ClientCertificateOptions = ClientCertificateOption.Manual,
                SslProtocols             = SslProtocols.Tls12
            };
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);

            store.Open(OpenFlags.ReadOnly);
            foreach (var cert in store.Certificates)
            {
                if (cert.SubjectName.Name == cert_subjectName)
                {
                    handler.ClientCertificates.Add(cert);
                }
            }
            using (HttpClient client = new HttpClient(handler))
            {
                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/xml"));
                var response = await client.PostAsync(RefundUrl, new StringContent(post_string, Encoding.UTF8));

                if (response.IsSuccessStatusCode)
                {
                    var res = GetInfoFromXml(await response.Content.ReadAsStringAsync());
                    if (res["return_code"] == "SUCCESS")
                    {
                        if (res["result_code"] == "SUCCESS")
                        {
                            return(true);
                        }
                        else
                        {
                            throw new Exception($"{res["err_code"]} : {res["err_code_des"]}");
                        }
                        //prepay_id = res["prepay_id"];
                    }
                    else
                    {
                        throw new Exception(res["return_msg"]);
                    }
                }
                return(false);
            }
        }
        /// <summary>
        /// 获取微信返回的预付单信息
        /// </summary>
        /// <param name="amount"></param>
        /// <returns></returns>
        public async Task <WeChatPayReturnModel> GetWeChatPay(string key)
        {
            var dicProperties = ToDicHelper.GetPropertiesFromObj(this);

            dicProperties.Remove(nameof(timeStamp));
            //拼接成XML请求数据
            StringBuilder sbPay = new StringBuilder();

            //sbPay.Append(@"<?xml version=""1.0"" encoding=""utf - 8""?>");
            foreach (KeyValuePair <string, string> k in dicProperties)
            {
                //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 }>");
                //}
                sbPay.Append($"<{ k.Key }><![CDATA[{ k.Value }]]></{ k.Key }>");
            }
            sbPay.Append($"<sign>{GetSign(dicProperties, key)}</sign>");
            string post_string = string.Format($"<xml>{sbPay.ToString()}</xml>");
            //发起请求,获取预付订单
            string prepay_id = "";

            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/xml"));
                var response = await client.PostAsync(UnifiedPayUrl, new StringContent(post_string, Encoding.UTF8));

                if (response.IsSuccessStatusCode)
                {
                    var res = GetInfoFromXml(await response.Content.ReadAsStringAsync());
                    if (res["return_code"] == "SUCCESS")
                    {
                        prepay_id = res["prepay_id"];
                    }
                    else
                    {
                        throw new Exception(res["return_msg"]);
                    }
                }
            }

            WeChatPayReturnModel result = new WeChatPayReturnModel()
            {
                NonceStr = nonce_str,
                AppId    = appid,
                Package  = "prepay_id=" + prepay_id,
            };
            //timeStamp = int.Parse(result.TimeStamp);

            //计算签名
            SortedDictionary <string, string> paysign = new SortedDictionary <string, string>
            {
                { "appId", appid },
                { "nonceStr", result.NonceStr },
                { "package", result.Package },
                { "signType", result.SignType },
                { "timeStamp", result.TimeStamp },
            };

            result.PaySign = GetSign(paysign, key);
            return(result);
        }