Node.js调用TikTok Get Order Settlements API时签名无效问题排查
环境
- Node.js
- Express.js
- MongoDB
问题接口
/api/finance/order/settlements
问题详情
在集成TikTok API过程中,其他接口(如获取授权店铺)均能正常调用,但调用Get Order Settlements接口时持续返回Error: signature is invalid错误。签名通过自定义generateSignature函数生成,采用HMAC-SHA256算法,逻辑与其他可用接口一致。
当前代码
签名生成函数
function generateSignature(path, params, secret) { const sortedKeys = Object.keys(params).sort(); let input = path; sortedKeys.forEach(key => { input += key + params[key]; }); input = secret + input + secret; const hmac = crypto.createHmac('sha256', secret); hmac.update(input); return hmac.digest('hex'); }
Express控制器函数
// 简化版代码 exports.getTikTokOrderSettlements = async (req, res) => { // ... [初始化和验证代码] const queryParams = { app_key: appKey, timestamp: timestamp, access_token: accessToken, shop_id: shopId, order_id: order_id, }; const sign = generateSignature(path, queryParams, secret); queryParams.sign = sign; const queryString = new URLSearchParams(queryParams).toString(); const tiktokApiUrl = `https://open-api.tiktokglobalshop.com${path}?${queryString}`; // ... [使用fetch调用API] };
已尝试操作
- 确认所有查询参数均纳入签名生成逻辑
- 检查参数排序规则与编码方式
- 将时间戳同步至GMT(UTC+00:00)时区
- 使用TikTok API测试工具中的已知有效硬编码值测试
疑问
仅该特定接口签名验证失败,是签名生成逻辑存在遗漏,还是该接口存在已知问题?
可能的原因及解决方案
1. 参数值编码不规范
TikTok财务类接口对参数值的URL编码要求可能更严格,若order_id等参数包含特殊字符,直接拼接会导致签名不匹配。需对参数值按RFC 3986标准做URL编码后再参与签名:
// 修改签名函数中的参数拼接逻辑 sortedKeys.forEach(key => { const encodedValue = encodeURIComponent(params[key]); input += key + encodedValue; });
注意:仅编码参数值,不要对参数名(key)进行编码。
2. 遗漏必填参数
核对Get Order Settlements接口文档,确认是否存在未纳入签名的必填参数(如部分财务接口要求的currency字段),即使使用测试值,也需将所有必填参数加入签名生成的参数列表。
3. 参数排序规则差异
大部分TikTok接口要求按参数名字典序排序,但少数特殊接口可能要求按参数传入顺序拼接。可尝试去掉sort(),直接按queryParams的构造顺序拼接参数生成签名。
4. 时间戳精度问题
确认timestamp为10位整数秒级时间戳,部分接口不接受毫秒级时间戳,可通过Math.floor(Date.now() / 1000)生成符合要求的时间戳。
5. 参数名大小写不匹配
核对文档中参数名的大小写格式,比如是否应为orderId而非order_id,字段名严格不匹配会导致签名验证失败。
6. Access Token权限不足
部分场景下,权限不足会伪装成签名错误返回。确认当前使用的Access Token已申请finance相关权限。
内容的提问来源于stack exchange,提问作者rom

