如何在 ASP.NET Core 中处理重复的 Webhook 事件(幂等性指南)
发布: (2026年2月17日 GMT+8 17:39)
3 分钟阅读
原文: Dev.to
Source: Dev.to
为什么会出现重复的 Webhook
支付网关(例如 Worldpay、Stripe)会在以下情况下有意重试 webhook 调用:
- 您的端点超时
- 它们没有收到 200 OK 响应
- 网络出现问题
如果您的系统不是幂等的,重复事件可能会:
- 覆盖有效的支付状态
- 触发重复的业务逻辑
- 导致数据不一致
- 产生财务对账问题
在支付系统中,这非常危险。
什么是幂等性?
幂等性指对同一事件进行多次处理,最终状态保持不变。换句话说,无论事件被处理多少次,结果都是相同的。
ASP.NET Core 中的简易策略
一种可靠的方法是将每个 webhook 事件 ID 存入数据库,并在处理前检查其是否已存在。
- 检查 事件 ID 是否已经存在。
- 如果已存在 → 忽略该 webhook。
- 如果不存在 → 处理 webhook 并保存该 ID。
public async Task HandleWebhook(WebhookEvent webhook)
{
var exists = await _context.PaymentEvents
.AnyAsync(e => e.EventId == webhook.EventId);
if (exists)
return;
var paymentEvent = new PaymentEvent
{
EventId = webhook.EventId,
PaymentId = webhook.PaymentId,
Status = webhook.Status,
CreatedAt = DateTime.UtcNow
};
_context.PaymentEvents.Add(paymentEvent);
await _context.SaveChangesAsync();
// Continue business logic safely
}
这样可以确保重复的重试不会破坏状态。
超越基础日志记录
在生产系统中,您可能还需要捕获:
- 完整的状态转移跟踪
- 之前状态与新状态的对比
- 原始负载存储
- 来源追踪(Webhook / 手动 / API)
结构化审计日志在这些需求下变得至关重要。
最后思考
重复的 webhook 不是 bug,而是一种保证。
如果您的 ASP.NET Core 支付集成没有实现幂等性,它本身就是脆弱的设计。
一个帮助处理这些场景的轻量级审计日志组件已为早期开发者提供: