跳到主要内容

Webhooks 集成

Webhook 用于在 GStable 侧发生重要变更时主动通知你的服务端(例如支付会话状态变化、结算完成等)。你只需提供稳定的 HTTPS 地址、订阅所需的事件类型,并在校验签名后处理 JSON 载荷,无需高频轮询业务接口。

本文是落地集成指南,分为两部分:

  1. 管理侧 — 使用 gstable-jsclient.webhook 维护端点配置。
  2. 投递侧 — 实现 HTTP 处理逻辑:校验快速返回 2xx异步执行业务

载荷结构、请求头与签名字符串构造等细节以 API 文档为准,请务必阅读 校验与处理。下文侧重要做什么推荐顺序,不展开内部实现细节。

前置条件

  • Node.js 18+gstable-js包与模块格式)。
  • 具备在商户侧管理 WebhookAPI 密钥
  • 可对外提供 HTTPS 公网地址(生产环境需受信任证书),能接收 POST,并在校验路径下读取原始请求体(未经框架提前改写)。
  • 已确认要订阅的 事件类型subscribedEvents 中的字符串需与列表完全一致

推荐集成顺序

  1. 设计 — 列出业务要响应的结果(如订单标记已支付、释放库存),映射到 事件列表 中的 eventType
  2. 先实现接收端(建议预发环境) — 完成路由:校验签名与时间戳、解析信封、尽快返回 2xx、将任务放入队列。
  3. 注册端点 — 调用 client.webhook.create,填写 HTTPS URL、可读名称与 subscribedEvents
  4. 保管签名密钥 — 响应中的 key 用于校验入站请求;写入密钥管理服务或仅限校验服务读取的环境变量,入库日志、提交到代码仓库。
  5. 上线 — 生产环境指向同一套处理逻辑;按计划或应急使用 refreshKey;维护窗口可 disable 端点暂停投递。
  6. 运维 — 关注投递失败与死信;以 eventId去重(至少一次投递语义)。

第一部分 — 使用 gstable-js 管理端点

通过 client.webhook 维护 GStable 存量的回调配置:URL、订阅事件、描述、启停、轮换密钥等。

目标调用
注册 URL 与事件client.webhook.create(body)
全量更新名称、URL、事件等client.webhook.update(body)
列举与审计client.webhook.list()
查看单个端点client.webhook.detail(webhookId)
暂停投递client.webhook.disable(webhookId)
恢复投递client.webhook.enable(webhookId)
轮换签名密钥client.webhook.refreshKey(webhookId)旧密钥立即失效
删除配置client.webhook.remove(webhookId)

create 用于新增update 一般为整包替换(需带齐必填字段)。字段说明见 Webhooks(SDK API)

示例 — 注册生产端点

import { GStableClient } from 'gstable-js';

const client = new GStableClient({ apiKey: process.env.GSTABLE_API_KEY });

const hook = await client.webhook.create({
webhookName: 'Production ledger',
webhookUrl: 'https://api.example.com/v1/webhooks/gstable',
subscribedEvents: ['payment.completed', 'payment.failed'],
webhookDescription: '订单与财务消费方',
});

// 持久化 hook.webhookId,供后续 update / disable 使用。
// hook.key 仅存于密钥系统 — 用于校验入站 Webhook。

事件名必须完全一致

subscribedEvents 中的每一项须与 事件列表 一致;拼写错误或不受支持的名字无法按预期触发。

密钥轮换建议

  • refreshKey旧密钥即刻作废,仍可能在途的请求使用旧密钥极短时间。
  • 可考虑轮换窗口内短时双密钥、先 disable 再轮换、或在轮换前排空队列。
  • 轮换完成后,务必更新校验服务使用的密钥(环境变量/密钥库)。

第二部分 — 接收并处理回调

SDK 不会替你校验入站 Webhook。你的服务需要:

1. 与注册信息一致的 URL

  • 生产环境 HTTPS、证书受信。
  • 响应 POST,正文为 JSON(统一信封字段如 eventIdeventTypepayload 等见 校验与处理)。

2. 用「原始 body」做签名

签名字符串必须与 GStable 实际发送的字节序列一致。若框架在校验前已解析 JSON,可能导致签名校验失败。请按文档使用 x-gstable-timestampx-gstable-signature

3. 先校验,再执行业务

严格按 校验与处理 构造待签名字符串、计算 HMAC、常量时间比对,并按需校验时间戳重放窗口

仅在确认无效请求时返回 4xx,并理解其与重试策略的关系(见下节)。

4. 快速应答

通过校验与基础校验后,应尽快返回 200–299。重数据库、调用第三方等耗时操作应异步化(队列/后台任务),避免 GStable 因超时而重试堆积。

5. 按「至少一次」设计幂等

同一逻辑事件可能投递多次。请使用 eventId(或其它稳定业务幂等键)在副作用前去重

6. 以载荷为准

结合 eventTypebusinessTypepayload 内文档化字段解析业务数据(例如会话类事件中的 sessionData 等)。


重试与错误响应

  • 当你的服务不可用或返回 5xx 时,平台通常会按策略退避重试(具体以 Webhook 产品文档为准)。
  • 校验失败返回 4xx 通常合理;若用 5xx 表示临时故障,应确保处理逻辑可安全重试

安全清单

  • TLS:生产勿用自签名证书。
  • 密钥:签名密钥仅存放在密钥系统/校验服务环境;人员变动时轮换。
  • 日志:_payload / 头信息做脱敏;绝不打印签名密钥。
  • 重放:若规范要求时间窗,应拒绝过期时间戳(详见校验文档)。

排查思路

现象建议检查
签名始终失败是否使用原始 body、密钥是否一致、字符串拼接与编码是否与文档一致。
重复扣款/重复更新是否缺少对 eventId 或业务键的幂等处理。
超时、重试风暴是否在 HTTP 线程内做重活 — 应异步化。
收不到事件URL 错误、证书问题、长期非 2xx 等。

延伸阅读