/// <summary> /// 查询订单退款状态 /// </summary> /// <param name="config">公共参数</param> /// <param name="out_refund_no">商户退款单号</param> /// <returns></returns> public static Message RefundQuery(TenPayConfig config, string out_refund_no) { var RequsetParam = new Dictionary<string, string>(); RequsetParam.Add("appid", config.appid); RequsetParam.Add("mch_id", config.mch_id); RequsetParam.Add("nonce_str", TenPayConfig.nonce_str()); RequsetParam.Add("out_refund_no", out_refund_no); RequsetParam.Add("sign_type", "MD5"); string sign = TenPaySign.CreateSign(RequsetParam, config.key);//创建签名 RequsetParam.Add("sign", sign); string RequestData = TenPayHelp.InstallXml(RequsetParam);//组装数据 //微信支付统一查询API地址 string sUrl = "https://api.mch.weixin.qq.com/pay/refundquery"; string sResult = TenPayHelp.HttpPost(sUrl, RequestData);//调用接口 var ResponeData = TenPayHelp.GetDictionaryFromCDATAXml(sResult); Message Msg = new Message(); if (TenPaySign.CheckSign(ResponeData, config.key)) {//验证签名 if (ResponeData["return_code"] == "SUCCESS") { if (ResponeData["result_code"] == "SUCCESS") { if (ResponeData["refund_status_0"] == "SUCCESS") { Msg.state = true; Msg.error = "退款成功"; } else { if (ResponeData["refund_status_0"] == "PROCESSING") Msg.error = "退款处理中"; if (ResponeData["refund_status_0"] == "REFUNDCLOSE") Msg.error = "退款关闭"; if (ResponeData["refund_status_0"] == "CHANGE") Msg.error = "退款异常"; } } else { Msg.error = ResponeData["err_code_des"];//错误信息描述 } } else { Msg.error = ResponeData["return_msg"]; } } else { Msg.error = sResult; } return Msg; }
/// <summary> /// 支付下单 /// </summary> /// <param name="config">公共参数</param> /// <param name="sClientIp">客户端的原始Ip(不能是代理IP必须是真实的IP)</param> /// <param name="sOrderNo">订单号</param> /// <param name="sDescription">订单描述,展示在支付页面上的文字描述</param> /// <param name="total_fee">支付金额(单位是分)</param> /// <param name="notify_url">异步通知地址</param> /// <param name="return_url">同步通知地址</param> /// <param name="iPayType">支付方式 1-支付宝 ;2-微信</param> /// <returns></returns> public Message bookOrder(TenPayConfig config, string sClientIp, string sOrderNo, string sDescription, decimal total_fee, string notify_url, string return_url, int iPayType, int time_expire = 2) { if (iPayType == 1) {//支付宝支付 var res = AlipayHelp.Alipay(new AlipayConfig() { app_id = config.appid, alipay_public_key = config.key, merchant_private_key = config.merchant_private_key }, sDescription, sOrderNo, total_fee.ToString(), notify_url, return_url, time_expire); return(res); } else { if (string.IsNullOrEmpty(sClientIp)) { return(new Message() { state = false, error = "用户真实IP必传" }); } string wxPayType = System.Configuration.ConfigurationManager.AppSettings["wxPayMtd"]; total_fee = total_fee * 100; wxPayType = string.IsNullOrEmpty(wxPayType) ? "weixin" : wxPayType; Message res = null; if (wxPayType.Equals("weixin")) { res = TenPayMode.UniteOrder_First(config, sDescription, sOrderNo, Convert.ToInt32(total_fee).ToString(), sClientIp, notify_url, time_expire); } else if (wxPayType.Equals("pingan")) { res = PingAnPay.UniteOrder_First(config, sDescription, sOrderNo, Convert.ToInt32(total_fee).ToString(), sClientIp, notify_url, time_expire); } else { return(res = new Message() { state = false, error = "微信支付类型错误." }); } if (res.state) {//对url进行urlencode处理 string redirect_url = return_url; if (redirect_url != null) { res.data = string.Format("{0}&redirect_url={1}", res.data, TenPayHelp.UrlEncode(redirect_url)); } } return(res); } }
/// <summary> /// 微信申请退款 /// </summary> /// <param name="config">公共参数</param> /// <param name="out_trade_no"></param> /// <param name="out_refund_no"></param> /// <param name="total_fee"></param> /// <param name="refund_fee"></param> /// <param name="refund_desc"></param> /// <returns></returns> public static Message PayRefund(TenPayConfig config,string out_trade_no, string out_refund_no, string total_fee, string refund_fee,string refund_desc) { var RequsetParam = new Dictionary<string, string>(); RequsetParam.Add("appid", config.appid); RequsetParam.Add("mch_id", config.mch_id); RequsetParam.Add("nonce_str", TenPayConfig.nonce_str()); RequsetParam.Add("sign_type", "MD5"); RequsetParam.Add("out_trade_no", out_trade_no); RequsetParam.Add("out_refund_no", out_refund_no); RequsetParam.Add("total_fee", total_fee); RequsetParam.Add("refund_fee", refund_fee); if (!string.IsNullOrEmpty(refund_desc)) {//退款原因 RequsetParam.Add("refund_desc", refund_desc); } string sign = TenPaySign.CreateSign(RequsetParam, config.key);//创建签名 RequsetParam.Add("sign", sign); string RequestData = TenPayHelp.InstallXml(RequsetParam);//组装数据 //微信退款申请API string sUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund"; string sResult = TenPayHelp.HttpPost(sUrl, RequestData, true, config);//调用接口 var ResponeData = TenPayHelp.GetDictionaryFromCDATAXml(sResult); Message result = new Message(); if (TenPaySign.CheckSign(ResponeData, config.key)) {//验证签名 if (ResponeData["return_code"] == "SUCCESS") { if (ResponeData["result_code"] == "SUCCESS") { result.state = true; result.error = "退款申请成功"; } else { result.error = ResponeData["err_code_des"];//错误信息描述 } } else { result.error = ResponeData["return_msg"]; } } else { result.error = sResult; } result.data = sResult; return result; }
/// <summary> /// 退款查询 /// </summary> /// <param name="config"></param> /// <param name="body"></param> /// <param name="outTradeNo"></param> /// <param name="outRefundNo"></param> /// <param name="totalFee"></param> /// <returns></returns> public static Message PayRefundQuery(TenPayConfig config, string outRefundNo) { Message payMsg = new Message(); JObject paramJObject = new JObject { new JProperty("refund_out_no", outRefundNo) }; string bizData = PingAnPayHelp.MakeDataJson(paramJObject.ToString(), openKey); string postData = PingAnPayHelp.SignAndPostData(bizData, openId, openKey); //请求统一下单支付API string requestUrl = ConfigurationManager.AppSettings["pingan_interface"] + "payrefundquery"; string responseStr = PingAnPayHelp.Post(requestUrl, postData);//调用接口 JObject jResult = JObject.Parse(responseStr); //查看返回结果 if (!jResult.SelectToken("errcode").ToString().Equals("0")) { payMsg.state = false; payMsg.data = payMsg.error = jResult.SelectToken("msg").ToString(); return(payMsg); } //验签 if (!PingAnPayHelp.CheckSign(jResult.SelectToken("data").ToString(), jResult.SelectToken("errcode").ToString(), openKey, jResult.SelectToken("msg").ToString(), jResult.SelectToken("sign").ToString(), jResult.SelectToken("timestamp").ToString())) { payMsg.state = false; payMsg.data = payMsg.error = "签名不一致!"; return(payMsg); } string dataStr = PingAnPayHelp.GetDataJson(jResult.SelectToken("data").ToString(), openKey); JObject jData = JObject.Parse(dataStr); if ("1".Equals(jData.SelectToken("status").ToString())) { payMsg.state = true; payMsg.data = PingAnPayHelp.MakeXmlRep(jResult.SelectToken("errcode").ToString(), jData.SelectToken("status").ToString(), "", jResult.SelectToken("msg").ToString(), ""); payMsg.error = "退款成功!"; return(payMsg); } payMsg.state = false; payMsg.data = payMsg.error = "退款失败!"; return(payMsg); }
/// <summary> /// 微信申请退款 /// </summary> /// <param name="sOrderNo">订单号</param> /// <param name="sRefundNo">退款订单号</param> /// <param name="total_fee">支付的金额</param> /// <param name="refund_fee">申请退款的金额</param> /// <param name="refund_desc">退款描述</param> /// <returns></returns> public Message PayRefund(TenPayConfig config, string sOrderNo, string sRefundNo, int total_fee, int refund_fee, string refund_desc) { string wxPayType = System.Configuration.ConfigurationManager.AppSettings["wxPayMtd"]; wxPayType = string.IsNullOrEmpty(wxPayType) ? "weixin" : wxPayType; Message result = null; if (wxPayType.Equals("weixin")) { result = TenPayMode.PayRefund(config, sOrderNo, sRefundNo, total_fee.ToString(), refund_fee.ToString(), refund_desc); } else if (wxPayType.Equals("pingan")) { result = PingAnPay.PayRefund(config, sOrderNo, sRefundNo, total_fee, refund_fee, refund_desc); } else { result = new Message() { state = false, error = "支付方式(wxPayType)参数错误" }; } return(result); }
/// <summary> /// Post请求微信系统 /// </summary> /// <param name="sUrl">请求的链接</param> /// <param name="PostData">请求的参数</param> /// <returns></returns> public static string HttpPost(string sUrl, string PostData, bool isUseCert = false, TenPayConfig config = null) { byte[] bPostData = System.Text.Encoding.UTF8.GetBytes(PostData); string sResult = string.Empty; try { HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(sUrl); webRequest.ProtocolVersion = HttpVersion.Version10; webRequest.Timeout = 30000; webRequest.Method = "POST"; webRequest.Headers.Add("Accept-Encoding", "gzip, deflate"); if (isUseCert && config != null) { //微信退款需要证书 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, config.SSLCERT_PATH); X509Certificate2 cert = new X509Certificate2(path, config.mch_id); //证书的密码就是商户号 webRequest.ClientCertificates.Add(cert); } if (bPostData != null) { Stream postDataStream = webRequest.GetRequestStream(); postDataStream.Write(bPostData, 0, bPostData.Length); } HttpWebResponse webResponse = (System.Net.HttpWebResponse)webRequest.GetResponse(); if (webResponse.ContentEncoding.ToLower() == "gzip")//如果使用了GZip则先解压 { using (System.IO.Stream streamReceive = webResponse.GetResponseStream()) { using (var zipStream = new System.IO.Compression.GZipStream(streamReceive, System.IO.Compression.CompressionMode.Decompress)) { using (StreamReader sr = new System.IO.StreamReader(zipStream, Encoding.GetEncoding(webResponse.CharacterSet))) { sResult = sr.ReadToEnd(); } } } } else if (webResponse.ContentEncoding.ToLower() == "deflate")//如果使用了deflate则先解压 { using (System.IO.Stream streamReceive = webResponse.GetResponseStream()) { using (var zipStream = new System.IO.Compression.DeflateStream(streamReceive, System.IO.Compression.CompressionMode.Decompress)) { using (StreamReader sr = new System.IO.StreamReader(zipStream, Encoding.GetEncoding(webResponse.CharacterSet))) { sResult = sr.ReadToEnd(); } } } } else { using (System.IO.Stream streamReceive = webResponse.GetResponseStream()) { using (System.IO.StreamReader sr = new System.IO.StreamReader(streamReceive, Encoding.UTF8)) { sResult = sr.ReadToEnd(); logger.Info("请求链接:" + sUrl); logger.Info("请求返回结果:" + sResult); } } } } catch (Exception ex) { logger.Info("请求异常:" + ex.Message); logger.Info(ex.Message, ex); } return(sResult); }
/// <summary> /// 订单查询 /// </summary> /// <param name="config"></param> /// <param name="out_trade_no">自己系统订单号</param> /// <returns></returns> public static Message OrderQuery(TenPayConfig config, string out_trade_no) { Message payMsg = new Message(); JObject paramJObject = new JObject { new JProperty("out_no", out_trade_no) }; string bizData = PingAnPayHelp.MakeDataJson(paramJObject.ToString(), openKey); string postData = PingAnPayHelp.SignAndPostData(bizData, openId, openKey); //请求统一下单支付API string requestUrl = ConfigurationManager.AppSettings["pingan_interface"] + "paystatus"; string responseStr = PingAnPayHelp.Post(requestUrl, postData);//调用接口 JObject jResult = JObject.Parse(responseStr); //查看返回结果 if (!jResult.SelectToken("errcode").ToString().Equals("0")) { payMsg.state = false; payMsg.data = payMsg.error = jResult.SelectToken("msg").ToString(); return(payMsg); } //验签 if (!PingAnPayHelp.CheckSign(jResult.SelectToken("data").ToString(), jResult.SelectToken("errcode").ToString(), openKey, jResult.SelectToken("msg").ToString(), jResult.SelectToken("sign").ToString(), jResult.SelectToken("timestamp").ToString())) { payMsg.state = false; payMsg.data = payMsg.error = "签名不一致!"; return(payMsg); } string dataStr = PingAnPayHelp.GetDataJson(jResult.SelectToken("data").ToString(), openKey); JObject jData = JObject.Parse(dataStr); //查询订单号 if (!out_trade_no.Equals((jData.SelectToken("out_no").ToString()))) { payMsg.state = false; payMsg.data = payMsg.error = "查询订单号与返回订单号不一致!"; return(payMsg); } string status = jData.SelectToken("status").ToString(); switch (status) { case "1": payMsg.state = true; payMsg.data = payMsg.error = "支付成功!"; return(payMsg); case "2": payMsg.state = false; payMsg.data = payMsg.error = "待支付!"; return(payMsg); case "4": payMsg.state = false; payMsg.data = payMsg.error = "已取消!"; return(payMsg); case "9": payMsg.state = false; payMsg.data = payMsg.error = "等待用户输入密码确认!"; return(payMsg); default: payMsg.state = false; payMsg.data = payMsg.error = "状态未知!"; return(payMsg); } }
/// <summary> /// 退款 /// </summary> /// <param name="config"></param> /// <param name="body"></param> /// <param name="out_trade_no"></param> /// <param name="total_fee"></param> /// <returns></returns> public static Message PayRefund(TenPayConfig config, string out_trade_no, string out_refund_no, int total_fee, int refund_fee, string refund_desc) { Message payMsg = new Message(); string refundPwd = ConfigurationManager.AppSettings["pingan_refund_pwd"]; JObject paramJObject = new JObject { new JProperty("out_no", out_trade_no), new JProperty("refund_out_no", out_refund_no), new JProperty("refund_ord_name", refund_desc), new JProperty("refund_amount", refund_fee), new JProperty("shop_pass", Utilities.SHA1(refundPwd).ToLower()) }; string bizData = PingAnPayHelp.MakeDataJson(paramJObject.ToString(), openKey); string postData = PingAnPayHelp.RefundSignAndPostData(bizData, openId, openKey); //请求统一下单支付API string requestUrl = ConfigurationManager.AppSettings["pingan_interface"] + "payrefund"; string responseStr = PingAnPayHelp.Post(requestUrl, postData);//调用接口 JObject jResult = JObject.Parse(responseStr); //查看返回结果 if (!jResult.SelectToken("errcode").ToString().Equals("0")) { payMsg.state = false; payMsg.data = payMsg.error = jResult.SelectToken("msg").ToString(); return(payMsg); } //验签 if (!PingAnPayHelp.CheckSign(jResult.SelectToken("data").ToString(), jResult.SelectToken("errcode").ToString(), openKey, jResult.SelectToken("msg").ToString(), jResult.SelectToken("sign").ToString(), jResult.SelectToken("timestamp").ToString())) { payMsg.state = false; payMsg.data = payMsg.error = "签名不一致!"; return(payMsg); } string dataStr = PingAnPayHelp.GetDataJson(jResult.SelectToken("data").ToString(), openKey); JObject jData = JObject.Parse(dataStr); //验证主要参数 if (total_fee != (int)jData.SelectToken("trade_amount")) { payMsg.state = false; payMsg.data = payMsg.error = "请求退款金额与实际退款金额不一致!"; return(payMsg); } if ("1".Equals(jData.SelectToken("status").ToString())) { payMsg.state = true; payMsg.data = PingAnPayHelp.MakeXmlRep(jResult.SelectToken("errcode").ToString(), jData.SelectToken("status").ToString(), jData.SelectToken("ord_no").ToString(), jResult.SelectToken("msg").ToString(), ""); payMsg.error = "退款请求成功!"; return(payMsg); } payMsg.state = false; payMsg.data = payMsg.error = "退款失败!"; return(payMsg); }
public static Message UniteOrder_First(TenPayConfig config, string body, string out_trade_no, string total_fee, string spbill_create_ip, string notify_url, int time_expire = 2) { notify_url = "http://hwsh.qianxingniwo.com:9211/WxPayNotify.ashx"; Message payMsg = new Message(); string scene = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"" + wapUrl + "\",\"wap_name\": \"" + wapName + "\"}} "; JObject paramJObject = new JObject { new JProperty("out_no", out_trade_no), new JProperty("trade_amount", total_fee), new JProperty("original_amount", total_fee), new JProperty("trade_type", "MWEB"), new JProperty("pmt_tag", "WeixinOL"), new JProperty("notify_url", notify_url), new JProperty("spbill_create_ip", spbill_create_ip), new JProperty("scene_info", scene) }; if (string.IsNullOrEmpty(openId) || string.IsNullOrEmpty(openKey)) { payMsg.state = false; payMsg.data = payMsg.error = "openid或openKey没有配置"; return(payMsg); } string bizData = PingAnPayHelp.MakeDataJson(paramJObject.ToString(), openKey); string postData = PingAnPayHelp.SignAndPostData(bizData, openId, openKey); //请求统一下单支付API string requestUrl = ConfigurationManager.AppSettings["pingan_interface"] + "payorder"; string responseStr = PingAnPayHelp.Post(requestUrl, postData);//调用接口 JObject jResult = JObject.Parse(responseStr); //查看返回结果 if (!jResult.SelectToken("errcode").ToString().Equals("0")) { payMsg.state = false; payMsg.data = payMsg.error = jResult.SelectToken("msg").ToString(); return(payMsg); } //验签 if (!PingAnPayHelp.CheckSign(jResult.SelectToken("data").ToString(), jResult.SelectToken("errcode").ToString(), openKey, jResult.SelectToken("msg").ToString(), jResult.SelectToken("sign").ToString(), jResult.SelectToken("timestamp").ToString())) { payMsg.state = false; payMsg.data = payMsg.error = "签名不一致!"; return(payMsg); } string dataStr = PingAnPayHelp.GetDataJson(jResult.SelectToken("data").ToString(), openKey); JObject jData = JObject.Parse(dataStr); //验证主要参数 if (!total_fee.Equals(jData.SelectToken("trade_amount").ToString())) { payMsg.state = false; payMsg.data = payMsg.error = "请求支付金额与实际支付金额不一致!"; return(payMsg); } string tradeResultStr = jData.SelectToken("trade_result").ToString(); JObject tradeResultJo = JObject.Parse(tradeResultStr); if (!"SUCCESS".Equals(tradeResultJo.SelectToken("return_code").ToString())) { payMsg.state = false; payMsg.data = payMsg.error = "支付请求失败!" + tradeResultJo.SelectToken("return_msg"); return(payMsg); } payMsg.data = jData.SelectToken("mweb_url").ToString(); payMsg.state = true; payMsg.error = "支付请求成功!"; return(payMsg); }
/// <summary> /// 统一下单支付接口 /// </summary> /// <param name="config">公共参数</param> /// <param name="body">描述</param> /// <param name="out_trade_no">商户系统内部的订单编号</param> /// <param name="total_fee">订单总金额,单位为分</param> /// <param name="spbill_create_ip">APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP.</param> /// <param name="notify_url">接收微信支付异步通知回调地址,不能携带参数</param> /// <returns></returns> public static Message UniteOrder_First(TenPayConfig config, string body, string out_trade_no, string total_fee, string spbill_create_ip, string notify_url, int time_expire=2) { /************************* 调用微信统一支付API所必需的参数******************************************/ //公众账号ID appid 微信分配的公众账号ID(企业号corpid即为此appId) //商户号 mch_id 微信支付分配的商户号 //随机字符串 nonce_str 随机字符串,不长于32位。推荐随机数生成算法 //签名 sign 签名,详见签名生成算法 //商品描述 body 商品或支付单简要描述 //商户订单号 out_trade_no 商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号 //总金额 total_fee 订单总金额,单位为分,详见支付金额 //终端IP spbill_create_ip APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。 //通知地址 notify_url 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。 //交易类型 trade_type 取值如下:JSAPI,NATIVE,APP,详细说明见参数规定 //商品ID product_id trade_type=NATIVE,此参数必传。此id为二维码中包含的商户定义的商品id或者订单号,商户自行定义。 /************************* 调用微信统一支付API所必需的参数******************************************/ var Dic = new Dictionary<string, string>(); Dic.Add("appid", config.appid); Dic.Add("mch_id", config.mch_id); Dic.Add("nonce_str", TenPayConfig.nonce_str()); Dic.Add("body", body); Dic.Add("out_trade_no", out_trade_no); Dic.Add("total_fee", total_fee); Dic.Add("spbill_create_ip", spbill_create_ip); Dic.Add("notify_url", notify_url); Dic.Add("trade_type", "MWEB");//新h5模式 Dic.Add("time_expire", DateTime.Now.AddHours(time_expire).ToString("yyyyMMddHHmmss"));//订单的失效时间 string sign = TenPaySign.CreateSign(Dic, config.key);//创建签名 Dic.Add("sign", sign); string RequestData = TenPayHelp.InstallXml(Dic); //请求统一下单支付API string sUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; string sResult = TenPayHelp.HttpPost(sUrl, RequestData);//调用接口 var Parameters = TenPayHelp.GetDictionaryFromCDATAXml(sResult); Message Msg = new Message(); if (TenPaySign.CheckSign(Parameters,config.key)) {//验证签名 if (Parameters["return_code"] == "SUCCESS") { if (Parameters["result_code"] == "SUCCESS") {//统一下单成功 Msg.state = true; Msg.data = Parameters["mweb_url"]; } else {//统一下单失败 Msg.error = Parameters["err_code_des"];//错误信息描述 } } else { Msg.error = Parameters["return_msg"]; } } else { Msg.error = sResult; } return Msg; }
/// <summary> /// 根据订单号查询微信支付状态 /// </summary> /// <param name="config">公共参数</param> /// <param name="sOrderNo"></param> /// <returns></returns> public Message QueryPayState(TenPayConfig config, string sOrderNo) { var res = TenPayMode.OrderQuery(config, sOrderNo); return(res); }