Amazon MWS SubmitFeed Content-MD5 HTTP header did not match the Content-MD5 calculated by Amazon

点点圈 提交于 2019-12-01 02:07:53

Hey sorry for late reply but why don't you try to send the file in multipart in the form-data request and other queryStrings in 'qs' property of request module. You can submit the request as follows:-

 reqOpt = {
   url: mwsReqUrl,
   method: 'POST',
   formData: {
      my_file: fs.createReadStream('file.txt')
  },
  headers: {
     'Content-Type': 'application/x-www-form-urlencoded'
  },
  qs: { 
     AWSAccessKeyId: '<your AWSAccessKeyId>',
     SellerId: '<your SellerId>',
     SignatureMethod: '<your SignatureMethod>',
     SignatureVersion: '<your SignatureVersion>',
     Timestamp: '<your Timestamp>',
     Version: '<your Version>',
     Action: 'SubmitFeed',
     MarketplaceId: '<your MarketplaceId>',
     FeedType: '_POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA_',
     PurgeAndReplace: 'false',
     ContentMD5Value: '<your file.txt ContentMD5Value>',
     Signature: '<your Signature>'
 }
}

request(reqOpt, function(err, res){

})

finally i got the solution as Ravi said above. Actually there are few points i want to clear here for you all who are facing the same issue:-

1)Amazon marketplace API doc is not giving proper information and example. Even i guess the documentation is not updated . As in doc they said that ContentMD5Value parameter value is optional, here is the link for doc:-

http://docs.developer.amazonservices.com/en_US/feeds/Feeds_SubmitFeed.html

You can check there they clearly mention that the field is not required but if you not pass than they gives the error that you must pass content MD5 value.

So that is wrong. ContentMD5 is required attribute.

2)They said in the same doc that you need to send file data weather its a xml or flat-file in the field key name i.e. FeedContent.

But that is also not needed you can send the file with any name no need to give FeedContent key for the file you just need to send the file in stream.

3)They will give the same error of contentMD5 not match weather you send file or not because if they not found file than the contentMD5 you send will not match to that. SO if you are getting the ContentMD5 not match error than check the following:-

1)Check that you are generating the right MD5 code for your file you can check whether you are generating the right code or not by there java code they given on doc . You can get that from the link:-

http://docs.developer.amazonservices.com/en_US/dev_guide/DG_MD5.html

2)Don't trust on online websites for generating the MD5 hash and base64 encoding.

3)If your MD5 is matched with the MD5 generated from Java code they given than one thing is clear that your MD5 is right so no need to change on that.

4)Once your MD5 is correct and after that also if you get the same error that is:-

Amazon MWS SubmitFeed Content-MD5 HTTP header did not match the Content-MD5 calculated by Amazon

ContentMD5 not matched .Than you need to check only and only you file uploading mechanism. Because now the file you are sending to Amazon is not either correct or you are not sending it in the right way.

Check for file upload :-

For checking wheather or not you are sending the right file you need to check with following:-

1)You need to send the required parameters like sellerId, marketplaceId, AWSAccessKey etc as query params.

2)You need to send the file in the form-data as multipart , if you are using the request module of node.js than you can see the above code given by Ravi.

3)you need to set the header as only:-

'Content-Type': 'application/x-www-form-urlencoded'

No need to send the header as chunked or tab separated etc because i don't need them any more they are even confuse me because somewhere someone write use this header on other place someone write use this header. So finally as i am abel to submit this API i didn't need any of the header rather than application/x-www-form-urlencoded.

Example:-

reqOpt = {
   url: mwsReqUrl,
   method: 'POST',
   formData: {
      my_file: fs.createReadStream('file.txt')
  },
  headers: {
     'Content-Type': 'application/x-www-form-urlencoded'
  },
qs: { }// all the parameters that you are using while creating signature.

Code for creating the contentMD5 is:-

var  fileData= fs.readFileSync('/home/parveen/Downloads/test/feed.txt','utf8');

var contentMD5Value = crypto.createHash('md5').update(fileData).digest('base64');

As i am facing the issue that is because i am using form and form-data simultaneously via request module so i convert my form data with qs(query string) and file in form-data as multipart.

So in this way you can successfully submit the API for submit feed.

Any queries are most welcome Thanks

Amazon requires the md5 hash of the file in base64 encoding.

Your code:

var fileReadStream = fs.createReadStream('/path/to/file.txt');
var file = fileReadStream.toString('base64'); //'[object Object]'
var contentMD5Value = crypto.createHash('md5').update(file).digest('base64');

wrongly assumes that a readStream's toString() will produce the file contents, when, in fact, this method is inherited from Object and produces the string '[object Object]'.

Base64-encoding that string always produces the 'FEGnkJwIfbvnzlmIG534uQ==' that you mentioned.

If you want to properly read and encode the hash, you can do the following:

var fileContents = fs.readFileSync('/path/to/file.txt'); // produces a byte Buffer
var contentMD5Value = crypto.createHash('md5').update(fileContents).digest('base64'); // properly encoded

which provides results equivalent to the following PHP snippet:

$contentMD5Value = base64_encode(md5_file('/path/to/file.txt', true));

Probably, I'm too late, but here are key points for C#:

1) Multipart form-data didn't work at all. Finished with the following (simplified):

HttpContent content = new StringContent(xmlStr, Encoding.UTF8, "application/xml");
HttpClient client = new HttpClient();
client.PostAsync(query, content)

2) About query:

UriBuilder builder = new UriBuilder("https://mws.amazonservices.com/");
NameValueCollection query = HttpUtility.ParseQueryString(builder.Query);

query["AwsAccessKeyId"] = your_key_str;
query["FeedType"] = "_POST_ORDER_FULFILLMENT_DATA_";
... other required params
query["ContentMD5Value"] = Md5Base64(xmlStr);

builder.Query = query.ToString();
query = builder.ToString();

3) About Md5base64

public static string Md5Base64(string xmlStr)
{
  byte[] plainTextBytes = Encoding.UTF8.GetBytes(xmlStr);
  MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
  byte[] hash = provider.ComputeHash(plainTextBytes);
  return Convert.ToBase64String(hash);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!