Search code examples
amazon-web-servicestimestampamazon-mwssuperagent

What is wrong with my timestamp in my MWS request?


If I submit a request to MWS via the scratchpad(AmazonServices/Scratchpad), it is successful, and I am able to view the details of the successful request. In particular, the timestamp on the request looks like this:

&Timestamp=2018-08-14T18%3A30%3A02Z

If I literally take this timestamp, as is, and try to use it in my code to make the same exact request, I get an error:

<Message>Timestamp 2018-08-14T18%3A30%3A02Z must be in ISO8601 
format</Message>\n 

Here is the function I am trying to place it in: (some chars changed in sensitive params)

exports.sendRequest = () => {

  return agent
    .post('https://mws.amazonservices.com/Products/2011-10-01')
    .query({
      AWSAccessKeyId: encodeURIComponent('BINAJO5TPTZ5TTRLNGQA'),
      Action: encodeURIComponent('GetMatchingProductForId'),
      SellerId: encodeURIComponent('H1N1R958BK8TTH'),
      SignatureVersion: encodeURIComponent('2'),
      Timestamp: '2018-08-14T18%3A30%3A02Z',
      Version: encodeURIComponent('2011-10-01'),
      Signature: encodeURIComponent(exports.generateSignature()),
      SignatureMethod: encodeURIComponent('HmacSHA256'),
      MarketplaceId: encodeURIComponent('ATVPDKIKX0DER'),
      IdType: encodeURIComponent('UPC'),
      'IdList.Id.1': encodeURIComponent('043171884536')
    })
    .then(res => {
      console.log('here is the response');
      console.log(res)
    })
    .catch(error => {
      console.log('here is the error');
      console.log(error);
    })
} 

What is even more strange, is that this is the path the request is being sent to:

path: '/Products/2011-10-01? 

AWSAccessKeyId=BINAJO5ZPTZ5YTTPNGQA&Action=GetMatchingProductForId&SellerId=H1N1R958ET8THH&SignatureVersion=2&Timestamp=2018-08-14T18%253A30%253A02Z&Version=2011-10-01&Signature=LwZn5of9NwCAgOOB0jHAbYMeQT31M6y93QhuX0d%252BCK8%253D&SignatureMethod=HmacSHA256&MarketplaceId=ATVPDKIKX0DER&IdType=UPC&IdList.Id.1=043171884536' },

The timestamp is not the same as the one I placed in the query. Why is this happening?


Solution

  • Your HTTP library is already doing the url-encoding for you, so you're double-encoding things. Remove all references to encodeURIComponent() and format your timestamp normally, with : and not %3A. Observe what happens to the generated URL.

    Why? URL-encoding isn't safe to do repeatedly.

    : becomes %3A with one pass, but it becomes %253A with a second pass, which is wrong.