用途:该技能面向需要接收与验证 NMI(Network Merchants)Webhook 的开发者,适用于搭建 NMI Webhook 处理程序、调试 Webhook-Signature 验证失败,以及处理 transaction.sale.success、transaction.auth.success、transaction.refund.success、transaction.void.success 等事件。
主要能力:NMI 不使用 Standard Webhooks 规范,每次投递携带单个自定义头 Webhook-Signature: t=<nonce>,s=<hex>。其核心要点为:t 是随机 nonce 而非时间戳,NMI 未提供重放/时间容忍窗口,不要按 Unix 时间解析 t 来拒绝旧投递;签名内容为 "<nonce>.<raw_body>",验证方式是对 nonce、字面量 . 与未经解析的原始请求体做 HMAC-SHA256(以签名密钥为密钥),十六进制编码后与 s 做时序安全比较,重新序列化 JSON 会破坏 HMAC。负载信封为 { "event_id", "event_type", "event_body" },event_type 为点分小写字符串。事件命名遵循 transaction.<action>.<result>,action 可为 sale、auth、capture、void、refund、credit、validate,result 可为 success、failure、unknown。
使用方式:提供 Node.js 的 verifyNmiWebhook(rawBody, signatureHeader, signingKey) 验证函数(代码保持原样,见下方)。环境变量为 NMI_SIGNING_KEY=your_webhook_signing_key,签名密钥在 NMI Merchant Control Panel 的 Settings → Webhooks 生成,与网关 API/security key 不同。本地开发可用 npx hookdeck-cli listen 3000 nmi --path /webhooks/nmi 启动隧道,并将打印的公网 URL 注册为端点 URL,再运行测试交易查看投递。示例处理程序见 examples/express/、examples/nextjs/、examples/fastapi/;参考材料见 references/overview.md、references/setup.md、references/verification.md。NMI 无官方 SDK,各语言均需手动验证。建议配合 webhook-handler-patterns 技能处理调用顺序、幂等、错误处理与重试逻辑(NMI 会重试失败投递,同一 event_id 可能到达两次;快速返回 2xx)。
限制:仅在先通过签名校验后再解析 JSON;必须使用原始请求体验证;不得将 t 视为时间戳;无官方 SDK。输出示例:验证函数 verifyNmiWebhook 的完整实现保留于原始资料。