关于 stigg-webhooks
stigg-webhooks 是用于接收和处理 Stigg Webhook 的技能,面向实现事件处理程序的开发者。内容涵盖验证密钥、去重、重试和乱序处理。
主要功能
- 01注册 Webhook 端点
- 02使用密钥验证来源
- 03按 messageId 去重
- 04处理重试与乱序事件
- 05覆盖订阅、试用和额度事件
适用场景
- 01接收订阅生命周期通知
- 02处理试用和额度变化
- 03构建幂等的事件处理程序
MCP 相关
文档建议使用 Stigg 文档 MCP 查询事件定义;该技能本身不是 MCP 服务。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ stiggio/ skills --skill stigg-webhooks安装后在 Claude Code 中输入/stigg-webhooks确认已加载。
附带文件references/event-catalog.mdreferences/handler-patterns.md
详细介绍
Stigg Webhooks — 接收和处理事件
Stigg 通过 Webhooks 通知你的应用发生的变更,包括订阅生命周期、试用状态转换、信用额度余额阈值、自动充值尝试、权益用量超限等。本技能介绍如何接收这些事件——注册端点、验证真实性、处理重试,以及了解载荷信封结构。
开始之前
根据总览 stigg 技能的要求:先搜索。 Webhook 事件名称和载荷会不断演变。使用 Mintlify Stigg 文档 MCP,通过 query_docs_filesystem_stigg 查询 /documentation/native-integrations/webhooks/events.mdx 及各事件的参考页面,确认确切的载荷架构后再编写处理程序代码。
注册 Webhook
在 Stigg 应用中:Settings → Integrations → Webhooks → + New webhook。
| 字段 | 说明 |
|---|---|
| 服务名称 | 便于识别的标签(例如“Production webhooks”“Dev”)。 |
| 端点 URL | 你的处理程序,例如 https://yourapp.com/api/stigg/webhooks。必须在 30 秒内响应 2XX,否则 Stigg 会重试。 |
| 要发送的事件 | 从目录中选择(订阅、试用、信用额度、权益、客户等)。 |
创建的 Webhook 会立即生效。在连接真实事件之前,使用 Send test event(特定事件上的 ⋮ 菜单)验证处理程序。
验证真实性 — 核验密钥
每个 Webhook 事件都会携带一个标头:
Stigg-Webhooks-Secret: <secret>
将此标头的值与 Webhook 详情页面显示的密钥进行比较。两者必须匹配。
HMAC 签名支持已列入 Stigg 的路线图。 目前,验证方式是直接比较密钥——请像对待 API 密钥一样保护该密钥(存放在环境变量中,绝不要写入源码)。
载荷信封
每个 Webhook 事件都具有以下顶层结构(具体细节因事件而异;请核对对应事件的页面):
{
"messageId": "msg_abc123", // unique per event delivery — use for idempotency
"type": "subscription.created", // event type
"createdAt": "2026-01-15T10:30:00Z",
"data": { /* event-specific payload */ }
}
不同事件类型的确切字段名称可能略有不同——务必对照实时事件参考页面(/documentation/native-integrations/webhooks/events.mdx 及其各事件子页面)确认。
幂等性 — 通过 messageId 去重
Stigg 可能会多次发送同一事件(重试、网络问题、边缘情况)。请务必:
- 从载荷中读取
messageId。 - 在去重存储中检查该 ID(Redis、数据库行、幂等性表)。
- 如果已处理,立即返回 200——不要再次执行处理程序。
- 如果是新事件,则处理该事件,然后记录已处理的
messageId。
不保证顺序
Stigg 不保证事件的投递顺序。你的处理程序必须能够容忍事件乱序:
subscription.canceled可能会先于时间上发生在它之前的对应subscription.updated到达。credit.balance.depleted可能会在后续额度已发放之后才到达。
如果顺序很重要,请从 Stigg API 获取最新状态,而不是根据事件流重建状态。
重试行为
如果端点返回非 2XX 状态码或超时(>30 秒),Stigg 会重试:
- 立即重试 3 次(无退避)。
- 再每隔 30 秒重试 3 次。
总计失败 6 次后,该事件将被标记为失败。失败事件会存储在 Stigg 后端,可根据请求重新发送(请联系支持团队;自助重放界面已列入路线图)。Stigg 还会主动监控 Webhook 投递失败情况,并在失败率飙升时联系你。
务必快速返回 200。 确认已收到事件后,再将工作加入异步队列。处理复杂逻辑的同步处理程序可能会导致 30 秒超时和不必要的重试。
IP 允许列表
Webhook 事件来自 Stigg 的 IP 地址。截至撰写本文时:18.119.35.43。该列表可能会变化——在固定 IP 地址之前,请重新获取 /documentation/native-integrations/webhooks/index.mdx 中的信息。
事件目录(按领域)
完整事件列表位于 /documentation/native-integrations/webhooks/events.mdx。请重新获取规范列表;以下是按领域整理的精选映射:
| 领域 | 常见事件 |
|---|---|
| 客户 | customer.created、customer.updated、customer.deleted、customer.payment_failed、payment_method.attached、payment_method.detached |
| 订阅 | subscription.created、subscription.updated、subscription.canceled、subscription.creation_failed、subscription.expired_non_recurring、billing.month_ends_soon、subscription.spend_limit_exceeded |
| 试用 | trial.started、trial.ends_soon(到期前 7 天)、trial.expired、trial.converted |
| 权益 | entitlement.usage_exceeded、entitlements.updated |
| 额度 — 余额 | credit.balance.low、credit.balance.depleted |
| 额度 — 授予 | credit.grant.created、credit.grant.updated、credit.grant.depleted、credit.grant.expired、credit.grant.balance_low |
| 额度 — 自动充值 | automatic_recharge.operation.attempted、credits.automatic_recharge_limit_exceeded(达到上限的 80/90/100%)、automatic_recharge.configuration.changed |
| 促销权益 | promotional_entitlement.granted、promotional_entitlement.updated、promotional_entitlement.revoked、promotional_entitlement.expired、promotional_entitlement.ends_soon |
| 目录 | plan.created、plan.updated_new_version_published、plan.deleted、addon.created、addon.updated_new_version_published、addon.deleted、feature.created、feature.updated、feature.deleted、coupon.created、coupon.updated、coupon.archived |
| 第三方 | third_party_sync_failed |
确切的事件名称可能会变化——请务必查阅文档再次确认。
处理程序骨架(Next.js App Router + Node)
// app/api/stigg/webhooks/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { redis } from '@/lib/redis';
const SECRET = process.env.STIGG_WEBHOOK_SECRET!;
export async function POST(req: NextRequest) {
// 1. Verify the secret
const headerSecret = req.headers.get('Stigg-Webhooks-Secret');
if (headerSecret !== SECRET) {
return NextResponse.json({ error: 'Invalid secret' }, { status: 401 });
}
const event = await req.json();
const { messageId, type, data } = event;
// 2. Idempotency
const seen = await redis.set(
`stigg:webhook:${messageId}`,
'1',
{ NX: true, EX: 60 * 60 * 24 * 7 }, // 7-day window
);
if (!seen) {
return NextResponse.json({ ok: true, dedup: true }); // already processed
}
// 3. Acknowledge fast — queue heavy work async
await queue.enqueue({ type, data });
return NextResponse.json({ ok: true });
}
处理程序应在约 500ms 内完成;所有实际工作都交给工作进程处理。Stigg 只关心是否收到 2XX 响应。
何时不应使用此技能
- 向外调用 Stigg API(配置、控制访问、报告)——请使用
stigg-api、stigg-subscriptions、stigg-entitlements、stigg-credits。 - 监听前端状态变更(结账后刷新缓存等)——这属于 SDK 的职责,而非 Webhook 的职责。
- 设置 Stigg MCP 服务——请使用
stigg-mcp。
常见错误
| 错误 | 修正方法 |
|---|---|
| 跳过签名验证 | Stigg-Webhooks-Secret 标头是目前唯一的真实性检查方式。请进行比对。 |
| 在处理程序中同步处理 | 尽快返回 2XX;将繁重工作异步加入队列。同步处理可能导致 30 秒超时。 |
| 假设事件有序 | Stigg 明确不保证事件顺序。请容忍乱序,或从 API 获取最新状态。 |
未对 messageId 做幂等处理 | Stigg 会在失败时重试——如果不去重,同一事件会被处理两次。 |
| 只依赖 IP 允许列表 | IP 列表可能变化。请同时使用 IP 允许列表和密钥验证。 |
| 因为“无法识别此事件”而返回 4XX | 这会触发重试。请返回 2XX,并静默忽略未知事件类型。 |
| 手动编写 HMAC 验证 | 目前尚未提供 HMAC 支持——此功能已列入路线图。目前的约定是直接比对明文密钥。 |
| 未处理投递失败 | 如果 Stigg 的 6 次尝试均失败,事件会被存储,但不会自动重放。请联系支持团队重新发送;对于持续失败,请设置运维告警。 |
| 将 Webhook 视为唯一事实来源 | 事件顺序没有保证,重放也无法自助完成。请将 Webhook 与定期对照 Stigg API 状态的机制结合使用。 |
| 订阅“所有事件” | 这会产生大量噪声,增加你这边的成本。请只选择实际需要处理的事件。 |