对接规范#
接收地址#
需业务接收方提供webhook地址,联系我司配置订阅推送。该地址需支持安全验签。
Content-Type: application/json
X-App-Id: 平台分配的AppId
X-Timestamp:推送的时间戳
X-Nonce:推送的随机字符串
X-Signature:生成的签名字符串
接收推送内容#
推送内容因事件类型而异,各个事件推送内容与含义可参考:开放接口API => 订阅通知。以下是【商品信息变更】事件的推送内容案例 {
"payload": {
"data": {
"productId": 25179,
"name": "33",
"cnName": "232",
"productSkuId": 32743,
"productSku": "E标nHs322yx01-20g"
}
},
"ctx": "[]",
"eventId": "823947304910004224",
"entityId": "32743",
"eventHash": "036c5aaead0258455895349d2646322c",
"eventType": "source",
"eventName": "openapi.product.change",
"sourceSystem": "westmonth.westmonth",
"eventVersion": "1.0.0",
"eventAt": "2025-09-09 15:52:25"
}
接口验签#
提示:以下X-App-Id、X-Secret-Key由我司生成,若有需要请联系我司开通分配
1
接收请求头
// 获取请求头
$xAppId = $request->header('X-App-Id');
$xTimestamp = $request->header('X-Timestamp');
$xSignature = $request->header('X-Signature');
$xNonce = $request->header('X-Nonce');
// 必填校验
if (empty($xAppId) || empty($xTimestamp) || empty($xSignature) || empty($xNonce)) {
return false;
}
2
时间有效性验证
$now = time();
$minValidTime = $now - $this->timestampTolerance; // 允许过去多久范围内的时间戳
$maxValidTime = $now + 60; // 允许60秒内的未来时间
if ($xTimestamp < $minValidTime || $xTimestamp > $maxValidTime) {
return false;
}
3
随机数验证(防重放)
if ($this->redis->exists($this->getNonceKey($xAppId, $xNonce)) > 0) {
return false;
}
4
验签参数合并
// 将请求头参数合并到内容参数
$params = array_merge($request->all(), [
'app_id' => $xAppId,
'timestamp' => $xTimestamp,
'nonce' => $xNonce,
'signature' => $xSignature,
]);
5
签名验证
1
复制签名
$signature = $params['signature'];
unset($params['signature']);
2
过滤无效字符
// 只过滤 null 和空字符串(保留 0、false 等)
$params = array_filter($params, fn($value) => $value !== null && $value !== '');
3
排序并拼接字符串
ksort($params);
// 转换为RFC3986标准的查询字符串
$queryString = http_build_query($params, '', '&', PHP_QUERY_RFC3986);
4
生成hash字符串
// 使用 sha256 方式生成字符串
$computedSignature = hash_hmac('sha256', $queryString, $X-Secret-Key)
5
签名比较
if (!hash_equals($computedSignature, $signature)) {
return false;
}
6
标记随机数为已使用
// 设置随机数已使用
$this->redis->setex($this->getNonceKey($xAppId, $xNonce), $expiresAt, 1);
验签示例#
X-App-Id:3acdfa31-c427-4f8f-922b-44e05b7d9766
X-Secret-Key:d0c024ba5d5a699f54936eb298d605e8
推送示例#