沃尔玛 API POST 因 400 错误请求(库存提要)ARCA 而失败

Walmart API POST failing with 400 Bad Request (inventory feed) ARCA

我在 POST 请求沃尔玛市场 API 进行批量数据交换时遇到问题,希望得到一些帮助。

背景: 我已经成功地编写了签名验证例程,并且可以成功执行get products 等GET 命令。这向我表明Authentication signatures 格式正确,headers(大部分)是正确的。

问题: 我收到 400 Bad Request 响应,请求内容无效。尝试向沃尔玛 API 提交测试提要时的响应。我读到这个问题很常见,但我还没有找到任何论坛 post 可以清楚地解释实际问题或如何解决它。这是我当前的参数:

阿卡 ARCA Rest Client For Chrome

URL:

https://marketplace.walmartapis.com/v2/feeds?feedType=inventory

Headers:

Accept: application/xml
WM_SVC.NAME: Walmart Marketplace
WM_CONSUMER.ID: <Consumer ID>
WM_SEC.AUTH_SIGNATURE: <Good Auth Signature>
WM_QOS.CORRELATION_ID: 15649814651
WM_SEC.TIMESTAMP: <Timestamp>
WM_CONSUMER.CHANNEL.TYPE: <Channel Type>
Content-Type: multipart/form-data

文件附件(不是原始负载,虽然已经尝试过)

<?xml version="1.0" encoding="utf-8"?>
<InventoryFeed xmlns="http://walmart.com/">
  <InventoryHeader>
    <version>1.4</version>
  </InventoryHeader>
  <inventory>
    <sku>KON04418</sku>
    <quantity>
      <unit>EACH</unit>
      <amount>4</amount>
    </quantity>
    <fulfillmentLagTime>1</fulfillmentLagTime>
  </inventory>
</InventoryFeed>

当我使用完全相同的 XML 并在 Walmart API Explorer 进行测试时 文件被接受,响应代码为 200 (OK)。

我已经使用 Notepad++ XML Tools 插件验证 XML 符合 Walmart 提供的 XSD。我已经看到许多关于需要应用边界的 post,因此我还尝试更改 Content-Type 并添加边界,但未能成功接受请求。

如果您能帮助我们将此请求发送到 return 响应代码 200,我们将不胜感激。

最后,一旦此请求在 ARCA 中得到验证,我将在 C# 中实现。我已经编写了所有代码,但是对于如何向 HttpWebRequest 添加附件与仅提交原始数据流相比,我有些模糊。如果可以就差异提供任何说明,我会再次表示感谢。

所以这个答案不够干净和优雅,更像是一种变通方法。我与沃尔玛工程团队内部的一些人进行了交谈,并被告知 C# SDK 应该会在接下来的几个月内推出。

经过我的所有研究,您向沃尔玛提交多部分表格的方式似乎有一些技巧,而且系统非常不灵活。我看过一些关于在 HTTP 请求正文中添加特定格式的边界的帖子,但没有这样的运气。我无法将正文作为文件或数据流附加到请求中。

解决方法非常简单,不幸的是很难看。它需要一些设置,但您可以围绕 Walmart Java SDK 创建一个 .jar 包装器并从您的 .Net 程序中调用它。

所以..过程中的步骤:

  • 获取适当的 .XSD 文件并从中生成 C# 类。
  • 构建格式正确的 XML 清单文件。确保包含命名空间!!如果您不包含适当的 ns2 / ns3 命名空间,沃尔玛将无法进行特定调用。
  • 动态生成一个批处理文件来调用您的 Java 模块。出于某种原因,直接生成命令行进程似乎让事情变得胡思乱想,所以我选择了批处理文件。

        string path = @Directory.GetParent(Environment.CurrentDirectory).ToString();
    
        if (File.Exists(@"../inventory.bat"))
        {
            File.Delete(@"../inventory.bat");
        }
    
        string batchCommand = @"cd " + path + Environment.NewLine + @"java -jar WalmartWrapper.jar SubmitInventoryFeed inventoryFeed.xml";
        File.WriteAllText(path + @"\inventory.bat", batchCommand);
    
        ProcessStartInfo info = new ProcessStartInfo();
        info.UseShellExecute = true;
        info.FileName = @"inventory.bat";
        info.WorkingDirectory = path;
        var p = Process.Start(info);
        p.WaitForExit();`
    
  • 从这里开始,Java 模块接管了工作。花了一些时间让它更像一个 SDK 而不是一个示例程序。下面是一些使事情正常工作的示例代码..

  • 入口点

    if ("SubmitInventoryFeed".equals(args[0].trim())) {
        if (args.length < 2) 
        {
            System.out.println("Need second argument for SubmitInventoryFeed");
            return;
        }
        String filename = args[1];
        Feed inventoryFeed = new Feed();
        try 
        {
            inventoryFeed.submitInventoryFeed(filename);
        } catch (Exception ex) {
            System.out.println("submitInventoryFeed failed: " + ex.getMessage());
        }
    }
    
  • SDK 调用(这是没有错误检查的 submitInventoryFeed 的骨架)

    String path = Paths.get(".").toAbsolutePath().normalize().toString();
    File itemFile = FileHandler.getFile(filename.trim());
    String filePath = path + "\" + "MarketplaceClientConfig.properties";
    WalmartMarketplace wm = Utils.getClient(filePath);
    Response response = wm.submitFeed(MarketplaceFeedType.inventory, itemFile);
    
  • 您可以使用ResponseChecker.isResponse200(response, true)测试提交是否成功

  • 使用 FeedAcknowledgement ack = response.readEntity(FeedAcknowledgement.class);获取实际响应以检查错误

我会第一个说我迫不及待地想用 Walmart 待定的 C# SDK 替换这项工作,但目前,这是我能够提交的唯一方式。我已经深入查看了沃尔玛代码,但不幸的是,在文件附件的幕后发生了一些 Java 魔法,所以实际上没有任何方法可以访问 C# 的确切过程和逆向工程.我认为真正了解 Java 里里外外的人都能弄明白,但我有足够的 Java 背景来拼凑出一个可行的解决方案,尽管很难看。