📋 概述
本页面用于测试商城推送到聚水潭系统的鉴权与签名机制。
🔄 商城 → 聚水潭系统
用途:商城推送订单、发货通知等到聚水潭系统
签名规则:不包含timestamp在签名字符串中
🔐 公共请求头
| 参数名 | 必填 | 说明 |
|---|---|---|
access_token |
是 | 商户或用户的身份令牌,用于识别调用方身份 |
X-Timestamp |
是 | 当前请求的时间戳(秒级)。注意:服务器会校验时间差,超过300秒(5分钟)的请求将被视为过期 |
X-Sign |
是 | 签名字符串。用于验证请求参数是否被篡改 |
🔢 签名算法步骤
- 准备参数:获取所有请求参数(GET或POST Body中的参数,不包含Header)
- 过滤空值:移除值为null或空字符串的参数,移除键名为sign的参数
- 字典排序:按照参数名(Key)的ASCII码从小到大排序(ksort)
- 拼接字符串:拼接成
key1=value1key2=value2...格式(无连接符) - 追加时间戳:仅方向2需要 - 追加
timestamp={X-Timestamp} - HMAC-SHA256加密:使用SecretKey对字符串进行HMAC-SHA256加密,生成小写签名
🧪 签名测试与验证
模拟商城推送订单到聚水潭
签名字符串不包含timestamp
📚 代码示例
PHP示例(商城推送订单)
$data = [
'event' => 'orderPay',
'mall_order_no' => 'M202607130001',
'amount' => '99.00'
];
// 从数据库或配置文件读取secret_key
$secretKey = $config['secret_key'];
$timestamp = time();
// 排序并拼接
ksort($data);
$signStr = '';
foreach ($data as $k => $v) {
if (is_array($v)) {
$v = json_encode($v, JSON_UNESCAPED_UNICODE);
}
$signStr .= $k . '=' . $v;
}
// 注意:不追加timestamp
$signature = hash_hmac('sha256', $signStr, $secretKey);
// 发送请求
$headers = [
'X-Event: orderPay',
'X-Sign: ' . $signature,
'X-Timestamp: ' . $timestamp
];
Python示例(聚水潭调用商城API)
import hmac
import hashlib
import time
params = {
'r': 'shop/goods/goods-list',
'pageNo': '1',
'pageSize': '10'
}
# 从数据库或配置文件读取secret_key
secret_key = config['secret_key']
timestamp = str(int(time.time()))
# 过滤空值并排序
filtered = {k: v for k, v in params.items() if v}
sorted_params = sorted(filtered.items())
# 拼接字符串
sign_str = ''.join([f"{k}={v}" for k, v in sorted_params])
# 追加timestamp(重要!)
sign_str_with_ts = sign_str + f"timestamp={timestamp}"
# HMAC-SHA256
signature = hmac.new(
secret_key.encode('utf-8'),
sign_str_with_ts.encode('utf-8'),
hashlib.sha256
).hexdigest()
# 请求头
headers = {
'apiSecretKey': secret_key,
'X-Sign': signature,
'X-Timestamp': timestamp
}
📌 注意事项与常见问题
核心概念
-
双向签名规则差异(重要!)
- 商城 → 聚水潭:签名字符串不包含timestamp
- 聚水潭 → 商城:签名字符串必须包含timestamp
- 混淆这两个规则是最常见的签名失败原因
-
SKU映射关系(关键!)
- 聚水潭的SKU编码 和 商城的货号(goods_no) 是精准对应关系
- 必须完全匹配(大小写、空格等),否则库存无法同步
- 在sku_mapping表中维护映射关系:jst_sku_id ↔ mall_goods_id + mall_attr_id
-
时间戳校验
- 服务器会校验请求时间戳,超过5分钟(300秒)的请求将被拒绝
- 确保客户端和服务器时间同步
-
Secret Key来源
- 从数据库表
jushuitan_baijia.mall_callback_config读取 - 不要在代码中硬编码Secret Key
- 从数据库表
签名算法要点
- 参数过滤:移除值为null、空字符串的参数,移除键名为"sign"的参数
- 字典排序:按照参数名的ASCII码从小到大排序(ksort)
- 拼接规则:格式为
key1=value1key2=value2...(无&符号) - 数组/对象值:需要JSON序列化为字符串后再拼接
- HMAC-SHA256:使用Secret Key加密,输出小写16进制字符串
常见问题排查
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 签名验证失败 | 1. 时间戳超过5分钟 2. 签名字符串拼接错误 3. 混淆了两个方向的规则 |
1. 检查服务器时间 2. 打印签名字符串对比 3. 确认是否应该包含timestamp |
| 库存同步失败 | 1. SKU编码不匹配 2. 商品未在商城上架 3. goods_no为空 |
1. 检查sku_mapping表 2. 确认商城商品状态 3. 确保goods_no字段完整 |
| 订单推送失败 | 1. 商品信息不完整 2. 规格属性匹配错误 |
1. 检查goods_list数据结构 2. 验证attrs和attr字段 |
调试技巧
- 查看签名字符串:本页面会显示完整的签名字符串,便于对比
- 检查API响应:注意区分HTTP状态码和业务code
- 时间戳验证:
Math.floor(Date.now() / 1000)生成当前时间戳 - 数据库验证:直接查询sku_mapping表确认映射关系