This commit is contained in:
zuohuaijun 2024-07-01 10:37:56 +08:00
commit 46d81dd0a7
5 changed files with 531 additions and 57 deletions

View File

@ -11,8 +11,21 @@ namespace Admin.NET.Core;
/// </summary>
[SugarTable(null, "系统微信支付表")]
[SysTable]
[SugarIndex("sys_wechat_pay_order_id", nameof(OrderId), OrderByType.Desc)]
public partial class SysWechatPay : EntityBase
{
/// <summary>
/// 关联的商户订单号
/// </summary>
[SugarColumn(ColumnDescription = "OrderId")]
public virtual long OrderId { get; set; }
/// <summary>
/// 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款)
/// </summary>
[SugarColumn(ColumnDescription = "OrderStatus")]
public virtual int OrderStatus { get; set; }
/// <summary>
/// 微信商户号
/// </summary>
@ -154,7 +167,7 @@ public partial class SysWechatPay : EntityBase
/// <summary>
/// 子商户AppId
/// </summary>
[SugarColumn(ColumnDescription = "回调通知地址")]
[SugarColumn(ColumnDescription = "子商户AppId")]
public string? SubAppId { get; set; }
/// <summary>

View File

@ -0,0 +1,121 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 微信退款表
/// </summary>
[SugarTable(null, "系统微信退款表")]
[SysTable]
[SugarIndex("sys_wechat_refund_order_id", nameof(OrderId), OrderByType.Desc)]
public class SysWechatRefund : EntityBase
{
/// <summary>
/// 微信支付订单号(原支付交易对应的微信订单号)
/// </summary>
[SugarColumn(ColumnDescription = "微信支付订单号", Length = 32)]
[Required]
public string TransactionId { get; set; }
/// <summary>
/// 商户订单号(原交易对应的商户付款单号)
/// </summary>
[SugarColumn(ColumnDescription = "商户付款单号", Length = 32)]
[Required]
public string OutTradeNumber { get; set; }
/// <summary>
/// 商户系统内部的退款单号商户系统内部唯一只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
/// </summary>
[SugarColumn(ColumnDescription = "商户退款单号", Length = 64)]
[Required]
public string OutRefundNo { get; set; }
/// <summary>
/// 退款原因,示例:商品已售完
/// </summary>
[SugarColumn(ColumnDescription = "退款原因", Length = 80)]
public string Reason { get; set; }
/// <summary>
/// 退款金额
/// </summary>
[SugarColumn(ColumnDescription = "退款金额")]
public int Refund { get; set; }
/// <summary>
/// 原订单总金额
/// </summary>
[SugarColumn(ColumnDescription = "订单总金额")]
public int Total { get; set; }
/// <summary>
/// 退款结果回调url
/// </summary>
[SugarColumn(ColumnDescription = "退款结果回调url", Length = 256)]
public string? NotifyUrl { get; set; }
/// <summary>
/// 退款资金来源, 可不传,默认使用未结算资金退款(仅对老资金流商户适用)
/// </summary>
[SugarColumn(ColumnDescription = "退款资金来源", Length = 32)]
public string FundsAccount { get; set; }
/// <summary>
/// 关联的商户订单号
/// </summary>
[SugarColumn(ColumnDescription = "关联的用户订单号")]
public long OrderId { get; set; }
/// <summary>
/// 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款)
/// </summary>
[SugarColumn(ColumnDescription = "关联的商户订单状态")]
public int OrderStatus { get; set; }
/// <summary>
/// 关联的商户商品编码
/// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品编码", Length = 32)]
public string MerchantGoodsId { get; set; }
/// <summary>
/// 关联的商户商品名称
/// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品名称", Length = 256)]
public string GoodsName { get; set; }
/// <summary>
/// 关联的商户商品单价
/// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品单价")]
public int UnitPrice { get; set; }
/// <summary>
/// 关联的商户商品退款金额
/// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品退款金额")]
public int RefundAmount { get; set; }
/// <summary>
/// 关联的商户商品退货数量
/// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品退货数量")]
public int RefundQuantity { get; set; } = 1;
/// <summary>
/// 附加数据
/// </summary>
[SugarColumn(ColumnDescription = "附加数据")]
public string? Attachment { get; set; }
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注")]
public string? Remark { get; set; }
}

View File

@ -32,6 +32,16 @@ public class WechatPayTransactionInput
/// 优惠标记
/// </summary>
public string GoodsTag { get; set; }
/// <summary>
/// 关联的商户订单号
/// </summary>
public long OrderId { get; set; }
/// <summary>
/// 关联的商户订单付款状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款)
/// </summary>
public int OrderStatus { get; set; } = 0;
}
public class WechatPayParaInput
@ -40,4 +50,95 @@ public class WechatPayParaInput
/// 订单Id
/// </summary>
public string PrepayId { get; set; }
}
public class RefundRequestInput // : WechatTenpayRequest
{
/// <summary>
/// 商户订单号(原支付交易对应的付款单号)
/// </summary>
public string OutTradeNumber { get; set; }
///// <summary>
///// 退款单号
///// </summary>
//public string OutRefundNumber { get; set; }
/// <summary>
/// 原订单金额(分)
/// </summary>
public int Total { get; set; }
/// <summary>
/// 退款金额(分)
/// </summary>
public int Refund { get; set; }
/// <summary>
/// 退款原因
/// </summary>
public string Reason { get; set; }
/// <summary>
/// 关联的商户订单号
/// </summary>
public long OrderId { get; set; }
/// <summary>
/// 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款)
/// </summary>
public int OrderStatus { get; set; }
/// <summary>
/// 关联的商户商品编码
/// </summary>
public string MerchantGoodsId { get; set; }
/// <summary>
/// 关联的商户商品名称
/// </summary>
public string GoodsName { get; set; }
/// <summary>
/// 关联的商户商品单价
/// </summary>
public int UnitPrice { get; set; } = 0;
/// <summary>
/// 关联的商户商品退款金额
/// </summary>
public int RefundAmount { get; set; } = 0;
/// <summary>
/// 关联的商户商品退货数量
/// </summary>
public int RefundQuantity { get; set; } = 1;
/// <summary>
/// 附加数据
/// </summary>
public string Attachment { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
}
public class PageSysWechatPayInput : BasePageInput
{
/// <summary>
/// order_id
/// </summary>
/// <example></example>
public long? OrderId { get; set; } = -1;
/// <summary>
/// order_status
/// </summary>
/// <example></example>
public long? OrderStatus { get; set; } = -1;
/// <summary>
/// out_trade_number
/// </summary>
/// <example></example>
public string OutTradeNumber { get; set; }
/// <summary>
/// success_time范围
/// </summary>
/// <example></example>
public List<DateTime?> SuccessTimeRange { get; set; }
/// <summary>
/// expire_time范围
/// </summary>
/// <example></example>
public List<DateTime?> ExpireTimeRange { get; set; }
}

View File

@ -12,19 +12,51 @@ public class WechatPayOutput
/// OpenId
/// </summary>
public string OpenId { get; set; }
/// <summary>
/// 商户(支付交易)单号,微信唯一
/// </summary>
public string OutTradeNumber { get; set; }
/// <summary>
/// 关联的商户(商品交易)订单号
/// </summary>
public long OrderId { get; set; }
/// <summary>
/// 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款)
/// </summary>
public int OrderStatus { get; set; }
/// <summary>
/// 订单金额
/// </summary>
public int Total { get; set; }
/// <summary>
/// 附加数据
/// </summary>
public string Attachment { get; set; }
/// <summary>
/// 优惠标记
/// </summary>
public string GoodsTag { get; set; }
}
/// <summary>
/// 支付发起时间
/// </summary>
public DateTimeOffset CreateTime { get; set; }
/// <summary>
/// 支付完成时间
/// </summary>
public DateTimeOffset SuccessTime { get; set; }
/// <summary>
/// 交易状态(支付成功后,微信返回)
/// </summary>
public string? TradeState { get; set; }
/// <summary>
/// 交易状态描述(支付成功后,微信返回)
/// </summary>
public string? TradeStateDescription { get; set; }
}
public class CreatePayTransactionOutput
{
public string PrepayId { get; set; }
public string OutTradeNumber { get; set; }
}

