feat: 优化支付宝回调通知记录功能

- 新增SignStr字段记录支付宝回调的原始签名字符串
- 修改日志记录格式,使用键值对形式记录回调通知数据
- 更新PayManager.RecordPayNoticeAsync方法支持记录原始签名字符串
- 移除AlipayManager中冗余的注释说明
This commit is contained in:
chenchun
2025-08-13 18:21:05 +08:00
parent f0cf6bf5c8
commit 2b3fad16fd
4 changed files with 19 additions and 8 deletions

View File

@@ -79,14 +79,15 @@ public class PayService : ApplicationService, IPayService
notifyData[item.Key] = item.Value.ToString(); notifyData[item.Key] = item.Value.ToString();
} }
_logger.LogInformation($"收到支付宝回调通知:{System.Text.Json.JsonSerializer.Serialize(notifyData)}"); var signStr = string.Join("&", notifyData.Select(kv => $"{kv.Key}={kv.Value}"));
_logger.LogInformation($"收到支付宝回调通知:{signStr}");
// 2. 验证签名 // 2. 验证签名
await _alipayManager.VerifyNotifyAsync(notifyData); await _alipayManager.VerifyNotifyAsync(notifyData);
// 3. 记录支付通知 // 3. 记录支付通知
await _payManager.RecordPayNoticeAsync(notifyData); await _payManager.RecordPayNoticeAsync(notifyData,signStr);
// 4. 更新订单状态 // 4. 更新订单状态
var outTradeNo = notifyData.GetValueOrDefault("out_trade_no", string.Empty); var outTradeNo = notifyData.GetValueOrDefault("out_trade_no", string.Empty);

View File

@@ -55,7 +55,6 @@ public class AlipayManager : DomainService
/// <exception cref="AlipayException"></exception> /// <exception cref="AlipayException"></exception>
public Task VerifyNotifyAsync(Dictionary<string, string> form) public Task VerifyNotifyAsync(Dictionary<string, string> form)
{ {
// 注意:不要对参数进行排序,保持支付宝回调的原始参数顺序
// 支付宝的验签需要保持原始参数顺序,排序会导致验签失败 // 支付宝的验签需要保持原始参数顺序,排序会导致验签失败
var result = Factory.Payment.Common().VerifyNotify(form); var result = Factory.Payment.Common().VerifyNotify(form);
if (result == false) if (result == false)

View File

@@ -55,4 +55,10 @@ public class PayNoticeRecordAggregateRoot: FullAuditedAggregateRoot<Guid>
/// </summary> /// </summary>
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)] [SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string NotifyData { get; set; } = string.Empty; public string NotifyData { get; set; } = string.Empty;
/// <summary>
/// 原始signstr
/// </summary>
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string SignStr { get; set; }
} }

View File

@@ -12,10 +12,10 @@ namespace Yi.Framework.AiHub.Domain.Managers;
/// </summary> /// </summary>
public class PayManager : DomainService public class PayManager : DomainService
{ {
private readonly ISqlSugarRepository<PayNoticeRecordAggregateRoot, Guid> _payNoticeRepository; private readonly ISqlSugarRepository<PayNoticeRecordAggregateRoot, Guid> _payNoticeRepository;
private readonly ICurrentUser _currentUser; private readonly ICurrentUser _currentUser;
private readonly ISqlSugarRepository<PayOrderAggregateRoot, Guid> _payOrderRepository; private readonly ISqlSugarRepository<PayOrderAggregateRoot, Guid> _payOrderRepository;
public PayManager( public PayManager(
ISqlSugarRepository<PayNoticeRecordAggregateRoot, Guid> payNoticeRepository, ISqlSugarRepository<PayNoticeRecordAggregateRoot, Guid> payNoticeRepository,
ICurrentUser currentUser, ISqlSugarRepository<PayOrderAggregateRoot, Guid> payOrderRepository) ICurrentUser currentUser, ISqlSugarRepository<PayOrderAggregateRoot, Guid> payOrderRepository)
@@ -82,26 +82,31 @@ public class PayManager : DomainService
{ {
order.TradeNo = tradeNo; order.TradeNo = tradeNo;
} }
await _payOrderRepository.UpdateAsync(order); await _payOrderRepository.UpdateAsync(order);
} }
/// <summary> /// <summary>
/// 记录支付通知 /// 记录支付通知
/// </summary> /// </summary>
/// <param name="notifyData">通知数据</param> /// <param name="notifyData">通知数据</param>
/// <param name="signStr"></param>
/// <returns></returns> /// <returns></returns>
public async Task RecordPayNoticeAsync(Dictionary<string, string> notifyData) public async Task RecordPayNoticeAsync(Dictionary<string, string> notifyData, string signStr)
{ {
var payNotice = new PayNoticeRecordAggregateRoot var payNotice = new PayNoticeRecordAggregateRoot
{ {
NotifyTime =DateTime.Parse(notifyData.GetValueOrDefault("notify_time", string.Empty)) , NotifyTime = DateTime.Parse(notifyData.GetValueOrDefault("notify_time", string.Empty)),
TradeNo = notifyData.GetValueOrDefault("trade_no", string.Empty), TradeNo = notifyData.GetValueOrDefault("trade_no", string.Empty),
OutTradeNo = notifyData.GetValueOrDefault("out_trade_no", string.Empty), OutTradeNo = notifyData.GetValueOrDefault("out_trade_no", string.Empty),
BuyerId = notifyData.GetValueOrDefault("buyer_id", string.Empty), BuyerId = notifyData.GetValueOrDefault("buyer_id", string.Empty),
TradeStatus = ParseTradeStatus(notifyData.GetValueOrDefault("trade_status", string.Empty)), TradeStatus = ParseTradeStatus(notifyData.GetValueOrDefault("trade_status", string.Empty)),
TotalAmount = decimal.TryParse(notifyData.GetValueOrDefault("total_amount", "-1"), out var amount) ? amount : 0, TotalAmount = decimal.TryParse(notifyData.GetValueOrDefault("total_amount", "-1"), out var amount)
? amount
: 0,
NotifyData = JsonSerializer.Serialize(notifyData), NotifyData = JsonSerializer.Serialize(notifyData),
SignStr = signStr
}; };
await _payNoticeRepository.InsertAsync(payNotice); await _payNoticeRepository.InsertAsync(payNotice);