I'm trying to create a request to Amazon Selling Partner API following this guide.
The first part: Creating an access has already been taken care of here.
The documentation of the API for Orders can be found here.
I'm trying to invoke the GET /orders/v0/orders operation.
Connecting to the API
The only mandatory parameter for this operation is the MarketplaceIds based on the documentation.
In order to get the orders we need to sign our request. Here is my code so far:
const ACCESS_ID = "MyAccessKey"; const ACCESS_KEY = "MyAccessSecret"; function GetOrders(){ var access_token = AccessToken(); //Time variables var currentDate = new Date(); var isoDate = currentDate.toISOString(); var yearMonthDay= Utilities.formatDate(currentDate, 'GTM-5', 'yyyyMMdd'); //API variables var end_point = 'https://sellingpartnerapi-eu.amazon.com'; //Credential variables var aws_region = "eu-west-1"; var service = "sellingpartnerapi"; var termination_string = "aws4_request"; //CanonicalRequest = httpRequestMethod + '\n' + CanonicalURI + '\n' + CanonicalQueryString + '\n' + CanonicalHeaders + '\n' + SignedHeaders + '\n' + HexEncode(Hash(RequestPayload)); //CanonicalRequest components: var httpRequestMethod = 'GET'; var canonicalURI = '/orders/v0/orders'; var canonicalQueryString = '?marketplaceId=A1PA6795UKMFR9'; var canonicalheaders = 'host:' + canonicalURI + '\n' + 'x-amz-access-token:' + access_token + '\n' + 'x-amz-date:' + isoDate; var signedheaders = 'host;user-agent;x-amz-access-token;x-amz-date'; //Building the canonical request var canonical_request = httpRequestMethod + '\n' + canonicalURI + '\n' + canonicalQueryString + '\n' + canonicalheaders + '\n' + signedheaders; var canonical_signature = Utilities.computeHmacSha256Signature(canonical_string, ACCESS_KEY); canonical_request = canonical_request + '\n' + canonical_signature; //CredentialScope = Date + AWS region + Service + Termination string; //StringToSign = Algorithm + \n + RequestDateTime + \n + CredentialScope + \n + HashedCanonicalRequest; var credential_scope = yearMonthDay + '/' + aws_region + '/' + service + '/' + termination_string; var string_to_sign = "AWS4-HMAC-SHA256" + '\n' + isoDate + '\n' + credential_scope + '\n' + canonical_request (not signed yet); var kSecret = ACCESS_KEY; var kDate = Utilities.computeHmacSha256Signature(yearMonthDay, "AWS4" + kSecret); var kRegion = Utilities.computeHmacSha256Signature(Utilities.newBlob(aws_region).getBytes(), kDate); var kService = Utilities.computeHmacSha256Signature(Utilities.newBlob(service).getBytes(), kRegion); var kSigning = Utilities.computeHmacSha256Signature(Utilities.newBlob(termination_string).getBytes(), kService); var signature = Utilities.computeHmacSha256Signature(kSigning, string_to_sign); signature = signature.map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2)}).join(""); var options = { 'method': 'GET', 'payload': { 'end_point': end_point, 'path': canonicalURI, 'query_string': canonicalQueryString //Path parameter not needed }, 'headers': { 'host': end_point, 'x-amz-access-token': access_token, 'x-amz-date': isoDate, 'user-agent': 'GAS Script 1.0 (Javascript)', 'Authorization': 'AWS4-HMAC-SHA256 Credential=' + ACCESS_ID + '/' + credential_scope + ', SignedHeaders=' + signedheaders + ', Signature=' + signature, }, } var getOrders = UrlFetchApp.fetch(end_point, options); Logger.log(getOrders); } PROBLEMS
Following the Step 4. Create and sign your request, part 1. Create a canonical request, it is mentioned on their guide on item #6.
Use a hash (digest) function like SHA256 to create a hashed value from the payload in the body of the HTTP or HTTPS request. Example Structure of payload
HashedPayload = Lowercase(HexEncode(Hash(requestPayload)))
Question: What exactly is the payload? and how can we encode it as per the guide mentions?
This element is part of the canonical_string variable
var canonical_string = httpRequestMethod + '\n' + canonicalURI + '\n' + canonicalQueryString + '\n' + canonicalheaders + '\n' + signedheaders + '\n\ + HashedPayload??; It then mentions on item #8
Create a digest (hash) of the canonical request with the same algorithm that you used to hash the payload.
The hashed canonical request must be represented as a string of lowercase hexadecimal characters. The following example shows the result of using SHA-256 to hash the example canonical request.
Question: Creating a hash of the canonical request doesn't require that we use a key?
This is a possible solution but I'm not sure:
//CanonicalRequest = httpRequestMethod + '\n' + CanonicalURI + '\n' + CanonicalQueryString + '\n' + CanonicalHeaders + '\n' + SignedHeaders + '\n' + HexEncode(Hash(RequestPayload)); //CanonicalRequest components: var httpRequestMethod = 'GET'; var canonicalURI = '/orders/v0/orders'; var canonicalQueryString = '?marketplaceId=A1PA6795UKMFR9'; var canonicalheaders = 'host:' + canonicalURI + '\n' + 'x-amz-access-token:' + access_token + '\n' + 'x-amz-date:' + isoDate; var signedheaders = 'host;user-agent;x-amz-access-token;x-amz-date'; //NEW var requestPayloadHashed = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, ""); //NEW requestPayloadHashed = requestPayloadHashed.map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2)}).join(""); //Building the canonical request //UPDATED var canonical_string = httpRequestMethod + '\n' + canonicalURI + '\n' + canonicalQueryString + '\n' + canonicalheaders + '\n' + signedheaders + '\n' + requestPayloadHashed; var canonical_signature = Utilities.computeHmacSha256Signature(canonical_string, ACCESS_KEY); var canonical_request = canonical_string + '\n' + canonical_signature; //NEW canonical_request = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, canonical_request); //CredentialScope = Date + AWS region + Service + Termination string; //StringToSign = Algorithm + \n + RequestDateTime + \n + CredentialScope + \n + HashedCanonicalRequest; var credential_scope = yearMonthDay + '/' + aws_region + '/' + service + '/' + termination_string; var string_to_sign = "AWS4-HMAC-SHA256" + '\n' + isoDate + '\n' + credential_scope + '\n' + canonical_request; It mentions in the guide:
If the payload is empty, use an empty string as the input to the hash function.
But I fail to recognize what is the payload exactly.
Finally, Completing those steps would allow me to have a first complete version of the script that then I will be able to test, however, is it correct to invoke the API like this?
var getOrders = UrlFetchApp.fetch(end_point, options); ERRORS
When running the script I get the following error:
Exception: The parameters (number[],String) don't match the method signature for Utilities.computeHmacSha256Signature.
For this part of the code:
var signature = Utilities.computeHmacSha256Signature(kSigning, string_to_sign); https://stackoverflow.com/questions/66557069/google-apps-script-getting-orders-from-amazon-selling-partner-api-signing-requ March 10, 2021 at 09:20AM
没有评论:
发表评论