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

使用Amazon SP-API更新库存时遇InvalidInput及签名不匹配问题

问题根因

  • 你完全搞错了SP-API提交库存Feed的标准流程,feeds/2020-09-04/documents 接口的作用是创建待上传的Feed文档凭证、获取预签名上传地址,这个接口不需要传库存XML,你原来把库存XML塞到这个接口的请求体里,就是第一次InvalidInput报错的直接原因。
  • 你新增AddJsonBody代码的时机错误,且原有错误的XML请求体参数没有删除,导致请求内容在签名完成后被修改,所以AWS V4签名校验失败,报签名不匹配错误。

正确修改步骤

  1. 先删除原来错误的请求体添加代码:
// 删掉这行错误代码,该接口不需要传XML
restRequest.AddParameter("contentType", xml, ParameterType.RequestBody);
  1. 调整CreateRequestFeedDocument方法,只给createFeedDocument接口传正确的JSON请求体,且要在签名之前完成所有请求内容的设置:
private static IRestRequest CreateRequestFeedDocument()
{
    IRestRequest restRequest = new RestRequest("feeds/2020-09-04/documents", Method.POST);
    // 签名之前就添加好正确的请求体
    restRequest.AddJsonBody(new { contentType = "text/xml; charset=UTF-8" });
    restRequest.AddQueryParameter("MarketplaceIds", "APJ6JRA9NG5V4,A1PA6795UKMFR9,A13V1IB3VIYZZH,A1805IZSGTT6HS,A1F83G8C2ARO7P,A1RKKUPIHCS9HS,A2NODRKZP88ZB9");

    // 后面的角色获取、LWA签名、AWS签名逻辑保留不变
    AssumeRoleResponse assumeRoleResponse = null;
    Task.Run(async () =>
    {
        assumeRoleResponse = await GetAssumeRoleTokenDetail();
    }).GetAwaiter().GetResult();

    var clientId = AmazonCredentials.Default.ClientId;
    var clientSecret = AmazonCredentials.Default.ClientSecret;
    var refreshToken = AmazonCredentials.Default.RefreshToken;

    var lwaAuthCreds = new LWAAuthorizationCredentials
    {
        ClientId = clientId,
        ClientSecret = clientSecret,
        RefreshToken = refreshToken,
        Endpoint = new Uri("https://api.amazon.com/auth/o2/token")
    };

    restRequest = new LWAAuthorizationSigner(lwaAuthCreds).Sign(restRequest);

    var awsAuthCreds = new AWSAuthenticationCredentials
    {
        AccessKeyId = assumeRoleResponse.Credentials.AccessKeyId,
        SecretKey = assumeRoleResponse.Credentials.SecretAccessKey,
        Region = AmazonCredentials.Default.Region
    };

    restRequest.AddHeader("x-amz-security-token", assumeRoleResponse.Credentials.SessionToken);
    restRequest = new AWSSigV4Signer(awsAuthCreds).Sign(restRequest, restClient.BaseUrl.Host);
    return restRequest;
}
  1. 调用createFeedDocument接口拿到返回结果后,走完整的Feed上传流程:
restClient = new RestClient(live_url_base);
IRestRequest restRequest = CreateRequestFeedDocument();
var response = restClient.Execute(restRequest);
// 解析返回结果,拿到feedDocumentId和预签名上传地址
dynamic feedDocResult = JsonConvert.DeserializeObject(response.Content);
string feedDocumentId = feedDocResult.feedDocumentId;
string uploadUrl = feedDocResult.url;

// 把你生成的库存XML用PUT方法上传到预签名地址
var uploadRequest = new RestRequest(uploadUrl, Method.PUT);
uploadRequest.AddParameter("text/xml; charset=UTF-8", xml, ParameterType.RequestBody);
var uploadResponse = new RestClient().Execute(uploadRequest);

// 最后调用createFeed接口提交上传任务
var createFeedRequest = new RestRequest("feeds/2020-09-04/feeds", Method.POST);
createFeedRequest.AddJsonBody(new 
{
    feedType = "POST_INVENTORY_AVAILABILITY_DATA", // 对应库存XML的官方feed类型
    marketplaceIds = new string[] {"APJ6JRA9NG5V4","A1PA6795UKMFR9","A13V1IB3VIYZZH","A1805IZSGTT6HS","A1F83G8C2ARO7P","A1RKKUPIHCS9HS","A2NODRKZP88ZB9"},
    inputFeedDocumentId = feedDocumentId
});
// 给createFeedRequest完成LWA和AWS签名后执行即可完成库存提交

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 22:24:03