From 1073066309e2ea655dfad26f32fdb298b56d61bf Mon Sep 17 00:00:00 2001 From: yzp Date: Tue, 25 Feb 2025 10:19:01 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=8A=9F=E8=83=BD=EF=BC=8CBUG:1=E3=80=81?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E5=88=9B=E5=BB=BA=E5=AE=9A=E5=8D=95=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E9=94=99=E8=AF=AF=202=E3=80=81=E9=80=80=E6=AC=BE?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E4=BD=BF=E7=94=A8=E5=9B=9E=E8=B0=83=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=203=E3=80=81=E9=80=80=E6=AC=BE=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E7=9A=84=E5=85=B3=E9=94=AE=E5=AD=97=E6=AE=B5=E4=BC=A0=E5=80=BC?= =?UTF-8?q?=E6=9C=89=E8=AF=AF=20Fix:=E5=A2=9E=E5=8A=A0=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E6=8E=A5=E6=88=AA=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Configuration/Wechat.json | 14 +- .../Admin.NET.Core/Entity/SysWechatRefund.cs | 19 +- .../Service/Wechat/Dto/WechatPayInput.cs | 4 +- .../Service/Wechat/SysWechatPayService.cs | 268 +++++++++++++++--- Admin.NET/Admin.NET.Web.Core/Startup.cs | 3 + .../api-services/apis/sys-wechat-pay-api.ts | 197 ++++++++++++- .../api-services/models/sys-wechat-refund.ts | 12 +- Web/src/views/system/weChatPay/index.vue | 70 +++-- 8 files changed, 494 insertions(+), 93 deletions(-) diff --git a/Admin.NET/Admin.NET.Application/Configuration/Wechat.json b/Admin.NET/Admin.NET.Application/Configuration/Wechat.json index f591e84d..dc59db4e 100644 --- a/Admin.NET/Admin.NET.Application/Configuration/Wechat.json +++ b/Admin.NET/Admin.NET.Application/Configuration/Wechat.json @@ -1,4 +1,4 @@ -{ +{ "$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json", "Wechat": { @@ -16,16 +16,16 @@ }, // 微信支付 "WechatPay": { - "AppId": "", // 微信公众平台AppId、开放平台AppId、小程序AppId、企业微信CorpId - "MerchantId": "", // 商户平台的商户号 - "MerchantV3Secret": "", // 商户平台的APIv3密钥 - "MerchantCertificateSerialNumber": "", // 商户平台的证书序列号 + "AppId": "wxaaaaaaaaaaaaaa85", // 微信公众平台AppId、开放平台AppId、小程序AppId、企业微信CorpId + "MerchantId": "1500000001", // 商户平台的商户号 + "MerchantV3Secret": "3aaaaaaaaaaaaaaaaaaaaaaaaaaaaaoo", // 商户平台的APIv3密钥 + "MerchantCertificateSerialNumber": "66aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", // 商户平台的证书序列号 "MerchantCertificatePrivateKey": "\\WxPayCert\\apiclient_key.pem" // 商户平台的API证书私钥(apiclient_key.pem文件内容) }, // 支付回调 "PayCallBack": { - "WechatPayUrl": "https://xxx/api/sysWechatPay/payCallBack", // 微信支付回调 - "WechatRefundUrl": "", // 微信退款回调 + "WechatPayUrl": "https://ip/sysWechatPay/payCallBack", // 微信支付回调: https://ip/sysWechatPay/payCallBack + "WechatRefundUrl": "https://ip/api/sysWechatPay/refundCallBack", // 微信退款回调:https://ip/api/sysWechatPay/refundCallBack "AlipayUrl": "", // 支付宝支付回调 "AlipayRefundUrl": "" // 支付宝退款回调 } diff --git a/Admin.NET/Admin.NET.Core/Entity/SysWechatRefund.cs b/Admin.NET/Admin.NET.Core/Entity/SysWechatRefund.cs index 19b96531..61003ba3 100644 --- a/Admin.NET/Admin.NET.Core/Entity/SysWechatRefund.cs +++ b/Admin.NET/Admin.NET.Core/Entity/SysWechatRefund.cs @@ -33,7 +33,12 @@ public class SysWechatRefund : EntityBase /// [SugarColumn(ColumnDescription = "商户退款单号", Length = 64)] [Required] - public string OutRefundNo { get; set; } + public string OutRefundNumber { get; set; } + + /// + /// 微信接口退款ID + /// + public string RefundId { get; set; } /// /// 退款原因,示例:商品已售完 @@ -75,19 +80,25 @@ public class SysWechatRefund : EntityBase /// 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款) /// [SugarColumn(ColumnDescription = "关联的商户订单状态", Length = 32)] - public string? OrderStatus { get; set; } + public string? RefundStatus { get; set; } + + /// + /// 支完成时间 + /// + [SugarColumn(ColumnDescription = "完成时间")] + public DateTime? SuccessTime { get; set; } /// /// 关联的商户商品编码 /// [SugarColumn(ColumnDescription = "关联的商户商品编码", Length = 32)] - public string MerchantGoodsId { get; set; } + public string? MerchantGoodsId { get; set; } /// /// 关联的商户商品名称 /// [SugarColumn(ColumnDescription = "关联的商户商品名称", Length = 256)] - public string GoodsName { get; set; } + public string? GoodsName { get; set; } /// /// 关联的商户商品单价 diff --git a/Admin.NET/Admin.NET.Core/Service/Wechat/Dto/WechatPayInput.cs b/Admin.NET/Admin.NET.Core/Service/Wechat/Dto/WechatPayInput.cs index b71954d7..84907694 100644 --- a/Admin.NET/Admin.NET.Core/Service/Wechat/Dto/WechatPayInput.cs +++ b/Admin.NET/Admin.NET.Core/Service/Wechat/Dto/WechatPayInput.cs @@ -140,13 +140,13 @@ public class PageSysWechatPayInput : BasePageInput /// order_id /// /// - public string? OrderId { get; set; } = "-1"; + public string? OrderId { get; set; } /// /// order_status /// /// - public string? OrderStatus { get; set; } = "-1"; + public string? OrderStatus { get; set; } /// /// out_trade_number diff --git a/Admin.NET/Admin.NET.Core/Service/Wechat/SysWechatPayService.cs b/Admin.NET/Admin.NET.Core/Service/Wechat/SysWechatPayService.cs index 4fa2f986..7916c334 100644 --- a/Admin.NET/Admin.NET.Core/Service/Wechat/SysWechatPayService.cs +++ b/Admin.NET/Admin.NET.Core/Service/Wechat/SysWechatPayService.cs @@ -15,6 +15,20 @@ namespace Admin.NET.Core.Service; [ApiDescriptionSettings(Order = 210, Description = "微信支付")] public class SysWechatPayService : IDynamicApiController, ITransient { + private static List wechatPayEventHandlers = new List(); + + /// + /// 注册支付记录变化事件处理器 + /// + /// 处理器 + /// 排序,数据越大越先执行 + public static void AddPayEventInterceptor(WechatPayEventInterceptor eh, int order) + { + eh.Order = order; + wechatPayEventHandlers.Add(eh); + wechatPayEventHandlers.Sort((a, b) => b.Order - a.Order); + } + private readonly SqlSugarRepository _sysWechatPayRep; private readonly SqlSugarRepository _sysWechatRefundRep; private readonly WechatPayOptions _wechatPayOptions; @@ -250,6 +264,82 @@ public class SysWechatPayService : IDynamicApiController, ITransient return await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == tradeId); } + /// + /// 获取支付订单详情(微信接口) 🔖 + /// + /// + /// + [DisplayName("获取支付订单详情(微信接口)")] + public async Task GetPayInfoFromWechat(string tradeId) + { + var request = new GetPayTransactionByOutTradeNumberRequest(); + request.OutTradeNumber = tradeId; + var response = await _wechatTenpayClient.ExecuteGetPayTransactionByOutTradeNumberAsync(request); + // 修改订单支付状态 + var wechatPayOld = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == response.OutTradeNumber + && u.MerchantId == response.MerchantId); + SysWechatPay wechatPayNew = null; + if (wechatPayOld != null) + wechatPayNew = wechatPayOld.DeepCopy(); + // 如果状态不一致就更新数据库中的记录 + if (wechatPayNew != null && wechatPayNew.TradeState != response.TradeState) + { + wechatPayNew.OpenId = response.Payer?.OpenId; + wechatPayNew.TransactionId = response.TransactionId; // 支付订单号 + wechatPayNew.TradeType = response.TradeType; // 交易类型 + wechatPayNew.TradeState = response.TradeState; // 交易状态 + wechatPayNew.TradeStateDescription = response.TradeStateDescription; // 交易状态描述 + wechatPayNew.BankType = response.BankType; // 付款银行类型 + if (response.Amount != null) + { + wechatPayNew.Total = response.Amount.Total; // 订单总金额 + wechatPayNew.PayerTotal = response.Amount.PayerTotal; // 用户支付金额 + } + if (response.SuccessTime.HasValue) + wechatPayNew.SuccessTime = response.SuccessTime.Value.DateTime; // 支付完成时间 + else + wechatPayNew.SuccessTime = DateTime.Now; + await _sysWechatPayRep.AsUpdateable(wechatPayNew).IgnoreColumns(true).ExecuteCommandAsync(); + } + if (wechatPayOld == null || wechatPayOld.TradeState!=wechatPayNew.TradeState) + { + //没必要等所有回调事件处理完再返回给微信,开一个Task执行 + Task.Run(async () => + { + foreach (var eh in wechatPayEventHandlers) + { + try + { + if (!await eh.PayInforChanged(wechatPayOld, wechatPayNew)) + break; + } + catch (Exception ex) + { + $"GetPayInfoFromWechat 中执行微信支付回调{eh.GetType().Name}出错".LogError(ex); + } + } + }).Start(); + } + // 下面这里创建一个新的对象,是因为不想把全部字段都返回 + wechatPayNew = new SysWechatPay() + { + AppId = _wechatPayOptions.AppId, + MerchantId = _wechatPayOptions.MerchantId, + SubAppId = _wechatPayOptions.AppId, + SubMerchantId = _wechatPayOptions.MerchantId, + OutTradeNumber = request.OutTradeNumber, + Attachment = response.Attachment, + TransactionId = response.TransactionId, + TradeType = response.TradeType, // 交易类型 + TradeState = response.TradeState, // 交易状态 + TradeStateDescription = response.TradeStateDescription, // 交易状态描述 + BankType = response.BankType, // 付款银行类型 + SuccessTime = response.SuccessTime.HasValue ? response.SuccessTime.Value.DateTime : DateTime.Now // 支付完成时间 + }; + + return wechatPayNew; + } + /// /// 微信支付成功回调(商户直连) 🔖 /// @@ -269,35 +359,97 @@ public class SysWechatPayService : IDynamicApiController, ITransient var callbackResource = _wechatTenpayClient.DecryptEventResource(callbackModel); // 修改订单支付状态 - var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber + var wechatPayOld = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber && u.MerchantId == callbackResource.MerchantId); - if (wechatPay == null) return null; - //wechatPay.OpenId = callbackResource.Payer.OpenId; // 支付者标识 - //wechatPay.MerchantId = callbackResource.MerchantId; // 微信商户号 - //wechatPay.OutTradeNumber = callbackResource.OutTradeNumber; // 商户订单号 - wechatPay.TransactionId = callbackResource.TransactionId; // 支付订单号 - wechatPay.TradeType = callbackResource.TradeType; // 交易类型 - wechatPay.TradeState = callbackResource.TradeState; // 交易状态 - wechatPay.TradeStateDescription = callbackResource.TradeStateDescription; // 交易状态描述 - wechatPay.BankType = callbackResource.BankType; // 付款银行类型 - wechatPay.Total = callbackResource.Amount.Total; // 订单总金额 - wechatPay.PayerTotal = callbackResource.Amount.PayerTotal; // 用户支付金额 - wechatPay.SuccessTime = callbackResource.SuccessTime; // 支付完成时间 - - await _sysWechatPayRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync(); + if (wechatPayOld == null) return null; + var wechatPayNew = wechatPayOld.DeepCopy(); + if (callbackResource.Payer!=null) + wechatPayNew.OpenId = callbackResource.Payer.OpenId; // 支付者标识 + wechatPayNew.TransactionId = callbackResource.TransactionId; // 支付订单号 + wechatPayNew.TradeType = callbackResource.TradeType; // 交易类型 + wechatPayNew.TradeState = callbackResource.TradeState; // 交易状态 + wechatPayNew.TradeStateDescription = callbackResource.TradeStateDescription; // 交易状态描述 + wechatPayNew.BankType = callbackResource.BankType; // 付款银行类型 + wechatPayNew.Total = callbackResource.Amount.Total; // 订单总金额 + wechatPayNew.PayerTotal = callbackResource.Amount.PayerTotal; // 用户支付金额 + wechatPayNew.SuccessTime = callbackResource.SuccessTime; // 支付完成时间 + await _sysWechatPayRep.AsUpdateable(wechatPayNew).IgnoreColumns(true).ExecuteCommandAsync(); + //因为这个是回调给微信的,所以这里没必要等所有回调事件处理完再返回给微信,开一个Task执行 + if (wechatPayOld.TradeState != wechatPayNew.TradeState) + { + Task.Run(async () => + { + foreach (var eh in wechatPayEventHandlers) + { + try + { + if (!await eh.PayInforChanged(wechatPayOld, wechatPayNew)) + break; + } + catch (Exception ex) + { + $"PayCallBack 中执行微信支付回调{eh.GetType().Name}出错".LogError(ex); + } + } + }).Start(); + } return new WechatPayOutput() { - Total = wechatPay.Total, - Attachment = wechatPay.Attachment, - GoodsTag = wechatPay.GoodsTag, - OrderId = long.Parse(wechatPay.OrderId) + Total = wechatPayNew.Total, + Attachment = wechatPayNew.Attachment, + GoodsTag = wechatPayNew.GoodsTag, + OrderId = long.Parse(wechatPayNew.OrderId) }; } return null; } + /// + /// 微信退款回调(商户直连) 🔖 + /// + /// + [AllowAnonymous] + [DisplayName("微信退款回调(商户直连)")] + public async Task RefundCallBack() + { + using var ms = new MemoryStream(); + await App.HttpContext.Request.Body.CopyToAsync(ms); + var b = ms.ToArray(); + var callbackJson = Encoding.UTF8.GetString(b); + + var callbackModel = _wechatTenpayClient.DeserializeEvent(callbackJson); + if ("REFUND.SUCCESS".Equals(callbackModel.EventType)) + { + //参考:https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/refund-result-notice.html + try + { + var callbackRefundResource = _wechatTenpayClient.DecryptEventResource(callbackModel); + // 修改订单支付状态 + var wechatRefund = await _sysWechatRefundRep.GetFirstAsync(u => u.OutRefundNumber == callbackRefundResource.OutRefundNumber); + if (wechatRefund == null) return null; + wechatRefund.RefundStatus = callbackRefundResource.RefundStatus; // 交易状态 + wechatRefund.SuccessTime = callbackRefundResource.SuccessTime.Value.DateTime; // 支付完成时间 + + await _sysWechatRefundRep.AsUpdateable(wechatRefund).IgnoreColumns(true).ExecuteCommandAsync(); + // 有退款,刷新一下订单状态(通过主动查询Wechat接口获取) + // 通过 GetPayInfoFromWechat 也会触发 WechatPayEventHandler,所以这个回调中不用主动调用 + await GetPayInfoFromWechat(callbackRefundResource.OutTradeNumber); + } + catch (Exception ex) + { + "微信退款回调时出错:".LogError(ex); + } + } + else + { + callbackModel.EventType.LogInformation(); + } + + return null; + } + /// /// 微信支付成功回调(服务商模式) 🔖 /// @@ -317,22 +469,43 @@ public class SysWechatPayService : IDynamicApiController, ITransient var callbackResource = _wechatTenpayClient.DecryptEventResource(callbackModel); // 修改订单支付状态 - var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber + var wechatPayOld = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber && u.MerchantId == callbackResource.MerchantId); - if (wechatPay == null) return; + + if (wechatPayOld == null) return; + var wechatPayNew = wechatPayOld.DeepCopy(); //wechatPay.OpenId = callbackResource.Payer.OpenId; // 支付者标识 //wechatPay.MerchantId = callbackResource.MerchantId; // 微信商户号 //wechatPay.OutTradeNumber = callbackResource.OutTradeNumber; // 商户订单号 - wechatPay.TransactionId = callbackResource.TransactionId; // 支付订单号 - wechatPay.TradeType = callbackResource.TradeType; // 交易类型 - wechatPay.TradeState = callbackResource.TradeState; // 交易状态 - wechatPay.TradeStateDescription = callbackResource.TradeStateDescription; // 交易状态描述 - wechatPay.BankType = callbackResource.BankType; // 付款银行类型 - wechatPay.Total = callbackResource.Amount.Total; // 订单总金额 - wechatPay.PayerTotal = callbackResource.Amount.PayerTotal; // 用户支付金额 - wechatPay.SuccessTime = callbackResource.SuccessTime; // 支付完成时间 + wechatPayNew.TransactionId = callbackResource.TransactionId; // 支付订单号 + wechatPayNew.TradeType = callbackResource.TradeType; // 交易类型 + wechatPayNew.TradeState = callbackResource.TradeState; // 交易状态 + wechatPayNew.TradeStateDescription = callbackResource.TradeStateDescription; // 交易状态描述 + wechatPayNew.BankType = callbackResource.BankType; // 付款银行类型 + wechatPayNew.Total = callbackResource.Amount.Total; // 订单总金额 + wechatPayNew.PayerTotal = callbackResource.Amount.PayerTotal; // 用户支付金额 + wechatPayNew.SuccessTime = callbackResource.SuccessTime; // 支付完成时间 - await _sysWechatPayRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync(); + await _sysWechatPayRep.AsUpdateable(wechatPayNew).IgnoreColumns(true).ExecuteCommandAsync(); + //因为这个是回调给微信的,所以这里没必要等所有回调事件处理完再返回给微信,开一个Task执行 + if (wechatPayOld.TradeState != wechatPayNew.TradeState) + { + Task.Run(async () => + { + foreach (var eh in wechatPayEventHandlers) + { + try + { + if (!await eh.PayInforChanged(wechatPayOld, wechatPayNew)) + break; + } + catch (Exception ex) + { + $"PayPartnerCallBack 中执行微信支付回调{eh.GetType().Name}出错".LogError(ex); + } + } + }).Start(); + } } } @@ -345,10 +518,16 @@ public class SysWechatPayService : IDynamicApiController, ITransient [DisplayName("微信退款申请)")] public async Task Refund(RefundRequestInput input) { + var vechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == input.OutTradeNumber); + if (vechatPay==null) + { + throw Oops.Bah("没有相应支付记录"); + } var request = new CreateRefundDomesticRefundRequest() { OutTradeNumber = input.OutTradeNumber, OutRefundNumber = "REFUND_" + DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff"), + NotifyUrl = _payCallBackOptions.WechatRefundUrl, Amount = new CreateRefundDomesticRefundRequest.Types.Amount() { Total = input.Total, @@ -359,7 +538,15 @@ public class SysWechatPayService : IDynamicApiController, ITransient var response = await _wechatTenpayClient.ExecuteCreateRefundDomesticRefundAsync(request); if (!response.IsSuccessful()) + { + // 退款失败,该单可能已经退款了,所以主动查询微信接口更新状态 + try + { + await this.GetPayInfoFromWechat(input.OutTradeNumber); + } + catch (Exception ex) { } throw Oops.Oh($"JSAPI 退款申请失败(状态码:{response.GetRawStatus()},错误代码:{response.ErrorCode},错误描述:{response.ErrorMessage})"); + } var wechatRefund = await _sysWechatRefundRep.GetFirstAsync(u => u.OutTradeNumber == input.OutTradeNumber); if (wechatRefund == null) @@ -367,15 +554,16 @@ public class SysWechatPayService : IDynamicApiController, ITransient // 保存退款申请信息 wechatRefund = new SysWechatRefund() { - TransactionId = input.OutTradeNumber, - OutTradeNumber = request.OutTradeNumber, - OutRefundNo = request.OutTradeNumber, // 每笔付款只退一次,所以这里直接用付款单号 + TransactionId = vechatPay.TransactionId, + OutTradeNumber = input.OutTradeNumber, + OutRefundNumber = request.OutRefundNumber, // 每笔付款只退一次,所以这里直接用付款单号 Reason = request.Reason, Refund = input.Refund, + RefundId = response.RefundId, Total = input.Total, - //NotifyUrl = "", + NotifyUrl = _payCallBackOptions.WechatRefundUrl, OrderId = input.OrderId, - OrderStatus = input.OrderStatus, + RefundStatus = input.OrderStatus, MerchantGoodsId = input.MerchantGoodsId, GoodsName = input.GoodsName, UnitPrice = input.UnitPrice, @@ -385,6 +573,8 @@ public class SysWechatPayService : IDynamicApiController, ITransient Remark = input.Remark }; await _sysWechatRefundRep.InsertAsync(wechatRefund); + // 发送了退款请求也要更新原定单的状态(从微信查询) + await this.GetPayInfoFromWechat(input.OutTradeNumber); } } @@ -530,10 +720,14 @@ public class SysWechatPayService : IDynamicApiController, ITransient /// 根据支付Id获取退款信息列表 🔖 /// /// + /// < /// [DisplayName("根据支付Id获取退款信息列表")] - public async Task> GetRefundList([FromQuery] string transactionId) + public async Task> GetRefundList([FromQuery] string transactionId, [FromQuery] string outTradeNumber ) { - return await _sysWechatRefundRep.AsQueryable().Where(u => u.TransactionId == transactionId).ToListAsync(); + return await _sysWechatRefundRep.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(transactionId), u => u.TransactionId == transactionId) + .WhereIF(!string.IsNullOrEmpty(outTradeNumber), u=> u.OutTradeNumber == outTradeNumber) + .ToListAsync(); } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Web.Core/Startup.cs b/Admin.NET/Admin.NET.Web.Core/Startup.cs index b7b2ad8e..d3eb775e 100644 --- a/Admin.NET/Admin.NET.Web.Core/Startup.cs +++ b/Admin.NET/Admin.NET.Web.Core/Startup.cs @@ -253,6 +253,9 @@ public class Startup : AppStartup // 注册启动执行任务 services.AddHostedService(); services.AddHostedService(); + + // 下面代码演示,引入自己的微信息支付信息变化事件处理器 + Admin.NET.Core.Service.SysWechatPayService.AddPayEventInterceptor(new WechatPayEventInterceptor(), int.MaxValue); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) diff --git a/Web/src/api-services/apis/sys-wechat-pay-api.ts b/Web/src/api-services/apis/sys-wechat-pay-api.ts index 793674d2..650cc607 100644 --- a/Web/src/api-services/apis/sys-wechat-pay-api.ts +++ b/Web/src/api-services/apis/sys-wechat-pay-api.ts @@ -174,6 +174,55 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config options: localVarRequestOptions, }; }, + /** + * + * @summary 获取支付订单详情(微信接口) 🔖 + * @param {string} tradeId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiSysWechatPayPayInfoFromWechatTradeIdGet: async (tradeId: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'tradeId' is not null or undefined + if (tradeId === null || tradeId === undefined) { + throw new RequiredError('tradeId','Required parameter tradeId was null or undefined when calling apiSysWechatPayPayInfoFromWechatTradeIdGet.'); + } + const localVarPath = `/api/sysWechatPay/payInfoFromWechat/{tradeId}` + .replace(`{${"tradeId"}}`, encodeURIComponent(String(tradeId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, 'https://example.com'); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + if (configuration && configuration.accessToken) { + const accessToken = typeof configuration.accessToken === 'function' + ? await configuration.accessToken() + : await configuration.accessToken; + localVarHeaderParameter["Authorization"] = "Bearer " + accessToken; + } + + const query = new URLSearchParams(localVarUrlObj.search); + for (const key in localVarQueryParameter) { + query.set(key, localVarQueryParameter[key]); + } + for (const key in options.params) { + query.set(key, options.params[key]); + } + localVarUrlObj.search = (new URLSearchParams(query)).toString(); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash, + options: localVarRequestOptions, + }; + }, /** * * @summary 获取支付订单详情 🔖 @@ -559,12 +608,56 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config }, /** * - * @summary 根据支付Id获取退款信息列表 🔖 - * @param {string} [transactionId] + * @summary 微信退款回调(商户直连) 🔖 * @param {*} [options] Override http request option. * @throws {RequiredError} */ - apiSysWechatPayRefundListGet: async (transactionId?: string, options: AxiosRequestConfig = {}): Promise => { + apiSysWechatPayRefundCallBackPost: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/sysWechatPay/refundCallBack`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, 'https://example.com'); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + if (configuration && configuration.accessToken) { + const accessToken = typeof configuration.accessToken === 'function' + ? await configuration.accessToken() + : await configuration.accessToken; + localVarHeaderParameter["Authorization"] = "Bearer " + accessToken; + } + + const query = new URLSearchParams(localVarUrlObj.search); + for (const key in localVarQueryParameter) { + query.set(key, localVarQueryParameter[key]); + } + for (const key in options.params) { + query.set(key, options.params[key]); + } + localVarUrlObj.search = (new URLSearchParams(query)).toString(); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash, + options: localVarRequestOptions, + }; + }, + /** + * + * @summary 根据支付Id获取退款信息列表 + * @param {string} [transactionId] + * @param {string} [outTradeNumber] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiSysWechatPayRefundListGet: async (transactionId?: string, outTradeNumber?: string, options: AxiosRequestConfig = {}): Promise => { const localVarPath = `/api/sysWechatPay/refundList`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, 'https://example.com'); @@ -589,6 +682,10 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config localVarQueryParameter['transactionId'] = transactionId; } + if (outTradeNumber !== undefined) { + localVarQueryParameter['outTradeNumber'] = outTradeNumber; + } + const query = new URLSearchParams(localVarUrlObj.search); for (const key in localVarQueryParameter) { query.set(key, localVarQueryParameter[key]); @@ -703,6 +800,20 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) { return axios.request(axiosRequestArgs); }; }, + /** + * + * @summary 获取支付订单详情(微信接口) 🔖 + * @param {string} tradeId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId, options); + return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; + return axios.request(axiosRequestArgs); + }; + }, /** * * @summary 获取支付订单详情 🔖 @@ -816,13 +927,27 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) { }, /** * - * @summary 根据支付Id获取退款信息列表 🔖 - * @param {string} [transactionId] + * @summary 微信退款回调(商户直连) 🔖 * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysWechatPayRefundListGet(transactionId?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { - const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayRefundListGet(transactionId, options); + async apiSysWechatPayRefundCallBackPost(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayRefundCallBackPost(options); + return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; + return axios.request(axiosRequestArgs); + }; + }, + /** + * + * @summary 根据支付Id获取退款信息列表 + * @param {string} [transactionId] + * @param {string} [outTradeNumber] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayRefundListGet(transactionId?: string, outTradeNumber?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayRefundListGet(transactionId, outTradeNumber, options); return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; return axios.request(axiosRequestArgs); @@ -880,6 +1005,16 @@ export const SysWechatPayApiFactory = function (configuration?: Configuration, b async apiSysWechatPayPayCallBackPost(options?: AxiosRequestConfig): Promise> { return SysWechatPayApiFp(configuration).apiSysWechatPayPayCallBackPost(options).then((request) => request(axios, basePath)); }, + /** + * + * @summary 获取支付订单详情(微信接口) 🔖 + * @param {string} tradeId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId: string, options?: AxiosRequestConfig): Promise> { + return SysWechatPayApiFp(configuration).apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId, options).then((request) => request(axios, basePath)); + }, /** * * @summary 获取支付订单详情 🔖 @@ -961,13 +1096,23 @@ export const SysWechatPayApiFactory = function (configuration?: Configuration, b }, /** * - * @summary 根据支付Id获取退款信息列表 🔖 - * @param {string} [transactionId] + * @summary 微信退款回调(商户直连) 🔖 * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysWechatPayRefundListGet(transactionId?: string, options?: AxiosRequestConfig): Promise> { - return SysWechatPayApiFp(configuration).apiSysWechatPayRefundListGet(transactionId, options).then((request) => request(axios, basePath)); + async apiSysWechatPayRefundCallBackPost(options?: AxiosRequestConfig): Promise> { + return SysWechatPayApiFp(configuration).apiSysWechatPayRefundCallBackPost(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary 根据支付Id获取退款信息列表 + * @param {string} [transactionId] + * @param {string} [outTradeNumber] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayRefundListGet(transactionId?: string, outTradeNumber?: string, options?: AxiosRequestConfig): Promise> { + return SysWechatPayApiFp(configuration).apiSysWechatPayRefundListGet(transactionId, outTradeNumber, options).then((request) => request(axios, basePath)); }, /** * @@ -1021,6 +1166,17 @@ export class SysWechatPayApi extends BaseAPI { public async apiSysWechatPayPayCallBackPost(options?: AxiosRequestConfig) : Promise> { return SysWechatPayApiFp(this.configuration).apiSysWechatPayPayCallBackPost(options).then((request) => request(this.axios, this.basePath)); } + /** + * + * @summary 获取支付订单详情(微信接口) 🔖 + * @param {string} tradeId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SysWechatPayApi + */ + public async apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId: string, options?: AxiosRequestConfig) : Promise> { + return SysWechatPayApiFp(this.configuration).apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId, options).then((request) => request(this.axios, this.basePath)); + } /** * * @summary 获取支付订单详情 🔖 @@ -1110,14 +1266,25 @@ export class SysWechatPayApi extends BaseAPI { } /** * - * @summary 根据支付Id获取退款信息列表 🔖 - * @param {string} [transactionId] + * @summary 微信退款回调(商户直连) 🔖 * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SysWechatPayApi */ - public async apiSysWechatPayRefundListGet(transactionId?: string, options?: AxiosRequestConfig) : Promise> { - return SysWechatPayApiFp(this.configuration).apiSysWechatPayRefundListGet(transactionId, options).then((request) => request(this.axios, this.basePath)); + public async apiSysWechatPayRefundCallBackPost(options?: AxiosRequestConfig) : Promise> { + return SysWechatPayApiFp(this.configuration).apiSysWechatPayRefundCallBackPost(options).then((request) => request(this.axios, this.basePath)); + } + /** + * + * @summary 根据支付Id获取退款信息列表 + * @param {string} [transactionId] + * @param {string} [outTradeNumber] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SysWechatPayApi + */ + public async apiSysWechatPayRefundListGet(transactionId?: string, outTradeNumber?: string, options?: AxiosRequestConfig) : Promise> { + return SysWechatPayApiFp(this.configuration).apiSysWechatPayRefundListGet(transactionId, outTradeNumber, options).then((request) => request(this.axios, this.basePath)); } /** * diff --git a/Web/src/api-services/models/sys-wechat-refund.ts b/Web/src/api-services/models/sys-wechat-refund.ts index 628fc180..b0e147f7 100644 --- a/Web/src/api-services/models/sys-wechat-refund.ts +++ b/Web/src/api-services/models/sys-wechat-refund.ts @@ -106,7 +106,7 @@ export interface SysWechatRefund { * @type {string} * @memberof SysWechatRefund */ - outRefundNo: string; + outRefundNumber: string; /** * 退款原因,示例:商品已售完 @@ -162,7 +162,15 @@ export interface SysWechatRefund { * @type {string} * @memberof SysWechatRefund */ - orderStatus?: string | null; + refundStatus?: string | null; + + /** + * 支完成时间 + * + * @type {Date} + * @memberof SysWechatRefund + */ + successTime?: Date | null; /** * 关联的商户商品编码 diff --git a/Web/src/views/system/weChatPay/index.vue b/Web/src/views/system/weChatPay/index.vue index a1ea84af..fb0aba34 100644 --- a/Web/src/views/system/weChatPay/index.vue +++ b/Web/src/views/system/weChatPay/index.vue @@ -10,7 +10,7 @@ - 查询 + 查询 重置 @@ -31,10 +31,12 @@ + @@ -45,13 +47,14 @@ size="small" text type="primary" - v-if="scope.row.qrcodeContent != null && scope.row.qrcodeContent != '' && (scope.row.tradeState === '' || !scope.row.tradeState)" + v-if="scope.row.qrcodeContent != null && scope.row.qrcodeContent != '' && (scope.row.tradeState === '' || !scope.row.tradeState || scope.row.tradeState=='NOTPAY')" @click="openQrDialog(scope.row.qrcodeContent)" > 付款二维码 查看退款 全额退款 + 刷新 @@ -75,16 +78,19 @@ 新增模拟数据 - + - + + + + - + - + @@ -134,7 +140,7 @@