【发布时间】:2012-03-05 22:49:22
【问题描述】:
我们使用亚马逊产品广告 API 在他们的网站上进行重新定价。对于那些不知道它的人来说,它基本上可以让您查询亚马逊数据库,而无需执行诸如抓取网页之类的耗时操作。它对我们非常有效,或者已经有效。他们现在正在为卖家解散这个 API,并在他们的 MWS 服务中将我们转移到一个新的 API。
据我所知,这些调用略有不同。两个明显的区别是 PA API 使用 HTTP 和 GET,而 MWS 使用 HTTPS 和 POST。
我不完全确定亚马逊文档中的示例是否正确,因为它们提供了创建为哈希签名 URL 请求的示例。这就是我们过去在使用 GET 方法的 PA-API 上成功执行此操作的方式。但是你可以为 POST 做到这一点吗?我不认为这是可能的,尽管我可能是错的,这肯定是例子所暗示的。
无论如何,创建签名 URL 是行不通的!所以我决定看看在 Delphi 中使用某种较低级别的 HTTPS POST。
我在这里搜索过,有几个不同的例子,但我无法让它们中的任何一个正常工作。一些示例似乎使用 INDY 10,不幸的是,我们被困在 INDY 9 上(出于兼容性原因)。我还查看了 WININET 包装器类型函数,但除了异常或错误之外,我无法返回结果。
这就是我在这里寻求帮助的原因。
如何使用 Delphi 对亚马逊 MWS 进行格式正确的调用?我尝试过以下页面中的示例:
How to make an HTTPS POST request in Delphi?
等等等等所有我能找到的!
但我收到了类似“错误请求”(异常)之类的错误。
我曾尝试使用 Fiddler(如其他地方所建议的那样)来查看正在发生的事情,但我还不能完全理解它(尽管我可以在其中编写一个有效的调用!)
所以我正在寻找一些指示或方向。我真的不想升级 INDY 或添加新库。我只想保持原样并使用我可用的东西。我们使用的是 D2007。
为了了解需要什么,我需要进行这种调用(GetServiceStatus 是最简单的):
POST /Products/2011-10-01?AWSAccessKeyId=<ACCESSKEY>
&Action=GetServiceStatus
&SellerId=<SELLERID>
&SignatureVersion=2
&Timestamp=2012-02-14T13%3A26%3A42Z
&Version=2011-10-01
&Signature=dtAvv595blmv%2FnV0h2Yr5bCGzKYXid0hkOuCmZOb3bc%3D
&SignatureMethod=HmacSHA256
到这个端点:
https://mws.amazonservices.co.uk/Products/2011-10-01
我认为我的问题在于我尝试过的所有示例我不知道如何正确设置调用,这可能是我收到错误请求错误的原因。
所以,一个不错的简单解决方案将不胜感激!
文档链接和观察:
这是 API 的开发者指南:
这是我们将使用的 API 的特定部分(取代当前的产品广告 API):
这里最基本的函数是GetServiceStatus函数。它不带任何参数。但是,它仍然需要使用来自亚马逊的凭证(卖家 ID、MWS 访问密钥和密钥(用于生成签名)进行身份验证和“签名”。我的感觉是,如果我可以让最简单的功能正常工作,那么其余的将随之而来。但是身份验证问题使找到解决方案变得如此困难。没有测试帐户。而且时间戳(以及因此调用的签名)会过期几分钟。
还有一个“迁移指南”:
但此文档确实包含一些错误。例如,端点不正确。
我的最新代码包括 ssl、cookie 管理器等:
var
LHTTP : TIdHTTP;
IdSSLIOHandlerSocket : TIdSSLIOHandlerSocket;
IdCookieManager : TIdCookieManager;
LParams : TStringList;
LResponse : string;
begin
IdCookieManager:=TIdCookieManager.Create(self);
IdSSLIOHandlerSocket:=TIdSSLIOHandlerSocket.Create(self);
with IdSSLIOHandlerSocket do begin
SSLOptions.Method := sslvSSLv3;
end;
LHTTP := TIdHTTP.Create(Self);
with LHTTP do begin
CookieManager:=IdCookieManager;
AllowCookies:=true;
IOHandler:=IdSSLIOHandlerSocket;
Request.ContentType:='text/xml';
Port:=443;
HandleRedirects:=true;
Host:='mws.amazonservices.co.uk';
ProtocolVersion:=pv1_1
end;
LParams := TStringList.Create;
try
LParams.Add('AWSAccessKeyId=<ACCESSKEY>');
LParams.Add('Action=GetServiceStatus');
LParams.Add('SellerId=<SELLERID>)');
LParams.Add('SignatureVersion=2');
LParams.Add('Timestamp=2012-02-15T13%3A00%3A07Z');
LParams.Add('Version=2011-10-01');
LParams.Add('Signature=viPlDAbzEBwlTAwq4hNaZi%2Fa1Klf7qIXIP%2BKUsOcJTI%3D');
LParams.Add('SignatureMethod=HmacSHA256');
LResponse:=LHTTP.Post('https://mws.amazonservices.co.uk/Products/2011-10-01?', LParams);
ShowMessage( LResponse );
except
on E: Exception do
ShowMessage('ouch! ' + E.Message );
end;
LHTTP.Free;
IdSSLIOHandlerSocket.Free;
IdCookieManager.Free;
end;
这是基于亚马逊期望收到的暂存器。最后的用户代理是可选的,不是必需的,也不是签名过程的一部分:
POST /Products/2011-10-01?AWSAccessKeyId=<ACCESSID>
&Action=GetServiceStatus
&SellerId=<SELLERID>
&SignatureVersion=2
&Timestamp=2012-02-15T13%3A00%3A07Z
&Version=2011-10-01
&Signature=viPlDAbzEBwlTAwq4hNaZi%2Fa1Klf7qIXIP%2BKUsOcJTI%3D
&SignatureMethod=HmacSHA256 HTTP/1.1
Host: mws.amazonservices.co.uk
x-amazon-user-agent: AmazonJavascriptScratchpad/1.0 (Language=Javascript)
Content-Type: text/xml
我试图从 Fiddler 获取信息,但它没有显示来自该软件的任何流量,但它必须与 Amazon 通信才能获得“400 bad request”错误。奇怪。
【问题讨论】:
-
您可能应该链接到您尝试使用的服务的文档,并选择您想要实现的非常具体的查询类型。让某人尽可能容易地提供帮助,因为其他方式您只是在等待既是 Delphi 开发人员又是亚马逊卖家的人。如果您付出足够的努力,即使我们不是亚马逊卖家,我(和其他人)也可能会尝试一下:例如,是否有 any 可以在没有卖家的情况下进行查询?亚马逊是否提供我们可以使用的测试账户?
-
嗨科斯敏。感谢您的评论。当然,你是 100% 正确的。我的大脑就像油灰一样试图解决这个问题,我现在意识到文档链接会有所帮助。我有工作中的链接。当我可以再次发布时(似乎我对新手的帖子有限制)我会发布链接。可悲的是,他们没有测试帐户。并且签名过程非常安全,使用卖家 ID、mws 访问 ID 和密钥来签署电话。所以我很感激这使得深入了解这个问题的整个过程变得更加困难。添加一个时间戳,它变得更难了。但我明天会发布文档链接。
-
您不应该“再次发布”,您应该编辑当前问题并添加相关详细信息。您的问题的标签列表下有一个
edit链接。这就是这个网站的运作方式:它不是一个讨论论坛,而是一个问答网站。 -
科斯敏,我很抱歉。我确实想知道,因为它确实说我在最初尝试时正在回答我自己的问题,我觉得这有点奇怪。我假设我使用从他的示例中创建的代码来编辑 Dorins 答案?这次我会这样做,并将我现在拥有的代码附加到他的回复中。如果这不是这样做的方法,请提出建议。再次抱歉,就像我说我是新来的一样,仍然对它的工作方式有所了解。但是感谢您对这里的工作方式的提醒 - 我想做的最后一件事就是在我寻求帮助时踩到任何人的脚趾。谢谢。
标签: delphi amazon-mws