View File

@ -12,18 +12,20 @@ namespace Admin.NET.Core.Service;
[ApiDescriptionSettings(Order = 210)]
public class SysWechatPayService : IDynamicApiController, ITransient
{
private readonly SqlSugarRepository<SysWechatPay> _sysWechatPayUserRep;
private readonly SqlSugarRepository<SysWechatPay> _sysWechatPayRep;
private readonly SqlSugarRepository<SysWechatRefund> _sysWechatRefundRep;
private readonly WechatPayOptions _wechatPayOptions;
private readonly PayCallBackOptions _payCallBackOptions;
private readonly WechatTenpayClient _wechatTenpayClient;
public SysWechatPayService(SqlSugarRepository<SysWechatPay> sysWechatPayUserRep,
IOptions<WechatPayOptions> wechatPayOptions,
IOptions<PayCallBackOptions> payCallBackOptions)
public SysWechatPayService(SqlSugarRepository<SysWechatPay> sysWechatPayRep
, SqlSugarRepository<SysWechatRefund> sysWechatRefundRep
, IOptions<WechatPayOptions> wechatPayOptions
, IOptions<PayCallBackOptions> payCallBackOptions)
{
_sysWechatPayUserRep = sysWechatPayUserRep;
_sysWechatPayRep = sysWechatPayRep;
this._sysWechatRefundRep = sysWechatRefundRep;
_wechatPayOptions = wechatPayOptions.Value;
_payCallBackOptions = payCallBackOptions.Value;
@ -64,11 +66,20 @@ public class SysWechatPayService : IDynamicApiController, ITransient
/// 微信支付统一下单获取Id(商户直连) 🔖
/// </summary>
[DisplayName("微信支付统一下单获取Id(商户直连)")]
public async Task<dynamic> CreatePayTransaction([FromBody] WechatPayTransactionInput input)
public async Task<CreatePayTransactionOutput> CreatePayTransaction([FromBody] WechatPayTransactionInput input)
{
string outTradeNumber = DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff") + (new Random()).Next(100, 1000); // 微信需要的订单号(唯一)
//检查订单信息是否已存在(使用“商户交易单号+状态”唯一性判断)
var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OrderId == input.OrderId && u.OrderStatus == input.OrderStatus);
if (wechatPay != null)
{
outTradeNumber = wechatPay.OutTradeNumber;
}
var request = new CreatePayTransactionJsapiRequest()
{
OutTradeNumber = DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff") + (new Random()).Next(100, 1000), // 订单号
OutTradeNumber = outTradeNumber,
AppId = _wechatPayOptions.AppId,
Description = input.Description,
Attachment = input.Attachment,
@ -80,27 +91,32 @@ public class SysWechatPayService : IDynamicApiController, ITransient
};
var response = await _wechatTenpayClient.ExecuteCreatePayTransactionJsapiAsync(request);
if (!response.IsSuccessful())
throw Oops.Oh(response.ErrorMessage);
throw Oops.Oh<Exception>(response.ErrorMessage);
// 保存订单信息
var wechatPay = new SysWechatPay()
if (wechatPay == null)
{
AppId = _wechatPayOptions.AppId,
MerchantId = _wechatPayOptions.MerchantId,
OutTradeNumber = request.OutTradeNumber,
Description = input.Description,
Attachment = input.Attachment,
GoodsTag = input.GoodsTag,
Total = input.Total,
OpenId = input.OpenId,
TransactionId = ""
};
await _sysWechatPayUserRep.InsertAsync(wechatPay);
// 保存订单信息
wechatPay = new SysWechatPay()
{
AppId = _wechatPayOptions.AppId,
MerchantId = _wechatPayOptions.MerchantId,
OutTradeNumber = request.OutTradeNumber,
Description = input.Description,
Attachment = input.Attachment,
GoodsTag = input.GoodsTag,
Total = input.Total,
OpenId = input.OpenId,
TransactionId = "",
OrderId = input.OrderId,
OrderStatus = input.OrderStatus
};
await _sysWechatPayRep.InsertAsync(wechatPay);
}
return new
return new CreatePayTransactionOutput
{
response.PrepayId,
request.OutTradeNumber
PrepayId = response.PrepayId,
OutTradeNumber = request.OutTradeNumber
};
}
@ -108,11 +124,20 @@ public class SysWechatPayService : IDynamicApiController, ITransient
/// 微信支付统一下单获取Id(服务商模式) 🔖
/// </summary>
[DisplayName("微信支付统一下单获取Id(服务商模式)")]
public async Task<dynamic> CreatePayPartnerTransaction([FromBody] WechatPayTransactionInput input)
public async Task<CreatePayTransactionOutput> CreatePayPartnerTransaction([FromBody] WechatPayTransactionInput input)
{
string outTradeNumber = DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff") + (new Random()).Next(100, 1000); // 微信需要的订单号(唯一)
//检查订单信息是否已存在(使用“商户交易单号+状态”唯一性判断)
var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OrderId == input.OrderId && u.OrderStatus == input.OrderStatus);
if (wechatPay != null)
{
outTradeNumber = wechatPay.OutTradeNumber;
}
var request = new CreatePayPartnerTransactionJsapiRequest()
{
OutTradeNumber = DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff") + (new Random()).Next(100, 1000), // 订单号
OutTradeNumber = outTradeNumber,
AppId = _wechatPayOptions.AppId,
MerchantId = _wechatPayOptions.MerchantId,
SubAppId = _wechatPayOptions.AppId,
@ -127,29 +152,31 @@ public class SysWechatPayService : IDynamicApiController, ITransient
};
var response = await _wechatTenpayClient.ExecuteCreatePayPartnerTransactionJsapiAsync(request);
if (!response.IsSuccessful())
throw Oops.Oh(response.ErrorMessage);
// 保存订单信息
var wechatPay = new SysWechatPay()
throw Oops.Oh<Exception>($"JSAPI 下单失败(状态码:{response.GetRawStatus()},错误代码:{response.ErrorCode},错误描述:{response.ErrorMessage}");
if (wechatPay == null)
{
AppId = _wechatPayOptions.AppId,
MerchantId = _wechatPayOptions.MerchantId,
SubAppId = _wechatPayOptions.AppId,
SubMerchantId = _wechatPayOptions.MerchantId,
OutTradeNumber = request.OutTradeNumber,
Description = input.Description,
Attachment = input.Attachment,
GoodsTag = input.GoodsTag,
Total = input.Total,
OpenId = input.OpenId,
TransactionId = ""
};
await _sysWechatPayUserRep.InsertAsync(wechatPay);
// 保存订单信息
wechatPay = new SysWechatPay()
{
AppId = _wechatPayOptions.AppId,
MerchantId = _wechatPayOptions.MerchantId,
SubAppId = _wechatPayOptions.AppId,
SubMerchantId = _wechatPayOptions.MerchantId,
OutTradeNumber = request.OutTradeNumber,
Description = input.Description,
Attachment = input.Attachment,
GoodsTag = input.GoodsTag,
Total = input.Total,
OpenId = input.OpenId,
TransactionId = ""
};
await _sysWechatPayRep.InsertAsync(wechatPay);
}
return new
return new CreatePayTransactionOutput
{
response.PrepayId,
request.OutTradeNumber
PrepayId = response.PrepayId,
OutTradeNumber = request.OutTradeNumber
};
}
@ -161,7 +188,7 @@ public class SysWechatPayService : IDynamicApiController, ITransient
[DisplayName("获取支付订单详情")]
public async Task<SysWechatPay> GetPayInfo(string tradeId)
{
return await _sysWechatPayUserRep.GetFirstAsync(u => u.OutTradeNumber == tradeId);
return await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == tradeId);
}
/// <summary>
@ -183,7 +210,7 @@ public class SysWechatPayService : IDynamicApiController, ITransient
var callbackResource = _wechatTenpayClient.DecryptEventResource<TransactionResource>(callbackModel);
// 修改订单支付状态
var wechatPay = await _sysWechatPayUserRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber
var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber
&& u.MerchantId == callbackResource.MerchantId);
if (wechatPay == null) return null;
//wechatPay.OpenId = callbackResource.Payer.OpenId; // 支付者标识
@ -198,7 +225,7 @@ public class SysWechatPayService : IDynamicApiController, ITransient
wechatPay.PayerTotal = callbackResource.Amount.PayerTotal; // 用户支付金额
wechatPay.SuccessTime = callbackResource.SuccessTime; // 支付完成时间
await _sysWechatPayUserRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
await _sysWechatPayRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
return new WechatPayOutput()
{
@ -230,7 +257,7 @@ public class SysWechatPayService : IDynamicApiController, ITransient
var callbackResource = _wechatTenpayClient.DecryptEventResource<PartnerTransactionResource>(callbackModel);
// 修改订单支付状态
var wechatPay = await _sysWechatPayUserRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber
var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber
&& u.MerchantId == callbackResource.MerchantId);
if (wechatPay == null) return;
//wechatPay.OpenId = callbackResource.Payer.OpenId; // 支付者标识
@ -245,7 +272,187 @@ public class SysWechatPayService : IDynamicApiController, ITransient
wechatPay.PayerTotal = callbackResource.Amount.PayerTotal; // 用户支付金额
wechatPay.SuccessTime = callbackResource.SuccessTime; // 支付完成时间
await _sysWechatPayUserRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
await _sysWechatPayRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
}
}
/// <summary>
/// 退款申请
/// https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/create.html
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("微信退款申请)")]
public async Task Refund(RefundRequestInput input)
{
var request = new CreateRefundDomesticRefundRequest()
{
OutTradeNumber = input.OutTradeNumber,
OutRefundNumber = "REFUND_" + DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff"),
Amount = new CreateRefundDomesticRefundRequest.Types.Amount()
{
Total = input.Total,
Refund = input.Refund
},
Reason = input.Reason,
};
var response = await _wechatTenpayClient.ExecuteCreateRefundDomesticRefundAsync(request);
if (!response.IsSuccessful())
throw Oops.Oh<Exception>($"JSAPI 退款申请失败(状态码:{response.GetRawStatus()},错误代码:{response.ErrorCode},错误描述:{response.ErrorMessage}");
var wechatRefund = await _sysWechatRefundRep.GetFirstAsync(u => u.OutTradeNumber == input.OutTradeNumber);
if (wechatRefund == null)
{
// 保存退款申请信息
wechatRefund = new SysWechatRefund()
{
TransactionId = input.OutTradeNumber,
OutTradeNumber = request.OutTradeNumber,
OutRefundNo = request.OutTradeNumber, //每笔付款只退一次,所以这里直接用付款单号
Reason = request.Reason,
Refund = input.Refund,
Total = input.Total,
//NotifyUrl = "",
OrderId = input.OrderId,
OrderStatus = input.OrderStatus,
MerchantGoodsId = input.MerchantGoodsId,
GoodsName = input.GoodsName,
UnitPrice = input.UnitPrice,
RefundAmount = input.RefundAmount,
RefundQuantity = input.RefundQuantity,
Attachment = input.Attachment,
Remark = input.Remark
};
await _sysWechatRefundRep.InsertAsync(wechatRefund);
}
}
/// <summary>
/// 查询单笔退款(通过商户退款单号)
/// https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/query-by-out-refund-no.html
/// </summary>
/// <param name="outRefundNumber"></param>
/// <returns></returns>
[DisplayName("微信查询单笔退款)")]
public async Task<GetRefundDomesticRefundByOutRefundNumberResponse> GetRefundByOutRefundNumber(string outRefundNumber)
{
var request = new GetRefundDomesticRefundByOutRefundNumberRequest()
{
OutRefundNumber = outRefundNumber
};
return await _wechatTenpayClient.ExecuteGetRefundDomesticRefundByOutRefundNumberAsync(request);
}
/// <summary>
/// 微信支付订单号查询(校正)
/// https://api.mch.weixin.qq.com/v3/pay/transactions/id/{transaction_id}
/// </summary>
/// <param name="transactionId"></param>
/// <returns></returns>
[DisplayName("微信支付订单号查询(校正)")]
public async Task<WechatPayOutput> GetPayTransactionByIdAsync(string transactionId)
{
var request = new GetPayTransactionByIdRequest()
{
MerchantId = _wechatPayOptions.MerchantId,
TransactionId = transactionId,
WechatpayCertificateSerialNumber = _wechatPayOptions.MerchantCertificateSerialNumber
};
var response = await _wechatTenpayClient.ExecuteGetPayTransactionByIdAsync(request);
if (response.TradeState == "SUCCESS")
{
// 修正订单支付状态
var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.TransactionId == transactionId && u.MerchantId == request.MerchantId);
if (wechatPay != null && string.IsNullOrEmpty(wechatPay.TradeState))
{
wechatPay.TransactionId = response.TransactionId; // 支付订单号
wechatPay.TradeType = response.TradeType; // 交易类型
wechatPay.TradeState = response.TradeState; // 交易状态
wechatPay.TradeStateDescription = response.TradeStateDescription; // 交易状态描述
wechatPay.BankType = response.BankType; // 付款银行类型
wechatPay.Total = response.Amount.Total; // 订单总金额
wechatPay.PayerTotal = response.Amount.PayerTotal; // 用户支付金额
wechatPay.SuccessTime = response.SuccessTime; // 支付完成时间
await _sysWechatPayRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
return wechatPay.Adapt<WechatPayOutput>();
}
}
return response.Adapt<WechatPayOutput>();
}
/// <summary>
/// 商户订单号查询(校正)
/// https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}
/// </summary>
/// <param name="outTradeNumber"></param>
/// <returns></returns>
[DisplayName("微信商户订单号查询(校正)")]
public async Task<WechatPayOutput> GetPayTransactionByOutTradeNumberAsync(string outTradeNumber)
{
var request = new GetPayTransactionByOutTradeNumberRequest()
{
MerchantId = _wechatPayOptions.MerchantId,
OutTradeNumber = outTradeNumber,
WechatpayCertificateSerialNumber = _wechatPayOptions.MerchantCertificateSerialNumber
};
var response = await _wechatTenpayClient.ExecuteGetPayTransactionByOutTradeNumberAsync(request);
if (response.TradeState == "SUCCESS")
{
// 修正订单支付状态
var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == outTradeNumber && u.MerchantId == request.MerchantId);
if (wechatPay != null && string.IsNullOrEmpty(wechatPay.TradeState))
{
wechatPay.TransactionId = response.TransactionId; // 支付订单号
wechatPay.TradeType = response.TradeType; // 交易类型
wechatPay.TradeState = response.TradeState; // 交易状态
wechatPay.TradeStateDescription = response.TradeStateDescription; // 交易状态描述
wechatPay.BankType = response.BankType; // 付款银行类型
wechatPay.Total = response.Amount.Total; // 订单总金额
wechatPay.PayerTotal = response.Amount.PayerTotal; // 用户支付金额
wechatPay.SuccessTime = response.SuccessTime; // 支付完成时间
await _sysWechatPayRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
return wechatPay.Adapt<WechatPayOutput>();
}
}
return response.Adapt<WechatPayOutput>();
}
/// <summary>
/// 获取支付记录列表(分页)
/// </summary>
/// <param name="input">PageSysWechatPayInput</param>
/// <returns></returns>
[DisplayName("获取支付记录列表(分页)")]
public async Task<SqlSugarPagedList<SysWechatPay>> PageAsync(PageSysWechatPayInput input)
{
var query = _sysWechatPayRep.AsQueryable()
.WhereIF(input.OrderId > 0, u => u.OrderId == input.OrderId)
.WhereIF(input.OrderStatus > 0, u => u.OrderStatus == input.OrderStatus)
.WhereIF(!string.IsNullOrWhiteSpace(input.OutTradeNumber), u => u.OutTradeNumber.Contains(input.OutTradeNumber.Trim()));
if (input.SuccessTimeRange != null && input.SuccessTimeRange.Count > 0)
{
DateTime? start = input.SuccessTimeRange[0];
query = query.WhereIF(start.HasValue, u => u.SuccessTime > start);
if (input.SuccessTimeRange.Count > 1 && input.SuccessTimeRange[1].HasValue)
{
var end = input.SuccessTimeRange[1].Value.AddDays(1);
query = query.Where(u => u.SuccessTime < end);
}
}
if (input.ExpireTimeRange != null && input.ExpireTimeRange.Count > 0)
{
DateTime? start = input.ExpireTimeRange[0];
query = query.WhereIF(start.HasValue, u => u.ExpireTime > start);
if (input.ExpireTimeRange.Count > 1 && input.ExpireTimeRange[1].HasValue)
{
var end = input.ExpireTimeRange[1].Value.AddDays(1);
query = query.Where(u => u.ExpireTime < end);
}
}
query = query.OrderByDescending(u => u.CreateTime);
return await query.ToPagedListAsync(input.Page, input.PageSize);
}
}