如何在 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 存入数据库,并在处理前检查其是否已存在。

  1. 检查 事件 ID 是否已经存在。
  2. 如果已存在 → 忽略该 webhook。
  3. 如果不存在 → 处理 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 支付集成没有实现幂等性,它本身就是脆弱的设计。

一个帮助处理这些场景的轻量级审计日志组件已为早期开发者提供:

Download here

0 浏览
Back to Blog

相关文章

阅读更多 »

开发者对幂等性的误解

快速提问:一个在后续调用中返回 404 的 DELETE endpoint 是否是幂等的?如果你因为响应变化而说不是,那么这篇 article 适合你。Idem…