/// <summary> /// 退款通知地址 /// </summary> /// <returns></returns> public ActionResult RefundNotifyUrl() { string responseCode = "FAIL"; string responseMsg = "FAIL"; try { ResponseHandler resHandler = new ResponseHandler(null); string return_code = resHandler.GetParameter("return_code"); string return_msg = resHandler.GetParameter("return_msg"); if (return_code == "SUCCESS") { responseCode = "SUCCESS"; responseMsg = "OK"; string appId = resHandler.GetParameter("appid"); string mch_id = resHandler.GetParameter("mch_id"); string nonce_str = resHandler.GetParameter("nonce_str"); string req_info = resHandler.GetParameter("req_info"); var decodeReqInfo = TenPayV3Util.DecodeRefundReqInfo(req_info, TenPayV3Info.Key); var decodeDoc = XDocument.Parse(decodeReqInfo); //获取接口中需要用到的信息 string transaction_id = decodeDoc.Root.Element("transaction_id").Value; string out_trade_no = decodeDoc.Root.Element("out_trade_no").Value; string refund_id = decodeDoc.Root.Element("refund_id").Value; string out_refund_no = decodeDoc.Root.Element("out_refund_no").Value; int total_fee = int.Parse(decodeDoc.Root.Element("total_fee").Value); int? settlement_total_fee = decodeDoc.Root.Element("settlement_total_fee") != null ? int.Parse(decodeDoc.Root.Element("settlement_total_fee").Value) : null as int?; int refund_fee = int.Parse(decodeDoc.Root.Element("refund_fee").Value); int tosettlement_refund_feetal_fee = int.Parse(decodeDoc.Root.Element("settlement_refund_fee").Value); string refund_status = decodeDoc.Root.Element("refund_status").Value; string success_time = decodeDoc.Root.Element("success_time").Value; string refund_recv_accout = decodeDoc.Root.Element("refund_recv_accout").Value; string refund_account = decodeDoc.Root.Element("refund_account").Value; string refund_request_source = decodeDoc.Root.Element("refund_request_source").Value; //进行业务处理 } } catch (Exception ex) { responseMsg = ex.Message; WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex)); } string xml = string.Format(@"<xml> <return_code><![CDATA[{0}]]></return_code> <return_msg><![CDATA[{1}]]></return_msg> </xml>", responseCode, responseMsg); return(Content(xml, "text/xml")); }
public void DecodeRefundReqInfoTest() { //文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_16&index=11 //数据来源:https://www.cnblogs.com/jhuangsjtu/p/8261683.html //var req_info = "T87GAHG17TGAHG1TGHAHAHA1Y1CIOA9UGJH1GAHV871HAGAGQYQQPOOJMXNBCXBVNMNMAJAA"; var req_info = "m4NnwrtY0jhpDgNp65H1V/0OWMtSoTYhhY89MHbflhmnaHq9ZKjx9ABq6Jpg4SccA876HVy7J9P85NpdvCMNGInZ4fANDRE+YfZe4HeF+bbFj6JETcEFPpE9YW+bTbC0D+gl/otScJfvB2QUK7+EeBGPHN1EWX9zbr2Gw6AUaORdFk3mGxV5dtjuwWQrv5juzkXDs33Z2dUMslO+i3j0cTDHqwS4hptx2j6h2HvzgzltFbjo7nysU+4rArqJvrGW/9r18e1St9XgG21NALqixfaSmqetOR4zLVL4/+z3CEz8cg5r+/4GUOTf3XFmLCZ/wEkRQhKRNVibG0NFfiG3KnqArMJ/dheQHCd7qL+XX/ZV6tj8RLMgL7R6hOiR03Ljyikdxq9M3K9CTYgf03pHJd3geXX1LgXrLxc1flL6NW+zD3ZayGYpr1WpLsSMG7z8W5j1pme6cRj3n2+CwSFnOnOkxaFuLKoJAJIqM3gbC0eN++vY73RKphlI4zZqg6o5s3MXI6ju1yoi/ZQ+XbTg2JttsdbU0aySernKwkt0rYMf0j/Mcvo2axgHbI3w/iTm141WxHUjkQ+ga2X1pOWdGifGhSmMP8oGaA/WD5MAsK1qXX0eFvUWS/PTauCSTWq5Cmr8loA/KL3jgvB0nyR4mfccB+tPy4Ny7kzOlr/VNeb0ULf96R0AWFWCtdt8AmujAP0DYiM5FSmYLI0XRhpSDjnEbBM8+isNE1GlAVR3NzzemwQORihScovpAktbRSN/d3N+NgTjSoVDiJvCOxCs3thX9qt9iwYbA+/X/gv8lza2FZyIzwkQxGRcYl8JWKpXzNW8EWUNVnSLdHvQttDeV3CvgP/x579RGd6whyFYS6AaI0qw7oTjCFh2EHS/VzGvFuv166ZlVIJ4MNvg79O9h63ZOSE1LzVqEsVh8fDCfM2GgJ9aUdl95Djgunit4yIZOdoigR3f/BEHKrYCEham11rYohaAXs4XAXWihsV3WD5j4G/P+txvjAwujvf4HDwzHgFsmSml013U2mUiy+v4zw==";//随便加密 var mch_id = "2IBtBXdrqC3kCBs4gaceL7nl2nnFadQv"; var result = TenPayV3Util.DecodeRefundReqInfo(req_info, mch_id); Console.WriteLine(result); Assert.IsNotNull(result); }
/// <summary> /// 退款通知地址 /// </summary> /// <returns></returns> public ActionResult RefundNotifyUrl() { WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "IP" + HttpContext.UserHostAddress()?.ToString()); string responseCode = "FAIL"; string responseMsg = "FAIL"; try { ResponseHandler resHandler = new ResponseHandler(null); string return_code = resHandler.GetParameter("return_code"); string return_msg = resHandler.GetParameter("return_msg"); WeixinTrace.SendCustomLog("跟踪RefundNotifyUrl信息", resHandler.ParseXML()); if (return_code == "SUCCESS") { responseCode = "SUCCESS"; responseMsg = "OK"; string appId = resHandler.GetParameter("appid"); string mch_id = resHandler.GetParameter("mch_id"); string nonce_str = resHandler.GetParameter("nonce_str"); string req_info = resHandler.GetParameter("req_info"); if (!appId.Equals(Senparc.Weixin.Config.SenparcWeixinSetting.TenPayV3_AppId)) { /* * 注意: * 这里添加过滤只是因为盛派Demo经常有其他公众号错误地设置了我们的地址, * 导致无法正常解密,平常使用不需要过滤! */ SenparcTrace.SendCustomLog("RefundNotifyUrl 的 AppId 不正确", $"appId:{appId}\r\nmch_id:{mch_id}\r\nreq_info:{req_info}"); return(Content("faild")); } var decodeReqInfo = TenPayV3Util.DecodeRefundReqInfo(req_info, TenPayV3Info.Key); var decodeDoc = XDocument.Parse(decodeReqInfo); //获取接口中需要用到的信息 string transaction_id = decodeDoc.Root.Element("transaction_id").Value; string out_trade_no = decodeDoc.Root.Element("out_trade_no").Value; string refund_id = decodeDoc.Root.Element("refund_id").Value; string out_refund_no = decodeDoc.Root.Element("out_refund_no").Value; int total_fee = int.Parse(decodeDoc.Root.Element("total_fee").Value); int? settlement_total_fee = decodeDoc.Root.Element("settlement_total_fee") != null ? int.Parse(decodeDoc.Root.Element("settlement_total_fee").Value) : null as int?; int refund_fee = int.Parse(decodeDoc.Root.Element("refund_fee").Value); int tosettlement_refund_feetal_fee = int.Parse(decodeDoc.Root.Element("settlement_refund_fee").Value); string refund_status = decodeDoc.Root.Element("refund_status").Value; string success_time = decodeDoc.Root.Element("success_time").Value; string refund_recv_accout = decodeDoc.Root.Element("refund_recv_accout").Value; string refund_account = decodeDoc.Root.Element("refund_account").Value; string refund_request_source = decodeDoc.Root.Element("refund_request_source").Value; WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "验证通过"); //进行后续业务处理 } } catch (Exception ex) { responseMsg = ex.Message; WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex)); } string xml = string.Format(@"<xml> <return_code><![CDATA[{0}]]></return_code> <return_msg><![CDATA[{1}]]></return_msg> </xml>", responseCode, responseMsg); return(Content(xml, "text/xml")); }
public override async Task <(bool success, RefundData refundDetail)> RefundResultNotify( IEnumerable <KeyValuePair <string, string> > query, IDictionary <string, string> header, IDictionary <string, string> form, Stream body) { await Task.CompletedTask; var xml = body.ReadToString(); if (xml.IsNullOrWhiteSpace()) { Logger.LogWarning("微信退款回调,xml数据为空"); return(false, null); } ResponseHandler resHandler; try { // 获取微信回调数据 resHandler = new ResponseHandler(HttpContextAccessor.HttpContext); string return_code = resHandler.GetParameter("return_code"); string return_msg = resHandler.GetParameter("return_msg"); if (return_code != "SUCCESS") { return(false, null); } string appId = resHandler.GetParameter("appid"); string mch_id = resHandler.GetParameter("mch_id"); string nonce_str = resHandler.GetParameter("nonce_str"); string req_info = resHandler.GetParameter("req_info"); var secret = MchOptions.Value.Get(mch_id)?.MchKey; if (secret.IsNullOrWhiteSpace()) { Logger.LogError($"微信支付回调,未找到商户密钥,mchId:{mch_id},result:{xml}"); return(false, null); } var decodeReqInfo = TenPayV3Util.DecodeRefundReqInfo(req_info, secret); var decodeDoc = XDocument.Parse(decodeReqInfo); //获取接口中需要用到的信息 string transaction_id = decodeDoc.Root.Element("transaction_id").Value; string out_trade_no = decodeDoc.Root.Element("out_trade_no").Value; string refund_id = decodeDoc.Root.Element("refund_id").Value; string out_refund_no = decodeDoc.Root.Element("out_refund_no").Value; int total_fee = int.Parse(decodeDoc.Root.Element("total_fee").Value); int? settlement_total_fee = decodeDoc.Root.Element("settlement_total_fee") != null ? int.Parse(decodeDoc.Root.Element("settlement_total_fee").Value) : null as int?; int refund_fee = int.Parse(decodeDoc.Root.Element("refund_fee").Value); int tosettlement_refund_feetal_fee = int.Parse(decodeDoc.Root.Element("settlement_refund_fee").Value); string refund_status = decodeDoc.Root.Element("refund_status").Value; string success_time = decodeDoc.Root.Element("success_time").Value; string refund_recv_accout = decodeDoc.Root.Element("refund_recv_accout").Value; string refund_account = decodeDoc.Root.Element("refund_account").Value; string refund_request_source = decodeDoc.Root.Element("refund_request_source").Value; var refundDetail = new RefundData { FailReason = "", LocalRefundNo = out_refund_no, RefundNo = refund_id, RealRefundAmount = tosettlement_refund_feetal_fee, Status = ToStatus(refund_status), SuccessTime = success_time.IsNullOrWhiteSpace() ? null : (long?)success_time.ConvertTo <DateTime>().GetLongDate(), OriginData = decodeReqInfo }; return(true, refundDetail); } catch (XmlException) { Logger.LogWarning("微信退款回调,xml数据解析错误"); return(false, null); } catch (Exception ex) { Logger.LogWarning(ex, "微信退款回调数据处理异常"); return(false, null); } }