跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://developers-sandbox.uqpaytech.com/llms.txt

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

为什么使用 Webhook

在构建 UQPAY 集成时,你可能希望应用能在 UQPAY 账户发生事件时实时接收这些事件,从而让后端系统据此执行相应动作。 启用 Webhook 事件需要先注册 Webhook 端点。注册完成后,UQPAY 会在你的账户发生事件时,将实时事件数据推送到应用的 Webhook 端点。UQPAY 通过 HTTPS 向你的应用发送 Webhook 事件,payload 为包含 Event 对象的 JSON。 Webhook 特别适合监听异步事件,例如客户的银行确认支付、客户发起拒付、定期付款成功,以及订阅付款的收取场景。

前置条件

在阅读本文之前,请先在控制台完成 Webhook 端点设置

Webhook 请求头

UQPAY 发送到你 Webhook 端点 URL 的 HTTP POST payload 会包含以下特殊 header:
HEADER
DESCRIPTION
x-wk-timestampLong 型时间戳,例如 1711077773。
x-wk-signature响应体的 HMAC512 十六进制摘要。当 Webhook 配置了 secret 时,UQPAY 会带上该 header。HMAC512 摘要由 sha512 散列函数生成,并以 secret 作为 HMAC 的 key。

示例事件 payload

{
  "version": "V1.6.0",
  "event_name": "ISSUING",
  "event_type": "issuing.transaction.authorization",
  "event_id": "234fca01-1ace-4d34-baf5-29b10e9d11c0",
  "source_id": "1a53aebf-900c-4e25-9852-b98f4338d94c",
  "data": {
    "authorization_code": "W6MJU9",
    "billing_amount": "11.5",
    "billing_currency": "USD",
    "card_available_balance": "988.5",
    "card_id": "50418faa-57a8-4ce2-9157-621b00b13a3b",
    "card_number": "40963608****1764",
    "cardholder_id": "25ea804d-7fd5-43d5-8792-0fc0214cdb2f",
    "description": "",
    "fee_pass_through": "Y",
    "merchant_data": [
      {
        "category_code": "5734",
        "city": "",
        "country": "",
        "name": "Test Merchant"
      }
    ],
    "original_transaction_id": "",
    "posted_time": "2026-04-12T15:27:39.563+08:00",
    "short_transaction_id": "T260412-2AHV51KO5U68",
    "transaction_amount": "10",
    "transaction_currency": "USD",
    "transaction_fee": "1.5",
    "transaction_fee_currency": "USD",
    "transaction_id": "1a53aebf-900c-4e25-9852-b98f4338d94c",
    "transaction_status": "APPROVED",
    "transaction_time": "2026-04-12T15:27:39.48+08:00",
    "transaction_type": "AUTHORIZATION",
    "wallet_type": ""
  }
}

IP 白名单

UQPAY 从以下 IP 之一发起 Webhook 调用。要成功接收 Webhook,请将这些 IP 加入白名单:

沙箱环境

  • 52.76.137.90

生产环境

  • 18.143.59.6454.179.248.20513.250.234.8818.136.58.213

签名验证

UQPAY 从一组固定的 IP 地址发送 Webhook 事件。请仅信任来自这些 IP 的事件。 此外,通过验证 Webhook 签名来确认收到的事件确由 UQPAY 发送。UQPAY 会对发送给你端点的 Webhook 事件进行签名,把签名放在事件的 x-wk-signature header 中,你可据此确认事件来自 UQPAY 而非第三方。你可以使用 UQPAY 的官方库校验,也可以用自有方案手动校验。 签名验证步骤:
  1. 获取你端点的签名密钥。
  2. 从请求头中提取 x-wk-timestampx-wk-signature
  3. 拼接出 value_to_digest 字符串:把原始 JSON payload(请求体,字符串形式)与 x-wk-timestamp(字符串形式)首尾相连。
  4. 以 SHA-512 散列函数计算 HMAC。使用端点的签名密钥作为 key,以 value_to_digest 字符串作为 message。
  5. 将计算出的签名与 x-wk-signature header 做比较。若匹配,再比较当前时间戳与收到时间戳之间的差值是否在你的容差范围内。
常见问题:签名不匹配构造预期签名时,请务必使用原始 JSON payload。许多库在解析 payload 时会对 JSON 做格式化 — 请在任何转换发生之前完成签名校验。

代码示例

...
payload = "" //webhook payload
secret = '<YOUR_WEBHOOK_SECRET>'
timestamp := c.GetHeader("x-wk-timestamp")
signature := c.GetHeader("x-wk-signature")

valueToDigest := payload + timestamp
signatureHex := calculateHMACSHA512([]byte(secret), []byte(valueToDigest))

//compare signatureHex with signature
...

重试策略

当你的 Webhook 端点不可用或响应超时,UQPAY 会按指数退避策略重发通知,直到收到成功响应或达到重试上限。 重试按指数退避排期:第 N 次重试发生在 2^(attempts+3) 秒之后,首次间隔 16 秒,后续依次翻倍,最大间隔上限为 900 秒(15 分钟)。最多重试 5 次。

最佳实践

立即确认事件

如果你的 Webhook 脚本包含复杂逻辑,可能在 UQPAY 观察到完整执行之前就已超时。请把 Webhook 的应答代码(返回 200 状态码以确认事件已收到)与该事件的后续业务处理逻辑分开。

处理重复事件

重要 — 处理重复事件Webhook 端点偶尔会收到同一事件的多次投递。建议通过让事件处理逻辑保持幂等来避免重复处理。去重时请使用事件 payload 中的 event_id 字段。所有重试尝试(例如未向 UQPAY 返回成功的 HTTP 200 响应)都会复用同一个 event_id,你可以据此安全地忽略重复事件。

事件顺序

UQPAY 不保证事件按其生成顺序投递。你的端点不应假设事件按生成顺序到达,需自行处理乱序场景。你也可以利用事件中的 x-wk-timestamp 进行排序。