首页 > 解决方案 > 使用 Google 脚本的 MWS 发布请求

问题描述

我正在尝试通过谷歌脚本向亚马逊发出发布请求以收集信息。

我们正在尝试将我们的订单发送到 MWS 并自动将它们转移到工作表中。

我到了签署请求的最后一步。

我不确定的几件事:

  1. 他们说我们使用密钥进行散列,我只看到一个客户端密钥和一个访问密钥 ID,我该使用哪个?
  2. 我是否将 URL 添加为签名内容的一部分?在 MWS Scratch pad 上,他们添加如下所示:

POST mws.amazonservices.com /Orders/2013-09-01

它是否必须在单独的行上是否需要发布和其他内容。有点不清楚。?

  1. 我在网上读到 sha256 字节码得到 base64 编码,而不是字符串文字,是真的吗?
  2. 我尝试使用在线工具对亚马逊提供给我的字符串进行哈希处理,并将其与他们提供的哈希值和 base64 编码进行比较,匹配的东西。我也试过解码,没有匹配

有人可以给我一个有效的例子,这样我就可以理解发生了什么以及它是如何工作的?

谢谢!

以下是我到目前为止的内容:

function POSTRequest() {

  var url = 'https:mws.amazonservices.com/Orders/2013-09-01?';

  var today = new Date();
  var todayTime = ISODateString(today);

  var yesterday = new Date();
  yesterday.setDate(today.getDate() - 1);
  yesterday.setHours(0,0,0,0);
  var yesterdayTime = ISODateString(yesterday); 

  var dayBeforeYesterday = new Date();
  dayBeforeYesterday.setDate(today.getDate() - 2);
  dayBeforeYesterday.setHours(0,0,0,0);
  var dayBeforeYesterdayTime = ISODateString(dayBeforeYesterday); 

  var unsignedURL = 
  'POST\r\nhttps:mws.amazonservices.com\r\n/Orders/2013-09-01\r\n'+
  'AWSAccessKeyId=xxxxxxxxxxx' +
  '&Action=ListOrders'+
  '&CreatedAfter=' + dayBeforeYesterdayTime +
  '&CreatedBefore' + yesterdayTime +
  '&FulfillmentChannel.Channel.1=AFN' +
  '&MWSAuthToken=xxxxxxxxxxxx'+
  '&MarketplaceId.Id.1=ATVPDKIKX0DER' +
  '&SellerId=xxxxxxxxxxx'+
  '&SignatureMethod=HmacSHA256'+
  '&SignatureVersion=2'+
  '&Timestamp='+ ISODateString(new Date) + 
  '&Version=2013-09-0';

  var formData = {
        'AWSAccessKeyId' : 'xxxxxxxxx',
        'Action' : "ListOrders",
        'CreatedAfter' : dayBeforeYesterdayTime,
        'CreatedBefore' : yesterdayTime,
        'FulfillmentChannel.Channel.1' : 'AFN',
        'MWSAuthToken' : 'xxxxxxxxxxxx',
        'MarketplaceId.Id.1' : 'ATVPDKIKX0DER',
        'SellerId' : 'xxxxxxxxxx',
        'SignatureMethod' : 'HmacSHA256',
        'SignatureVersion' : '2',
        'Timestamp' : ISODateString(new Date),
        'Version' : '2013-09-01',
        'Signature' : calculatedSignature(unsignedURL)

      };

   var options = {
     "method" : "post",
     "muteHttpExceptions" : true,
     "payload" : formData
   };


  var result = UrlFetchApp.fetch(url, options);
  writeDataToXML(result);
  Logger.log(result);


  if (result.getResponseCode() == 200) {
  writeDataToXML(result);
  }
}




function calculatedSignature(url) {
var urlToSign = url;
var secret = "xxxxxxxxxxxxxxxxxxx";
var accesskeyid = 'xxxxxxxxxxxxxxx';

  var byteSignature = Utilities.computeHmacSha256Signature(urlToSign, secret);
// convert byte array to hex string
var signature = byteSignature.reduce(function(str,chr){
  chr = (chr < 0 ? chr + 256 : chr).toString(16);
  return str + (chr.length==1?'0':'') + chr;
},'');


  Logger.log("URL to sign: " + urlToSign);
  Logger.log("");
  Logger.log("byte " + byteSignature);
  Logger.log("");
  Logger.log("reg " + signature);

var byte64 =  Utilities.base64Encode(byteSignature)
Logger.log("base64 byte " + Utilities.base64Encode(byteSignature));
  Logger.log("");
Logger.log("base64 reg " + Utilities.base64Encode(signature)); 

 return byte64;
}

标签: javascriptpostgoogle-apps-scriptamazon-mws

解决方案


第一步,创建要签名的字符串

string_to_sign是以下的组合:

  • POST后跟一个NEWLINE字符的字符串
  • 主机名mws.amazonservices.com, 后跟NEWLINE
  • API URL,通常只是/,或类似/Orders/2013-09-01的东西,后跟NEWLINE
  • Signature除URL 编码外的所有参数的字母顺序列表,例如a=1&b=2,后面不跟任何内容

最小参数似乎如下:

  • AWSAccessKeyId是亚马逊提供的 20 个字符的代码
  • Action是您的 API 调用的名称,例如GetReport
  • SellerId是您的 14 个字符的卖家 ID
  • SignatureMethodHmacSHA256
  • SignatureVersion2
  • Timestamp20181231T23:59:59ZUTC 新年前一秒的日期
  • Version是 API 版本吗2013-09-01
  • 您的调用可能需要其他参数,具体取决于Action

请注意:

  • NEWLINE字符只是“\n”,而不是“\r\n ”
  • 主机名不应包含“https://”或“http://”
  • Signature参数对于稍后的实际调用是必需的(参见步骤 3),但不是.string_to_sign

string_to_sign现在应该看起来像这样:

POST
mws.amazonservices.com
/Orders/2013-09-01
AWSAccessKeyId=12345678901234567890&Action=ListOrders&CreatedAfter .... &Version=2013-09-01

第 2 步,签署该字符串

  • 使用 40 个字符计算上述字符串的 SHA256 哈希Secret Key
  • 使用 Base64 编码此哈希
  • 在伪代码中:signature = Base64encode( SHA256( string_to_sign, secret_key ))

第三步,拨打电话

发送 HTTPS POST 请求,使用按字母顺序排列的完整参数列表,现在在中间的某个位置包括上面的签名Signature,因为您需要保持字母升序。

https://mws.amazonservices.com/Orders/2013-09-01?AWSAccessKeyId....Version=2013-09-01

第四步,处理结果

您应该得到两件东西:一个响应头和一个 XML 文档。请务必评估标头中的 HTTP 状态以及 XML 文档的所有内容。当 HTTP 返回“200 OK”时,一些错误消息被深深地隐藏在 XML 中。

第 5 步,高级内容

如果您使用需要您发送文档的呼叫,例如SendFeed,您需要执行以下附加步骤:

  • 计算文档的 MD5 哈希
  • 使用 Base64 编码此哈希
  • 在伪代码中:contentmd5= Base64encode( MD5( document ))
  • 添加Content-Type: text/xml(或任何适合您的文档)作为 HTTP 标头
  • 添加Content-MD5:加上 base64 编码的哈希作为 HTTP 标头

推荐阅读