You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopee联盟Open API返回Invalid Signature错误排查求助

Shopee联盟API签名无效(错误10020)解决方法

问题重现

以下是用于获取Shopee联盟商品列表的代码:

import requests
import time
import hashlib

appID = APP_ID
secret = SECRET

# Set the API endpoint URL
url = "https://open-api.affiliate.shopee.com.my/graphql"

# Set the GraphQL query
body = """
{
  productOfferV2(
    listType:0
    sortType:5
  ) {
    nodes {
      commissionRate
      commission
      price
      productLink
      offerLink
    }
  }
}
"""
payload = {"query": body}

timestamp = str(int(time.time()))
factor = f'{appID}{timestamp}{payload}{secret}'
signature = hashlib.sha256(factor.encode()).hexdigest()


print(factor)

# Set the request headers
headers = {
    'Content-type':'application/json',
    'Authorization':f'SHA256 Credential={appID},Timestamp={timestamp},Signature={signature}'
}

# Send the POST request
response = requests.post(url, json=payload, headers=headers)

# Print the response
print(response.json())

运行后返回错误:

{'errors': [{'message': 'error [10020]: Invalid Signature', 'extensions': {'code': 10020, 'message': 'Invalid Signature'}}]}

已确认appID、secret和timestamp正确,问题出在签名生成环节。

问题分析

签名无效的核心原因是生成签名因子时,直接使用了Python字典的字符串表示,而非与请求发送时一致的标准JSON序列化字符串。

当你用requests.post(..., json=payload)时,requests会自动将payload序列化为无多余空格的标准JSON字符串(如{"query":"{...}"}),但你代码中str(payload)得到的是Python字典的字符串形式(如{'query': '{...}'}),两者格式不一致,导致签名校验失败。

解决方法

需要将payload序列化为与请求发送时完全一致的JSON字符串,再代入签名因子计算。具体步骤:

  1. 导入json模块,使用json.dumps()将payload序列化为无空格的JSON字符串(保持和requests默认序列化格式一致)。
  2. 用序列化后的字符串替代原代码中的payload生成签名因子。

修改后的代码

import requests
import time
import hashlib
import json  # 新增导入

appID = APP_ID
secret = SECRET

url = "https://open-api.affiliate.shopee.com.my/graphql"

body = """
{
  productOfferV2(
    listType:0
    sortType:5
  ) {
    nodes {
      commissionRate
      commission
      price
      productLink
      offerLink
    }
  }
}
"""
payload = {"query": body}

timestamp = str(int(time.time()))
# 将payload序列化为标准JSON字符串,去掉多余空格
payload_str = json.dumps(payload, separators=(',', ':'))
# 使用序列化后的字符串生成签名因子
factor = f'{appID}{timestamp}{payload_str}{secret}'
signature = hashlib.sha256(factor.encode()).hexdigest()

print(factor)

headers = {
    'Content-type':'application/json',
    'Authorization':f'SHA256 Credential={appID},Timestamp={timestamp},Signature={signature}'
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())

额外检查点

  • 确认secret没有多余的空格或大小写错误,严格匹配Shopee联盟后台的配置。
  • 确保timestamp是当前时间的整数秒(代码中str(int(time.time()))是正确的),避免时间差过大导致签名失效。

内容的提问来源于stack exchange,提问作者Zulfiqar Laili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:35:18