Я знаю, что этот вопрос не нов, но все решение, которое я получаю для этого, находится в PHP или моя проблема отличается от них.
Я использую API-интерфейс канала MWS для отправки плоского файла для обновлений цены и количества и всегда получаю следующую ошибку:
HTTP-заголовок Content-MD5, который вы передали для своего канала, не соответствовал Content-MD5, который мы рассчитали для вашего фида
Я хотел бы задать здесь 3 вопроса:
-
Параметр ContentMD5Value является необязательным, как указано в doc, но если я не передал это, то он скажет, что вы должны ввести ContentMD5Value.
-
Как и в doc
ContentFeed
, который мы даем Amazon. Amazon создаетcontentMD5
для этого файла, а затем сравнивает это значениеcontentMD5
со значениемcontentMD5
, которое мы отправляем на Amazon.
Если оба соответствуют, то ОК, в противном случае он выдает ошибку. Но если предположить, что я не буду отправлять файл, то также будут появляться те же ошибки, что MD5 не соответствует. Как это возможно? В каком файле они рассчитывают MD5? Потому что я не отправил файл вContentFeed
. -
Если я отправлю
contentMD5
в заголовок, а также параметр и отправивContentFeed
в тело, я все равно получаю ошибку.
Примечание. - Я отправляю contentMD5
в заголовке, а также в параметрах в форме, используя модуль запроса, а также вычисляя подпись с этим, а затем передаю ContentFeed
в теле.
Я использую JavaScript (Meteor), я вычисляю md5 с помощью модуля crpyto
.
Во-первых, я думаю, что мой md5 ошибается, но затем я попробовал с онлайн-сайта, который даст мне md5 для файла md5.
для моего файла:
Значение MD5: d90e9cfde58aeba7ea7385b6d77a1f1e
Base64Encodevalue: ZDkwZTljZmRlNThhWWJhN2VhNzM4NWI2ZDc3YTFmMWU =
Плоский файл, который я скачал для обновления цены и количества: -
https://sellercentral.amazon.in/gp/help/13461?ie=UTF8&Version=1&entries=0&
Я вычислил подпись также, указав ContentMD5Value
при расчете сигнатуры.
FEEDTYPE: '_ POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA _
Как, я прочитал документацию для этого, я передал MD5-заголовок в заголовках, а также отправлю как параметр.
Amazon doc говорит:
Ранее Amazon MWS принимала хэш MD5 как заголовок Content-MD5 вместо параметра. Передача его в качестве параметра гарантирует, что MD5 значение является частью сигнатуры метода, которая препятствует тому, чтобы на сеть от вмешательства в содержимое фида.
Amazon MWS по-прежнему будет принимать заголовок Content-MD5, независимо от того, Включен параметр ContentMD5Value. Если и заголовок, и параметр используются, и они не совпадают, вы получите Ошибка InvalidParameterValue.
Я использую модуль request
для http-запросов.
Я передаю все необходимые ключи, идентификатор продавца и т.д. в форме модуля запроса и передавая FeedContent
в теле.
Я попытался отправить файл следующим образом:
Метод submitFeed: -
submitFeed : function(){
console.log("submitFeedAPI running..");
app = mwsReport({auth: {sellerId:'A4TUFSCXD64V3', accessKeyId:'AKIAJBU3FTBCJUIZWF', secretKey:'Eug7ZbaLljtrnGKGFT/DTH23HJ' }, marketplace: 'IN'});
app.submitFeedsAPI({FeedType:'_POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA_'},Meteor.bindEnvironment(function(err,response){
if(err){
console.log("error in submit feed...")
console.log(err)
}
else{
console.log("suuccess submit feed....")
console.log(response);
}
}))
Метод, который вызывает Amazon submitFeedAPI: -
var submitFeedsAPI = function(options, callback){
console.log("submitFeedsAPI running...");
var fileReadStream = fs.createReadStream('/home/parveen/Downloads/test/testting.txt');
var contentMD5Value = crypto.createHash('md5').update(file).digest('base64');
var reqForm = {query: {"Action": "SubmitFeed", "MarketplaceId": mpList[mpCur].id, "FeedType":options.FeedType,"PurgeAndReplace":false,"ContentMD5Value":contentMD5Value}};
mwsReqProcessor(reqForm, 'submitFeedsAPI', "submitFeedsAPIResponse", "submitFeedsAPIResult", "mwsprod-0000",false,file, callback);
}
also try
var fileReadStream = fs.createReadStream('/home/parveen/Downloads/test/testting.txt');
var base64Contents = fileReadStream.toString('base64');
var contentMD5Value = crypto.createHash('md5').update(base64Contents).digest('base64');
Функция mwsReqProcessor следующая: -
mwsReqProcessor = function mwsReqProcessor(reqForm, name, responseKey, resultKey, errorCode,reportFlag,file, callback) {
reqOpt = {
url: mwsReqUrl,
method: 'POST',
timeout: 40000,
body:{FeedContent: fs.readFileSync('/home/parveen/feedContentFile/Flat.File.PriceInventory.in.txt')},
json:true,
form: null,
headers: {
// 'Transfer-Encoding': 'chunked',
//'Content-Type': 'text/xml',
// 'Content-MD5':'ZDkwZTljZmRlNThhZWJhN2VhNzM4NWI2ZDc3YTFmMWU=',
// 'Content-Type': 'text/xml; charset=iso-8859-1'
'Content-Type':'text/tab-separated-values;charset=UTF-8'
},
}
reqOpt.form = mwsReqQryGen(reqForm);
var r = request(reqOpt, function (err, res, body){
console.log(err)
console.log(res)
})
// var form = r.form();
//form.append('FeedContent',fs.createReadStream('/home/parveen/feedContent//File/Flat.File.PriceInventory.in.txt'))
}
Метод генерации mwsReqQryGen: -
mwsReqQryGen = function mwsReqQryGen(options) {
var method = (options && options.method) ? ('' + options.method) : 'POST',
host = (options && options.host) ? ('' + options.host) : mwsReqHost,
path = (options && options.path) ? ('' + options.path) : mwsReqPath,
query = (options && options.query) ? options.query : null,
returnData = {
"AWSAccessKeyId": authInfo.accessKeyId,
"SellerId": authInfo.sellerId,
"SignatureMethod": "HmacSHA256",
"SignatureVersion": "2",
"Timestamp": new Date().toISOString(),
"Version":"2009-01-01",
},
key;
if(query && typeof query === "object")
for(key in query)
if(query.hasOwnProperty(key)) returnData[key] = ('' + query[key]);
if(authInfo.secretKey && method && host && path) {
// Sort query parameters
var keys = [],
qry = {};
for(key in returnData)
if(returnData.hasOwnProperty(key)) keys.push(key);
keys = keys.sort();
for(key in keys)
if(keys.hasOwnProperty(key)) qry[keys[key]] = returnData[keys[key]];
var sign = [method, host, path, qs.stringify(qry)].join("\n");
console.log("..................................................")
returnData.Signature = mwsReqSignGen(sign);
}
//console.log(returnData); // for debug
return returnData;
};
Я также пробовал со следующим: -
reqOpt = {
url: mwsReqUrl,
method: 'POST',
timeout: 40000,
json:true,
form: null,
body: {FeedContent: fs.createReadStream('/home/parveen/feedContentFile/Flat.File.PriceInventory.in.txt')},
headers: {
// 'Transfer-Encoding': 'chunked',
//'Content-Type': 'text/xml',
// 'Content-MD5':'ZDkwZTljZmRlNThhZWJhN2VhNzM4NWI2ZDc3YTFmMWU=',
// 'Content-Type': 'text/xml; charset=iso-8859-1'
},
}
Я также пробовал без JSON и напрямую отправлял поток чтения файла в тело, то есть:
reqOpt = {
url: mwsReqUrl,
method: 'POST',
timeout: 40000,
form: null,
body: fs.createReadStream('/home/parveen/feedContentFile/Flat.File.PriceInventory.in.txt'),
headers: {
// 'Transfer-Encoding': 'chunked',
//'Content-Type': 'text/xml',
// 'Content-MD5':'ZDkwZTljZmRlNThhZWJhN2VhNzM4NWI2ZDc3YTFmMWU=',
// 'Content-Type': 'text/xml; charset=iso-8859-1'
},
}
Но такая же ошибка возникает каждый раз:
HTTP-заголовок Content-MD5, который вы передали для своего канала, не соответствовал Content-MD5, который мы рассчитали для вашего фида
Я хочу знать, где я делаю неправильно, и как правильно подать API-интерфейс и отправить файл с помощью модуля запроса.
Я также пробовал с кодом, указанным в MWS, для генерации MD5, но тот же ошибка возникала каждый раз.
Мой .txt файл следующим образом:
sku price quantity TP-T2-00-M 2
Любая помощь очень ценится