修改退款接口

development
温天培 1 year ago
parent ab26dd1b08
commit 703a0db421

@ -0,0 +1,43 @@
using System;
using SqlSugar;
using System.ComponentModel;
using GDZZ.Core.Entity;
namespace GDZZ.Application.Entity
{
/// <summary>
/// 退款表
/// </summary>
[SugarTable("Mini_Refund")]
[Description("退款表")]
public class ReFund : DEntityBase
{
/// <summary>
/// 退款金额
/// </summary>
public decimal Amount { get; set; }
/// <summary>
/// 退款状态
/// </summary>
public RefundStatusEnum State { get; set; }
/// <summary>
/// 退款消息
/// </summary>
public string Message { get; set; }
/// <summary>
/// 退款单号
/// </summary>
public string PayNo { get; set; }
/// <summary>
/// 商户退款单号
/// </summary>
public string refundNo { get; set; }
/// <summary>
/// 微信订单号
/// </summary>
public string TransactionNo { get; set; }
/// <summary>
/// 微信退款单号
/// </summary>
public string RefundID { get; set; }
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GDZZ.Application
{
/// <summary>
/// 退款状态
/// </summary>
public enum RefundStatusEnum
{
/// <summary>
/// 退款中
/// </summary>
[Description("退款中")] REDIND = 0,
/// <summary>
/// 退款失败
/// </summary>
[Description("退款失败")] REFAILED =1,
/// <summary>
/// 退款成功
/// </summary>
[Description("退款成功")] RESUCCESS = 2,
}
}

@ -614,6 +614,46 @@
推荐标题 推荐标题
</summary> </summary>
</member> </member>
<member name="T:GDZZ.Application.Entity.ReFund">
<summary>
退款表
</summary>
</member>
<member name="P:GDZZ.Application.Entity.ReFund.Amount">
<summary>
退款金额
</summary>
</member>
<member name="P:GDZZ.Application.Entity.ReFund.State">
<summary>
退款状态
</summary>
</member>
<member name="P:GDZZ.Application.Entity.ReFund.Message">
<summary>
退款消息
</summary>
</member>
<member name="P:GDZZ.Application.Entity.ReFund.PayNo">
<summary>
退款单号
</summary>
</member>
<member name="P:GDZZ.Application.Entity.ReFund.refundNo">
<summary>
商户退款单号
</summary>
</member>
<member name="P:GDZZ.Application.Entity.ReFund.TransactionNo">
<summary>
微信订单号
</summary>
</member>
<member name="P:GDZZ.Application.Entity.ReFund.RefundID">
<summary>
微信退款单号
</summary>
</member>
<member name="T:GDZZ.Application.Entity.SeIF"> <member name="T:GDZZ.Application.Entity.SeIF">
<summary> <summary>
职业表 职业表
@ -764,6 +804,26 @@
储值 储值
</summary> </summary>
</member> </member>
<member name="T:GDZZ.Application.RefundStatusEnum">
<summary>
退款状态
</summary>
</member>
<member name="F:GDZZ.Application.RefundStatusEnum.REDIND">
<summary>
退款中
</summary>
</member>
<member name="F:GDZZ.Application.RefundStatusEnum.REFAILED">
<summary>
退款失败
</summary>
</member>
<member name="F:GDZZ.Application.RefundStatusEnum.RESUCCESS">
<summary>
退款成功
</summary>
</member>
<member name="F:GDZZ.Application.ResumeStatusEnum.Release"> <member name="F:GDZZ.Application.ResumeStatusEnum.Release">
<summary> <summary>
已发布 已发布
@ -1293,6 +1353,17 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:GDZZ.Application.Service.WXPay.WXPayService.WxRefund(GDZZ.Application.WxRefundInput)">
<summary>
微信小程序退款
</summary>
<returns></returns>
</member>
<member name="M:GDZZ.Application.Service.WXPay.WXPayService.RefundNotifyUrl">
<summary>
退款回调
</summary>
</member>
<member name="P:GDZZ.Application.AuthUserInput.Discount"> <member name="P:GDZZ.Application.AuthUserInput.Discount">
<summary> <summary>
折扣 折扣
@ -1358,6 +1429,26 @@
公司信息 公司信息
</summary> </summary>
</member> </member>
<member name="P:GDZZ.Application.WxRefundInput.OrderID">
<summary>
订单编号
</summary>
</member>
<member name="P:GDZZ.Application.WxRefundInput.PayNo">
<summary>
退款单号
</summary>
</member>
<member name="P:GDZZ.Application.WxRefundInput.RealPic">
<summary>
真实支付金额
</summary>
</member>
<member name="P:GDZZ.Application.WxRefundInput.Message">
<summary>
退款消息
</summary>
</member>
<member name="T:GDZZ.Application.BaseUserService"> <member name="T:GDZZ.Application.BaseUserService">
<summary> <summary>
基础用户服务 基础用户服务

@ -0,0 +1,35 @@
using GDZZ.Application.Enum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GDZZ.Application
{
public class WxRefundInput
{
/// <summary>
/// 订单编号
/// </summary>
public long OrderID { get; set; }
/// <summary>
/// 退款单号
/// </summary>
public string PayNo { get; set; }
/// <summary>
/// 真实支付金额
/// </summary>
public decimal RealPic { get; set; }
/// <summary>
/// 退款消息
/// </summary>
public string Message { get; set; }
}
}

@ -23,7 +23,7 @@ using Microsoft.AspNetCore.Authorization;
using System.Collections.Generic; using System.Collections.Generic;
using Mapster; using Mapster;
using Furion.FriendlyException; using Furion.FriendlyException;
using Senparc.CO2NET.Cache.Redis;
namespace GDZZ.Application.Service.WXPay namespace GDZZ.Application.Service.WXPay
{ {
@ -42,7 +42,7 @@ namespace GDZZ.Application.Service.WXPay
private readonly SqlSugarRepository<MiniRecharge> rechargeRep; //充值仓储 private readonly SqlSugarRepository<MiniRecharge> rechargeRep; //充值仓储
private readonly SqlSugarRepository<MiniPayTake> payTakeRep; //支付仓储 private readonly SqlSugarRepository<MiniPayTake> payTakeRep; //支付仓储
private readonly SqlSugarRepository<ReFund> refundRep; //退款仓储
private readonly WechatOAuth _wechatOAuth; //微信权限服务 private readonly WechatOAuth _wechatOAuth; //微信权限服务
private readonly IHttpContextAccessor _httpContextAccessor; //http服务 private readonly IHttpContextAccessor _httpContextAccessor; //http服务
@ -66,11 +66,13 @@ namespace GDZZ.Application.Service.WXPay
SqlSugarRepository<SeIF> Self, SqlSugarRepository<SeIF> Self,
SqlSugarRepository<MiniRecharge> rechargeRep, SqlSugarRepository<MiniRecharge> rechargeRep,
SqlSugarRepository<MiniPayTake> payTakeRep, SqlSugarRepository<MiniPayTake> payTakeRep,
SqlSugarRepository<ReFund> refundRep,
WechatOAuth wechatOAuth, WechatOAuth wechatOAuth,
IHttpContextAccessor _httpContextAccessor, IHttpContextAccessor _httpContextAccessor,
IEventPublisher eventPublisher) IEventPublisher eventPublisher)
{ {
this.self = Self; this.self = Self;
this.refundRep= refundRep;
this.balance = balance; this.balance = balance;
this.Baseuser = Baseuser; this.Baseuser = Baseuser;
this.ComsumeRep = ComsumeRep; this.ComsumeRep = ComsumeRep;
@ -158,6 +160,10 @@ namespace GDZZ.Application.Service.WXPay
} }
#region 小程序支付
/// <summary> /// <summary>
///微信小程序支付 ///微信小程序支付
/// </summary> /// </summary>
@ -192,7 +198,7 @@ namespace GDZZ.Application.Service.WXPay
string nonceStr = TenPayV3Util.GetNoncestr(); string nonceStr = TenPayV3Util.GetNoncestr();
TenPayV3UnifiedorderRequestData xmlDataInfo = new TenPayV3UnifiedorderRequestData(Config.SenparcWeixinSetting.WxOpenAppId, TenPayV3UnifiedorderRequestData xmlDataInfo = new TenPayV3UnifiedorderRequestData(Config.SenparcWeixinSetting.WxOpenAppId,
Config.SenparcWeixinSetting.TenPayV3_MchId,"余额充值", sp_billno, Config.SenparcWeixinSetting.TenPayV3_MchId, "余额充值", sp_billno,
pMoney, pMoney,
"127.0.0.1", "127.0.0.1",
Config.SenparcWeixinSetting.TenPayV3_TenpayNotify, TenPayV3Type.JSAPI, authUserInput.OpenID, Config.SenparcWeixinSetting.TenPayV3_TenpayNotify, TenPayV3Type.JSAPI, authUserInput.OpenID,
@ -218,6 +224,7 @@ namespace GDZZ.Application.Service.WXPay
} }
/// <summary> /// <summary>
/// 微信小程序支付回调 /// 微信小程序支付回调
/// </summary> /// </summary>
@ -226,18 +233,16 @@ namespace GDZZ.Application.Service.WXPay
[Route("/Mini/NotifyUrl")] [Route("/Mini/NotifyUrl")]
[UnifyResult(typeof(string))] [UnifyResult(typeof(string))]
[AllowAnonymous] [AllowAnonymous]
public async Task<string> NotifyUrl() public async Task<ActionResult> NotifyUrl()
{
try
{ {
ResponseHandler resHandler = new ResponseHandler(this._httpContextAccessor.HttpContext); ResponseHandler resHandler = new ResponseHandler(this._httpContextAccessor.HttpContext);
ContentResult content = new ContentResult();
string return_code = resHandler.GetParameter("return_code"); string return_code = resHandler.GetParameter("return_code");
string return_msg = resHandler.GetParameter("return_msg"); string return_msg = resHandler.GetParameter("return_msg");
//var res = "";
resHandler.SetKey(Config.SenparcWeixinSetting.TenPayV3_Key); resHandler.SetKey(Config.SenparcWeixinSetting.TenPayV3_Key);
try
{
//验证请求是否从微信发过来(安全) //验证请求是否从微信发过来(安全)
if (resHandler.IsTenpaySign() && return_code.ToUpper() == "SUCCESS") if (resHandler.IsTenpaySign() && return_code.ToUpper() == "SUCCESS")
{ {
@ -273,15 +278,155 @@ namespace GDZZ.Application.Service.WXPay
}); });
} }
} }
content.Content = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);
this.SendTemplate(0, return_code, resHandler);
}
else
{
content.Content = "回调失败";
}
this.LogRecord(resHandler);
}
catch (Exception ex)
{
content.Content = ex.Message;
}
return content;
}
#endregion
#region 小程序退款
/// <summary>
///微信小程序退款
/// </summary>
/// <returns></returns>
[HttpPost]
[Route("Mini/v1/refund")]
public async Task<dynamic> WxRefund(WxRefundInput wxRefundInput)
{
//查询订单
var order = this.payTakeRep.FirstOrDefault(x => x.OrderId == wxRefundInput.OrderID);
if (order == null)
return new Exception("查询无此订单,退款失败");
//生成退款单
var res = await this.refundRep.InsertReturnEntityAsync(new ReFund()
{
State = RefundStatusEnum.REDIND,
Amount = order.PaymentMoney,
Message = "退款审核中",
PayNo = order.Id.ToString(),
});
if (res == null)
return new Exception("生成退款单失败");
string notifyUrl = string.Format(Config.SenparcWeixinSetting.TenPayV3_TenpayNotify, "RefundNotifyUrl");
string opUserId = Config.SenparcWeixinSetting.TenPayV3_MchId;
//退款金额
int refundFee = (int)(order.PaymentMoney * 100);
//支付时的总金额
int totalFee = (int)(order.PaymentMoney * 100);
string outRefundNo = res.Id.ToString();//新退款单号
string outTradeNo = order.OrderId.ToString();
var nonceStr = TenPayV3Util.GetNoncestr();
var dataInfo = new TenPayV3RefundRequestData(Config.SenparcWeixinSetting.WxOpenAppId, Config.SenparcWeixinSetting.TenPayV3_MchId,
Config.SenparcWeixinSetting.TenPayV3_Key, null, nonceStr, null, outTradeNo, outRefundNo, totalFee, refundFee, opUserId, null,
notifyUrl: notifyUrl);
return new
{
message = "退款请求完成",
};
}
/// <summary>
/// 退款回调
/// </summary>
[HttpPost("RefundNotifyUrl")]
[UnifyResult(typeof(string))]
public async Task<ActionResult> RefundNotifyUrl()
{
ResponseHandler resHandler = new ResponseHandler(this._httpContextAccessor.HttpContext);
ContentResult content = new ContentResult();
string return_code = resHandler.GetParameter("return_code");
string return_msg = resHandler.GetParameter("return_msg");
var mch_key = Senparc.Weixin.Config.SenparcWeixinSetting.TenPayV3_Key;
try
{
if (return_code.ToUpper() == "SUCCESS")
{
string req_info = resHandler.GetParameter("req_info");
var decodeReqInfo = TenPayV3Util.DecodeRefundReqInfo(req_info, mch_key);
var decodeDoc = System.Xml.Linq.XDocument.Parse(decodeReqInfo);
var refundNotifyXml = decodeDoc.Serialize();
//获取接口中需要用到的信息
string out_trade_no = decodeDoc.Root.Element("out_trade_no").Value;
string transaction_id = decodeDoc.Root.Element("transaction_id").Value;
string refund_id = decodeDoc.Root.Element("refund_id").Value;
int total_fee = int.Parse(decodeDoc.Root.Element("total_fee").Value);
int refund_fee = int.Parse(decodeDoc.Root.Element("refund_fee").Value);
string out_refund_no = decodeDoc.Root.Element("out_refund_no").Value;
var refun = this.refundRep.FirstOrDefault(x => x.PayNo == out_refund_no);
refun.PayNo = out_refund_no;
refun.Amount = ((float)refund_fee.ParseToInt() / 100).ParseToDecimal();
refun.Message = "退款完成";
refun.RefundID = refund_id;
refun.refundNo = out_refund_no;
refun.TransactionNo = transaction_id;
refun.State = RefundStatusEnum.RESUCCESS;
if (this.refundRep.Update(refun) > 0)
{
content.Content = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);
return content;
}
} }
else else
{ {
Console.WriteLine("回调失败"); content.Content = "回调处理失败!";
//res = "wrong";//错误的订单处理 }
}
catch (Exception e)
{
content.Content = e.Message;
}
return content;
} }
/* 这里可以进行订单处理的逻辑 */ #endregion
#region 附加服务
public void SendTemplate(int type, string return_code, ResponseHandler resHandler)
{
switch (type)
{
case 0:
//发送支付成功的模板消息 //发送支付成功的模板消息
try try
{ {
@ -297,6 +442,16 @@ namespace GDZZ.Application.Service.WXPay
{ {
Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息", ex.ToString()); Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息", ex.ToString());
} }
break;
default:
break;
}
}
private void LogRecord(ResponseHandler resHandler)
{
#region 记录日志 #region 记录日志
@ -317,21 +472,7 @@ namespace GDZZ.Application.Service.WXPay
} }
#endregion #endregion
string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);
return xml;
}
catch (Exception ex)
{
WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
throw;
}
} }
#endregion
} }
} }

Loading…
Cancel
Save