跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://waffo.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

事件类型

eventType说明
PAYMENT_NOTIFICATION支付完成或失败
REFUND_NOTIFICATION退款完成或失败
TOKENIZATION_NOTIFICATIONToken 生成、状态变更或卡片信息更新
SUBSCRIPTION_STATUS_NOTIFICATION订阅状态变更(激活、取消等,也用于订阅扣款事件)
SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION订阅周期变更
SUBSCRIPTION_CHANGE_NOTIFICATION订阅变更(升降级)完成

通用结构

所有 Webhook 使用相同的请求结构:
POST {notifyUrl}
Content-Type: application/json
X-SIGNATURE: {Waffo 私钥签名}

PAYMENT_NOTIFICATION

支付完成后通知。
{
  "eventType": "PAYMENT_NOTIFICATION",
  "acquiringOrderId": "ACQ123456",
  "merchantOrderId": "ORDER123",
  "paymentRequestId": "REQ123",
  "orderStatus": "PAY_SUCCESS",
  "orderAmount": "100.00",
  "orderCurrency": "USD",
  "finalDealAmount": "100.00"
}

REFUND_NOTIFICATION

退款完成后通知,发送到创建退款时的 refundNotifyUrl
{
  "eventType": "REFUND_NOTIFICATION",
  "acquiringRefundOrderId": "REF123456",
  "refundRequestId": "REFUND_REQ123",
  "refundStatus": "ORDER_FULLY_REFUNDED",
  "refundAmount": "100.00"
}

TOKENIZATION_NOTIFICATION

Tokenization 完成、Token 状态变更或 Token 卡片信息更新时通知,发送到调用 Generate Token 时传入的 notifyUrl
{
  "eventType": "TOKENIZATION_NOTIFICATION",
  "result": {
    "tokenRequestId": "202510111010050001",
    "tokenId": "tok_xxxxxxxxxxxx",
    "tokenType": "CARD",
    "tokenStatus": "UNVERIFIED",
    "tokenData": {
      "maskedCardInfo": "481852******0147",
      "cardHolderName": "Zhang san",
      "cardExpiry": "01/2030",
      "cardBin": "481852",
      "cardScheme": "VISA",
      "cardType": "CREDIT_CARD",
      "cardIssuerName": "INTL HDQTRS-CENTER OWNED",
      "cardIssueCountryCode": "RUS"
    },
    "billingAddress": {
      "countryCode": "USA",
      "region": "CA",
      "city": "Cupertino",
      "postalCode": "95014",
      "address": "One Apple Park Way"
    },
    "merchantUserId": "merchant-user-001",
    "merchantInfo": {
      "merchantId": "your_merchant_id",
      "subMerchantId": ""
    }
  }
}
字段说明
tokenRequestId商户发起 Tokenization 时传入的请求 ID。若状态变更由 Waffo 触发,该字段可能不存在
tokenIdToken ID。商户需安全保存,用于后续 Token 支付
tokenTypeToken 类型,目前为 CARD
tokenStatusToken 状态:UNVERIFIEDVERIFIEDEXPIREDSUSPENDED
tokenData卡片摘要信息,包括脱敏卡号、有效期、BIN、卡组织、卡类型、发卡行与发卡国家
billingAddress持卡人账单地址
merchantUserId商户侧用户 ID
merchantInfo商户信息

SUBSCRIPTION_STATUS_NOTIFICATION

当订阅状态发生变更时通知(包括激活、取消、扣款结果等)。
{
  "eventType": "SUBSCRIPTION_STATUS_NOTIFICATION",
  "subscriptionId": "SUB123456",
  "subscriptionStatus": "ACTIVE"
}
SDK 中可使用两种处理器:
  • onSubscriptionStatus() — 直接处理此事件
  • onSubscriptionPayment() — 当 onSubscriptionStatus 未注册时的降级处理

SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION

当订阅周期达到终态时通知,用于追踪续费结果。
{
  "eventType": "SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION",
  "subscriptionId": "SUB123456",
  "period": "3",
  "orderStatus": "PAY_SUCCESS"
}

SUBSCRIPTION_CHANGE_NOTIFICATION

订阅变更(升降级)完成时通知。
{
  "eventType": "SUBSCRIPTION_CHANGE_NOTIFICATION",
  "result": {
    "subscriptionRequest": "new-sub-req-001",
    "originSubscriptionRequest": "orig-sub-req-001",
    "subscriptionId": "waffo-sub-12345",
    "subscriptionChangeStatus": "SUCCESS",
    "subscriptionAction": "UPGRADE",
    "remainingAmount": "50.00",
    "currency": "HKD"
  }
}
subscriptionChangeStatus说明
SUCCESS变更成功
CLOSED变更失败/关闭

商户响应

所有 Webhook 必须返回 HTTP 200,body 为 {"message":"success"}且必须携带 X-SIGNATURE 响应头(用商户私钥签名响应 body)。
Waffo 同时验证 HTTP 状态码和响应 body。如果响应格式不正确或缺少签名,Waffo 会认为通知投递失败并重试。

使用 SDK(推荐)

SDK 的 handleWebhook() 方法自动处理签名验证、事件路由和响应签名:
const result = await waffo.webhook().handleWebhook(body, signature);
res.setHeader('X-SIGNATURE', result.responseSignature);
res.status(200).send(result.responseBody);

手动响应

如不使用 SDK,响应 body 必须是以下之一:
  • {"message":"success"} — 已成功处理
  • {"message":"failed"} — 处理失败,Waffo 将重试
  • {"message":"unknown"} — 状态未知,Waffo 将重试
重试策略failedunknown 时,Waffo 最多重试 8 次(含首次),间隔从 30 秒递增到 8 小时。详见 重试与失败恢复

订阅通知选择指南

订阅场景涉及三类通知,按需选择监听:
事件触发时机适合场景
SUBSCRIPTION_STATUS_NOTIFICATION订阅主单状态变更(激活、取消、关闭)管理订阅生命周期:开通/关闭用户权益
SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION每期续费的终态(重试过程不通知,仅最终结果)只关心每期最终结果,不关心中间重试
PAYMENT_NOTIFICATION每次支付订单(含首期 + 续期每次重试)了解每次扣款的失败原因、支付时间等详情
典型组合推荐:
  • 最小集成:监听 SUBSCRIPTION_STATUS_NOTIFICATION + SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION
  • 完整集成:三种都监听,用 PAYMENT_NOTIFICATION 获取每次重试的详细失败原因