# 退款
# 退款
退款方法核心代码如下:
/// <summary>
/// 退款申请接口
/// </summary>
/// <returns></returns>
public ActionResult Refund()
{
try
{
string nonceStr = TenPayV3Util.GetNoncestr();
string outTradeNo = HttpContext.Session.GetString("BillNo");
string outRefundNo = "OutRefunNo-" + SystemTime.Now.Ticks;
int totalFee = int.Parse(HttpContext.Session.GetString("BillFee"));
int refundFee = totalFee;
string opUserId = TenPayV3Info.MchId;
var notifyUrl = "https://sdk.weixin.senparc.com/TenPayV3/RefundNotifyUrl";
var dataInfo = new TenPayV3RefundRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, TenPayV3Info.Key,
null, nonceStr, null, outTradeNo, outRefundNo, totalFee, refundFee, opUserId, null, notifyUrl: notifyUrl);
var result = TenPayOldV3.Refund(_serviceProvider, dataInfo);//证书地址、密码,在配置文件中设置,并在注册微信支付信息时自动记录
ViewData["Message"] = $"退款结果:{result.result_code} {result.err_code_des}。您可以刷新当前页面查看最新结果。";
return View();
}
catch (Exception ex)
{
WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
throw;
}
}
本项目参考文件:
/Controllers/TenPayV3Controller.cs
说明:上述代码为了方便演示,并限定在没有登录功能的情况下只能退款本人自己支付过的订单,因此将 BillNo(订单号)存在 Session 中,实际开发过程中可放入 URL 或 Post 参数中进行请求,并注意做好权限验证!
# 退款回调
在退款接口调用过程中,有一个 notifyUrl
的参数,此地址用于接收微信服务器发送的退款信息回调信息。代码如下:
/// <summary>
/// 退款通知地址
/// </summary>
/// <returns></returns>
public ActionResult RefundNotifyUrl()
{
string responseCode = "FAIL";
string responseMsg = "FAIL";
try
{
ResponseHandler resHandler = new ResponseHandler(HttpContext);
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;
//验证通过,进行后续业务处理
}
}
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");
}
本项目参考文件:
/Controllers/TenPayV3Controller.cs