事件类型
通用结构
所有 Webhook 使用相同的请求结构:
PAYMENT_NOTIFICATION
支付完成后通知。
REFUND_NOTIFICATION
退款完成后通知,发送到创建退款时的 refundNotifyUrl。
TOKENIZATION_NOTIFICATION
Tokenization 完成、Token 状态变更或 Token 卡片信息更新时通知,发送到调用 Generate Token 时传入的 notifyUrl。
SUBSCRIPTION_STATUS_NOTIFICATION
当订阅状态发生变更时通知(包括激活、取消、扣款结果等)。
SDK 中可使用两种处理器:
onSubscriptionStatus() — 直接处理此事件
onSubscriptionPayment() — 当 onSubscriptionStatus 未注册时的降级处理
SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION
当订阅周期达到终态时通知,用于追踪续费结果。
SUBSCRIPTION_CHANGE_NOTIFICATION
订阅变更(升降级)完成时通知。
商户响应
所有 Webhook 必须返回 HTTP 200,body 为 {"message":"success"},且必须携带 X-SIGNATURE 响应头(用商户私钥签名响应 body)。
Waffo 同时验证 HTTP 状态码和响应 body。如果响应格式不正确或缺少签名,Waffo 会认为通知投递失败并重试。
使用 SDK(推荐)
SDK 的 handleWebhook() 方法自动处理签名验证、事件路由和响应签名:
手动响应
如不使用 SDK,响应 body 必须是以下之一:
{"message":"success"} — 已成功处理
{"message":"failed"} — 处理失败,Waffo 将重试
{"message":"unknown"} — 状态未知,Waffo 将重试
重试策略:failed 或 unknown 时,Waffo 最多重试 8 次(含首次),间隔从 30 秒递增到 8 小时。详见 重试与失败恢复。
订阅通知选择指南
订阅场景涉及三类通知,按需选择监听:
SUBSCRIPTION_STATUS_NOTIFICATION 和 SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION 都是异步分发的 Webhook,受队列消费、重试、网络延迟等影响,到达顺序不保证;不要把回调到达顺序作为业务状态机依据。正确的处理方式(幂等去重、收到任一回调后先调用 subscription/inquiry 查询最终状态)见 处理最佳实践。
典型组合推荐:
- 最小集成:监听
SUBSCRIPTION_STATUS_NOTIFICATION + SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION
- 完整集成:三种都监听,用
PAYMENT_NOTIFICATION 获取每次重试的详细失败原因