Skip to content

签名与幂等

日期: 2026-09-18

状态: HMAC v2 已发布

1. HMAC v2 签名

1.1 签名原文

按以下顺序拼接六行,最后一行后不加换行:

text
HTTP_METHOD\n
NORMALIZED_PATH\n
CANONICAL_QUERY\n
BODY_SHA256\n
TIMESTAMP\n
NONCE
  • HTTP_METHOD:大写 HTTP 方法,例如 POST
  • NORMALIZED_PATH:不含域名和查询串的完整路径,例如 /open/v1/checkout-sessions
  • CANONICAL_QUERY:当前已发布的支付 API 不使用查询参数,因此填写空字符串,并在路径行后保留一个空行。
  • BODY_SHA256:实际发送请求体原始字节的 SHA-256 小写十六进制摘要。GET 请求对空字节串计算摘要。
  • TIMESTAMP:Unix 秒级时间戳。与 SmartPay 服务器时间的偏差必须不超过 300 秒。
  • NONCE:调用方为每次请求生成的随机字符串;同一应用在 300 秒窗口内不可重复。

使用应用凭证的 Secret 计算:

text
signature = hex(HMAC-SHA256(appSecret, canonicalRequest))

X-Signature 必须是 64 位十六进制字符串。服务端使用恒定时间比较验证签名。

1.2 请求头

text
X-App-Id: <应用 App ID>
X-Key-Id: <当前活动凭证 Key ID>
X-Timestamp: <Unix 秒级时间戳>
X-Nonce: <本次请求唯一随机值>
X-Signature: <64 位 HMAC-SHA256 十六进制签名>
Idempotency-Key: <写操作必填>
Content-Type: application/json

查询接口同样必须携带前五个认证头,但不需要 Idempotency-Key

1.3 原始请求体要求

SmartPay 对网络收到的原始请求字节计算摘要。签名后不得改变 JSON 的空格、换行、字段顺序或字符编码。推荐客户端先生成 UTF-8 请求体字符串,再用同一字节数组计算摘要并发送。

1.4 凭证轮换

应用可以同时保留多把未撤销且未过期的活动凭证,并通过 X-Key-Id 指定本次请求使用的凭证。轮换流程在商户工作台完成:创建新凭证、安全保存一次性展示的 Secret、激活新凭证、验证调用,再撤销旧凭证。不要在新凭证验证成功前撤销旧凭证。

2. 幂等

创建支付会话、门店终端付款码支付和创建退款等写操作必须携带 Idempotency-Key。建议使用 UUID,或使用“业务类型 + 商户业务单号”生成稳定且不可复用的键。付款码请求重试必须保持原请求体和幂等键不变,严禁把 authCode 另行持久化为重试任务。

幂等范围由租户、应用、API 操作和 Idempotency-Key 共同确定:

  • 同一范围内,相同键和相同原始请求体会返回首次成功执行保存的响应,不重复执行业务。
  • 同一范围内,相同键但请求体摘要不同会返回 IDEMPOTENCY_CONFLICT,HTTP 状态码为 409。
  • 首次请求仍在处理中,或失败后尚未达到安全恢复窗口时,重复请求也会返回冲突,调用方应稍后查询或重试。
  • 平台为写请求设置 24 小时幂等保留时间;调用方不应在 24 小时后复用旧键,因为平台为审计或安全目的可能延迟清理记录。

3. 超时和重试

  • HTTP 超时不代表业务失败。先使用原业务单号或 SmartPay 资源 ID 查询,再决定是否重试。
  • 重试同一业务操作时,必须保持请求体和 Idempotency-Key 不变;每次网络请求仍需生成新的 X-NonceX-Timestamp,并重新计算签名。
  • 不要在结果未知时更换业务单号或幂等键重新创建支付、退款或其他写操作。

4. 客户端安全

  • App Secret 只允许保存在客户服务端的密钥管理系统中;小程序、H5 和 APP 不得直接持有生产 Secret。
  • Secret 不得出现在 URL、浏览器存储、客户端日志、监控明文字段或代码仓库中。
  • 凭证明文只在签发恢复期内展示;控制台列表不会回显 Secret。
  • mTLS 和客户 IP 白名单尚未作为 HMAC v2 公共能力发布。未在控制台和开发文档中明确启用前,不应将其作为生产接入前提。

智收通平台为技术服务商:不持有客户资金、不开立支付账户、不从事资金清算。