Closed flalex closed 3 years ago
Look at the post-example in this python script https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html
I think the problem is that you are missing the payload header.
Hi @rogersv, thanks for reply, but could you clarify what header are you referring? Not sure if it's payload_hash that used in building canonical_request, because wrong payload_hash leads to InvalidSignatureException.
Also, at the link above POST request uses amz_target and content-type as signed_headers, but official guide hasn't mentioned that and it looks confusing. https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#step-3-add-headers-to-the-uri
Look for x-amz-content-sha256 in https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
That helped me in another post call. I have not try this specific call.
You send data in json? try convert and if dont work : Content-Type: application/json
Same problem, I try to send a POST request, but nothing works.
@rogersv
Look for x-amz-content-sha256 in https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
That helped me in another post call. I have not try this specific call.
It didn't help. Also, I'm really curious why it could be related to another service.
Request
POST https://sellingpartnerapi-na.amazon.com/solicitations/v1/orders/MY_ORDER_ID/solicitations/productReviewAndSellerFeedback user-agent: MY_USER_AGENT/0.1 (Language=Python) Accept-Encoding: gzip, deflate Accept: / Connection: keep-alive host: sellingpartnerapi-na.amazon.com x-amz-date: 20201118T115356Z Authorization: AWS4-HMAC-SHA256 Credential=/20201118/us-east-1/execute-api/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-content-sha256;x-amz-date, Signature=9dad9b71951da0df0fecabeab2d68175cf79020809cb87bb2c62fb32127fe101 x-amz-access-token: Atza|MY_TOKEN Content-Type: application/json Content-Length: 35
b'{"marketplaceIds": "ATVPDKIKX0DER"}'
Response:
{'Date': 'Wed, 18 Nov 2020 11:53:57 GMT', 'Content-Type': 'application/json', 'Content-Length': '136', 'Connection': 'keep-alive', 'x-amzn-RequestId': '6b13452b-9bca-48d6-b88b-31a5c11e69ba', 'x-amzn-ErrorType': 'BadRequestException', 'x-amz-apigw-id': 'WM61YFEKoAMFkRg='}
{ "errors": [ { "message": "Missing or invalid request parameters: [marketplaceIds]", "code": "InvalidInput" } ] }
@rodrigojob I tried to send it as json, url-encoded, as query string. Nothing works. @FexusZ Do you have samples?
Could amazon team helps with that? It takes minutes to find the answer for API developers and not hours for making experiments.
for : https://sellingpartnerapi-eu.amazon.com/fba/smallAndLight/v1/feePreviews
and body : { "marketplaceIds":"A13V1IB3VIYZZH", "Items": [ { "asin":"B0794VMZ8G", "price": [ { "amount":10, "currencyCode":"EUR" } ] } ] }
i get error response : { "errors": [ { "code": "InvalidInput", "message": "Invalid Input", "details": "" } ] }
Get request work correctly, but i can't make POST or other request, i use postman and body is in raw
I added other header parameter in the request, I am using php and curl, and it also doesn't work too..
header :
I just tested the call and it seems to work fine. It is quite clear in the documentation that the marketplaceIds is a query parameter
. There is no body for this request.
Hi @rogersv, Could you please share example of your request. It's better to see it once, right. Thank you!
Method: POST
Request:
https://sellingpartnerapi-eu.amazon.com/solicitations/v1/orders/{myorderid}/solicitations/productReviewAndSellerFeedback?marketplaceIds={marketplaceId}
Headers:
{
"x-amz-date": "20201118T144755Z",
"x-amz-access-token": "mytoken",
"x-amz-security-token": "anothertoken",
"host": "sellingpartnerapi-eu.amazon.com",
"Authorization": "AWS4-HMAC-SHA256 Credential=XXX/20201118/eu-west-1/execute-api/aws4_request,SignedHeaders=host;x-amz-access-token;x-amz-date;x-amz-security-token, Signature=YYY"
}
Edit: this was an example of a successful request.
the method must POST but the marketplace parameter will send as GET parameter
Try: MarketplaceIds
Hi @flalex What did the trick for me was setting the content-type improperly for the request to pass.
I was using the following :
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
but that led to the error
{
errors: [
{
message: "When Content-Type:application/x-www-form-urlencoded, URL cannot include query-string parameters (after '?'): '/solicitations/v1/orders/{order_id}/solicitations/productReviewAndSellerFeedback?'",
code: 'InvalidInput'
}
]
}
Which is quite surprising.
By accident, I switched to another content-type (I was trying to pass the params as a json)
'Content-Type': 'application/json; charset=utf-8',
Which works fine...
Here is my complete code
const access_token = '' // access token
const key_id = '' // IAM user key id
const secret = '' // IAM user secret
const endpoint = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#selling-partner-api-http-methods
const region = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#selling-partner-api-endpoints
const market_place_id = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#marketplaceid-values
const HTTP_method = 'POST'
const path = `/solicitations/v1/orders/${order_id}/solicitations/productReviewAndSellerFeedback`
const query_string = `marketplaceIds=${market_place_id}`
const service = 'execute-api'
const now = new Date()
const headers_to_sign = {
host: endpoint,
'x-amz-access-token': access_token,
'x-amz-date': `${moment(now).toISOString()}`,
'user-agent': 'intellifox-api-1.6',
}
const canonical_request = createCanonicalRequest(
HTTP_method, path, query_string, headers_to_sign
)
const string_to_sign = createStringToSign(
now, region, service, canonical_request,
)
const signature = createSignature(
secret, now, region, service, string_to_sign,
)
await axios({
method: HTTP_method,
url: `https://${endpoint}${path}${query_string ? '?' + query_string : ''}`,
headers: {
Authorization: `AWS4-HMAC-SHA256 Credential=${key_id}/${moment(now).format('YYYYMMDD')}/${region}/${service}/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date, Signature=${signature}`,
'Content-Type': 'application/json; charset=utf-8',
...headers_to_sign,
},
})
Hi @flalex What did the trick for me was setting the content-type improperly for the request to pass.
I was using the following :
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
but that led to the error
{ errors: [ { message: "When Content-Type:application/x-www-form-urlencoded, URL cannot include query-string parameters (after '?'): '/solicitations/v1/orders/{order_id}/solicitations/productReviewAndSellerFeedback?'", code: 'InvalidInput' } ] }
Which is quite surprising.
By accident, I switched to another content-type (I was trying to pass the params as a json)
'Content-Type': 'application/json; charset=utf-8',
Which works fine...
Here is my complete code
const access_token = '' // access token const key_id = '' // IAM user key id const secret = '' // IAM user secret const endpoint = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#selling-partner-api-http-methods const region = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#selling-partner-api-endpoints const market_place_id = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#marketplaceid-values const HTTP_method = 'POST' const path = `/solicitations/v1/orders/${order_id}/solicitations/productReviewAndSellerFeedback` const query_string = `marketplaceIds=${market_place_id}` const service = 'execute-api' const now = new Date() const headers_to_sign = { host: endpoint, 'x-amz-access-token': access_token, 'x-amz-date': `${moment(now).toISOString()}`, 'user-agent': 'intellifox-api-1.6', } const canonical_request = createCanonicalRequest( HTTP_method, path, query_string, headers_to_sign ) const string_to_sign = createStringToSign( now, region, service, canonical_request, ) const signature = createSignature( secret, now, region, service, string_to_sign, ) await axios({ method: HTTP_method, url: `https://${endpoint}${path}${query_string ? '?' + query_string : ''}`, headers: { Authorization: `AWS4-HMAC-SHA256 Credential=${key_id}/${moment(now).format('YYYYMMDD')}/${region}/${service}/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date, Signature=${signature}`, 'Content-Type': 'application/json; charset=utf-8', ...headers_to_sign, }, })
Hi intellifox-hq, don't you need the "AWS IAM Role ARN" to create your Signature? The key like "arn:aws:iam::123456789:role".
Hello @kingsun-he the code above is a functional one we use in our app. The only place we needed to use the "AWS IAM Role ARN" was in the Developer Central dashboard, but it is not used to sign the message directly. It is referenced by the following:
const key_id = '' // IAM user key id
const secret = '' // IAM user secret
Which points to the IAM user whose role must match what is entered in the Developer Central dashborad.
Hello @kingsun-he the code above is a functional one we use in our app. The only place we needed to use the "AWS IAM Role ARN" was in the Developer Central dashboard, but it is not used to sign the message directly. It is referenced by the following:
const key_id = '' // IAM user key id const secret = '' // IAM user secret
Which points to the IAM user whose role must match what is entered in the Developer Central dashborad.
Hi intellifox-hq, Do you mean you can call the method "productReviewAndSellerFeedback" though you didn't use the Role ARN key? I failed to call this method. It always return "Access to requested resource is denied." It make me depressed.
Dear @kingsun-he , I know exactly how you feel. This is not easy. You can read on my own journey on this issue: https://github.com/amzn/selling-partner-api-models/issues/805 I described all the steps I took to resolve it.
Just for the "Access to requested resource is denied." be careful of the route you use: check it and re-check it. This error is also returned if you use a wrong route (I paid the price for this error myself..)
Take care
Dear @kingsun-he , I know exactly how you feel. This is not easy. You can read on my own journey on this issue: amzn/selling-partner-api-models#805 I described all the steps I took to resolve it.
Just for the "Access to requested resource is denied." be careful of the route you use: check it and re-check it. This error is also returned if you use a wrong route (I paid the price for this error myself..)
Take care
Hi intellifox-hq, It seems that it doesn't resolve my problem. I took self-authorize to my application. It has nothing to do with App Store. Actually, I can access to orders-api, catalogItem-api and get the data successfully. But when I used the 2 methods of solicitations-api, it will return "Access to requested resource is denied." always. So do you use the 2 methods successfully?
Even I tried it in postman, I failed. So I wonder if there is a problem of Amazon API.
====================================== Here is my http Info: POST /solicitations/v1/orders/123-1234567-1234567/solicitations/productReviewAndSellerFeedback?marketplaceIds=ATVPDKIKX0DER HTTP/1.1 Host: sandbox.sellingpartnerapi-eu.amazon.com x-amz-access-token: Atza|IXXXXXXXO8Rd8MBkai security_token: FwoGZXIvYXdzEOP//////////wXXXXXXXXXXXBALlAyCg/ll0/VnFuMANI14d/Nm6e0OK9rgPN6k4xPSolDnWmArfjDpuugE= Content-Type: application/json X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 X-Amz-Security-Token: FwoGZXIvYXdzEOP//////////wEaDFXXXXXX4xPSolDnWmArfjDpuugE= X-Amz-Date: 20210201T103142Z Authorization: AWS4-HMAC-SHA256 Credential=ASIXXXXXXXXG/20210201/eu-west-1/execute-api/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=fa41a7fcXXXXXXXXXXXXXfec0081d2d9efc9178f9e42857cb
Hi intellifox-hq, It seems that it doesn't resolve my problem. I took self-authorize to my application. It has nothing to do with App Store. Actually, I can access to orders-api, catalogItem-api and get the data successfully. But when I used the 2 methods of solicitations-api, it will return "Access to requested resource is denied." always. So do you use the 2 methods successfully?
Even I tried it in postman, I failed. So I wonder if there is a problem of Amazon API.
====================================== Here is my http Info: POST /solicitations/v1/orders/123-1234567-1234567/solicitations/productReviewAndSellerFeedback?marketplaceIds=ATVPDKIKX0DER HTTP/1.1 Host: sandbox.sellingpartnerapi-eu.amazon.com x-amz-access-token: Atza|IXXXXXXXO8Rd8MBkai security_token: FwoGZXIvYXdzEOP//////////wXXXXXXXXXXXBALlAyCg/ll0/VnFuMANI14d/Nm6e0OK9rgPN6k4xPSolDnWmArfjDpuugE= Content-Type: application/json X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 X-Amz-Security-Token: FwoGZXIvYXdzEOP//////////wEaDFXXXXXX4xPSolDnWmArfjDpuugE= X-Amz-Date: 20210201T103142Z Authorization: AWS4-HMAC-SHA256 Credential=ASIXXXXXXXXG/20210201/eu-west-1/execute-api/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=fa41a7fcXXXXXXXXXXXXXfec0081d2d9efc9178f9e42857cb
I checked the code I use for this: the route seems correct, the query string also, I don't see why it would fail. The only thing that could trigger this issue is if the order_id is not related to your account. If that's not the case, reach out to the support, they take some time but they solve issues as soon as they can.
Good day to you
Try making marketplaceIds a list (marketplaceIds = [ATVPDKIKX0DER]). This solved it for me for uploading feeds and other documents on Python, maybe it works on you too.
Could you please help with work example of POST request? How should be passed marketplaceIds parameter? What Content-Type should be here? Also tried to use json content-type and pass it as query parameter. Nothing works for me.
Request
Response: