/**
         *
         * 查询订单
         * @param WxPayData inputObj 提交给查询订单API的参数
         * @param int timeOut 超时时间
         * @throws WxPayException
         * @return 成功时返回订单查询结果,其他抛异常
         */
        public static WxPayData OrderQuery(WxPayData inputObj, int timeOut = 6)
        {
            string url = "https://api.mch.weixin.qq.com/pay/orderquery";

            //检测必填参数
            if (!inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id"))
            {
                throw new WxPayException("订单查询接口中,out_trade_no、transaction_id至少填一个!");
            }

            inputObj.SetValue("appid", WxPayConfig.APPID);                 //公众账号ID
            inputObj.SetValue("mch_id", WxPayConfig.MCHID);                //商户号
            inputObj.SetValue("nonce_str", RandHelper.GenerateNonceStr()); //随机字符串
            inputObj.SetValue("sign", inputObj.MakeSign());                //签名

            string xml = inputObj.ToXml();

            var start = DateTime.Now;

            var    requestResult = CoreHelper.GetHttpResult(url, xml, contentType: KeyModel.ContentType.Xml);
            string response      = requestResult.Obj; // HttpService.Post(xml, url, false, timeOut);


            var end      = DateTime.Now;
            int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时

            //将xml格式的数据转化为对象以返回
            WxPayData result = new WxPayData();

            result.FromXml(response);

            return(result);
        }
        /// <summary>
        /// 支付宝表单提交字符串
        /// </summary>
        public string FormHtml(out string tradeNo)
        {
            tradeNo = RandHelper.GenerateNonceStr();

            StringBuilder build = new StringBuilder();

            //把请求参数打包成数组
            SortedDictionary <string, string> sParaTemp = new SortedDictionary <string, string>();

            sParaTemp.Add("service", StringHelper.Get(this.ServiceName));                               //调用的接口名,无需修改
            sParaTemp.Add("partner", StringHelper.Get(this.PartnerNo));                                 // 合作身份者ID,签约账号,以2088开头由16位纯数字组成的字符串,查看地址:https://b.alipay.com/order/pidAndKey.htm
            sParaTemp.Add("seller_id", StringHelper.Get(this.SellerId));                                // 收款支付宝账号,以2088开头由16位纯数字组成的字符串,一般情况下收款账号就是签约账号
            sParaTemp.Add("_input_charset", StringHelper.Get(this.InputCharset));                       // 字符编码格式 目前支持 gbk 或 utf-8
            sParaTemp.Add("payment_type", "1");                                                         // 支付类型 ,无需修改
            sParaTemp.Add("notify_url", StringHelper.Get(this.NotifyUrl));                              // 服务器异步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
            sParaTemp.Add("return_url", StringHelper.Get(this.ReturnUrl));                              // 页面跳转同步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问

            #region 防调鱼配置

            ////↓↓↓↓↓↓↓↓↓↓请在这里配置防钓鱼信息,如果没开通防钓鱼功能,请忽视不要填写 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
            ////防钓鱼时间戳  若要使用请调用类文件submit中的Query_timestamp函数
            //public static string anti_phishing_key = "";
            ////客户端的IP地址 非局域网的外网IP地址,如:221.0.0.1
            //public static string exter_invoke_ip = "";
            ////↑↑↑↑↑↑↑↑↑↑请在这里配置防钓鱼信息,如果没开通防钓鱼功能,请忽视不要填写 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
            sParaTemp.Add("anti_phishing_key", "");
            sParaTemp.Add("exter_invoke_ip", "");

            #endregion

            sParaTemp.Add("out_trade_no", StringHelper.Get(tradeNo));
            sParaTemp.Add("subject", StringHelper.Get(this.Subject));                           //商品名称
            sParaTemp.Add("total_fee", StringHelper.Get(this.Money));
            sParaTemp.Add("body", StringHelper.Get(this.Body));
            sParaTemp.Add("extra_common_param", StringHelper.Get(this.ExtraCommonParam));


            //对参数进行过滤排序及生成字符串
            Dictionary <string, string> par = FilterPara(sParaTemp);
            string prestr = CreateLinkString(par);

            par.Add("sign", AlipayMd5Sign(prestr, StringHelper.Get(this.Key), StringHelper.Get(this.InputCharset)));
            par.Add("sign_type", "MD5"); // 签名方式


            //构造请求信息
            build.Append("<form id='alipaysubmit' name='alipaysubmit' action='" + StringHelper.Get(this.Gateway) + "_input_charset=" + StringHelper.Get(this.InputCharset) + "' method='GET'>");
            foreach (KeyValuePair <string, string> temp in par)
            {
                build.Append("<input type='hidden' name='" + temp.Key + "' value='" + temp.Value + "'/>");
            }
            build.Append("<input type='submit' value='确认' style='display:none;'></form>");
            build.Append("<script>document.forms['alipaysubmit'].submit();</script>");

            //submit按钮控件请不要含有name属性
            return(build.ToString());
        }
        /**
         * 生成扫描支付模式一URL
         * @param productId 商品ID
         * @return 模式一URL
         */
        public static string GetPrePayUrl(string productId)
        {
            WxPayData data = new WxPayData();

            data.SetValue("appid", WxPayConfig.APPID);                 //公众帐号id
            data.SetValue("mch_id", WxPayConfig.MCHID);                //商户号
            data.SetValue("time_stamp", GenerateTimeStamp());          //时间戳
            data.SetValue("nonce_str", RandHelper.GenerateNonceStr()); //随机字符串
            data.SetValue("product_id", productId);                    //商品ID
            data.SetValue("sign", data.MakeSign());                    //签名
            string str = ToUrlParams(data.GetValues());                //转换为URL串
            string url = "weixin://wxpay/bizpayurl?" + str;

            return(url);
        }
        /**
         * 生成直接支付url,支付url有效期为2小时,模式二
         * @param productId 商品ID
         * @return 模式二URL
         */
        public static string GetPayUrl(string rechargeRecordId, string tags, string descript, decimal moneyValue, out string tradeNo)
        {
            tradeNo = RandHelper.GenerateNonceStr();
            WxPayData data = new WxPayData();

            data.SetValue("body", descript);                                                      //商品描述
            data.SetValue("attach", "");                                                          //附加数据
            data.SetValue("out_trade_no", tradeNo);                                               //随机字符串
            data.SetValue("total_fee", StringHelper.Get(IntHelper.Get(moneyValue * 100)));        //总金额
            data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));                 //交易起始时间
            data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss")); //交易结束时间
            data.SetValue("goods_tag", tags);                                                     //商品标记
            data.SetValue("trade_type", "NATIVE");                                                //交易类型
            data.SetValue("product_id", rechargeRecordId);                                        //商品ID
            WxPayData result = UnifiedOrder(data);                                                //调用统一下单接口
            string    url    = result.GetValue("code_url").ToString();                            //获得统一下单接口返回的二维码链接

            return(url);
        }
        /**
         * 统一下单
         * @param WxPaydata inputObj 提交给统一下单API的参数
         * @param int timeOut 超时时间
         * @throws WxPayException
         * @return 成功时返回,其他抛异常
         */
        public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 6)
        {
            string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

            //检测必填参数
            if (!inputObj.IsSet("out_trade_no"))
            {
                throw new WxPayException("缺少统一支付接口必填参数out_trade_no!");
            }
            else if (!inputObj.IsSet("body"))
            {
                throw new WxPayException("缺少统一支付接口必填参数body!");
            }
            else if (!inputObj.IsSet("total_fee"))
            {
                throw new WxPayException("缺少统一支付接口必填参数total_fee!");
            }
            else if (!inputObj.IsSet("trade_type"))
            {
                throw new WxPayException("缺少统一支付接口必填参数trade_type!");
            }

            //关联参数
            if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))
            {
                throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
            }
            if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))
            {
                throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
            }

            //异步通知url未设置,则使用配置文件中的url
            if (!inputObj.IsSet("notify_url"))
            {
                inputObj.SetValue("notify_url", WxPayConfig.NOTIFY_URL);//异步通知url
            }

            inputObj.SetValue("appid", WxPayConfig.APPID);                 //公众账号ID
            inputObj.SetValue("mch_id", WxPayConfig.MCHID);                //商户号
            inputObj.SetValue("spbill_create_ip", WxPayConfig.IP);         //终端ip
            inputObj.SetValue("nonce_str", RandHelper.GenerateNonceStr()); //随机字符串

            //签名
            inputObj.SetValue("sign", inputObj.MakeSign());

            string xml           = inputObj.ToXml();
            var    start         = DateTime.Now;
            var    requestResult = CoreHelper.GetHttpResult(url, xml, contentType: KeyModel.ContentType.Xml);
            string response      = requestResult.Obj; // HttpService.Post(xml, url, false, timeOut);

            var end      = DateTime.Now;
            int timeCost = (int)((end - start).TotalMilliseconds);

            WxPayData result = new WxPayData();

            result.FromXml(response);

            //ReportCostTime(url, timeCost, result);//测速上报

            return(result);
        }