Generate and Verify Signature for API Request and Response
Every API request needs a signature to ensure that your interactions are secure and that the responses you receive originate from Amazon.
For both generating and checking these signatures, Amazon Pay Later uses the Hash-based Message Authentication Code (HMAC) SHA-384 algorithm. Along with Amazon's Signature v4 process, HMAC SHA-384 algorithm generates and validates signatures.
For detailed information on signature generate, please follow this guide.
Here is a high level overview of how to generate a signature:
-
Create a canonical request following the standard format for APIs.
-
Create a string to sign using the canonical request created in step 1.
-
Derive a signing key using the secret key provided by Amazon.
Note
For access to available secret keys, see Amazon Pay Later Integration Details.
-
Calculate the final signature using the signing key and the string to sign.
Create Canonical Request
Refer to the pseudocode below:
CanonicalRequest =
HTTPRequestMethod + '\n' +
hostname/uri + '\n' +
formattedQueryParameters + '\n' +
formattedHeaders + '\n' +
FormattedRequestParameters
formattedQueryParameters, formattedHeaders, and formattedRequestParameters are sorted key-value pairs of parameters joined by '&'. Each key-value string follows RFC3886 encoding.
For practical insight and examples of constructing canonical requests for online APIs, see Canonical Request Samples for Online APIs.
Examples of Canonical Requests
POST / PUT Method
POST
amazonpay.amazon.in/v1/payments/refund
x-amz-algorithm=AWS4-HMAC-SHA384&x-amz-client-id=A2XMNOQAN8MC64&x-amz-date=20200906T043202Z&x-amz-expires=500&x-amz-source=Browser&x-amz-user-agent=Postman&x-amz-user-ip=52.95.75.13
amount=.1&attributableProgram=S2SPay&chargeId=api_testing_262¤cyCode=INR&customerIdType=Barcode&customerIdValue=4025914314671133&intent=AuthorizeAndCapture&merchantId=A2XMNOQAN8MC64&storeDetail=%7BstoreIdType%3DMERCHANT_STORE_ID%2C%20storeId%3DTest_Store_ID_1%7D
Note
For POST / PUT API, as there are no query parameters, pass an empty string.
GET Method
GET
amazonpay.amazon.in/v1/payments/refund
merchantId=A2XMNOQAN8MC64&txnId=Refundtest5459-k&txnIdType=MerchantTxnId
x-amz-algorithm=AWS4-HMAC-SHA384&x-amz-client-id=A2XMNOQAN8MC64&x-amz-date=20200906T055702Z&x-amz-expires=500&x-amz-source=Browser&x-amz-user-agent=Postman&x-amz-user-ip=52.95.75.13
Note
For GET API, as there are no body parameters, hence add a new line characters after headers.
Verify Response Signatures
To ensure the authenticity of response signatures, review these sample canonical response formats for verification.
Example Canonical Response for POST Method
POST
amazonpay.amazon.in/v1/payments/refund
x-amz-algorithm=AWS4-HMAC-SHA384&x-amz-date=20200906T071710Z&x-amz-request-id=ab6e5e05-1f15-48a1-ae39-84fd9ae62a17
amazonRefundId=S04-8640119-6506863-R007626&amount=0.10&createTime=2020-09-06T05%3A34%3A35.129Z¤cyCode=INR&refundId=Refundtest5459-k&refundedFee=0.00&status=Approved&updateTime=2020-09-06T05%3A35%3A05.488Z
Example Canonical Response for GET Method
GET
amazonpay.amazon.in/v1/payments/refund
x-amz-algorithm=AWS4-HMAC-SHA384&x-amz-date=20200906T072009Z&x-amz-request-id=33c6c2f3-7de0-4e31-bb5e-7e637da8a04d
amazonRefundId=S04-8640119-6506863-R007626&amount=0.10&createTime=2020-09-06T05%3A34%3A35.129Z¤cyCode=INR&refundId=Refundtest5459-k&refundedFee=0.00&status=Approved&updateTime=2020-09-06T05%3A35%3A05.488Z
Note
As responses are returned in the body, canonical requests for both POST and GET methods follow the same pattern for signature verification.
Create a String to Sign
The 'string to sign' consolidates essential data about the request and the preceding canonical request, forming the basis for generating the signature.
The 'string to sign' combines the algorithm, date and time, credential scope, and the digest of the canonical request using the following structure:
StringToSign =
Algorithm + '\n' +
RequestDateTime + '\n' +
CredentialScope + '\n' +
HashedCanonicalRequest
To construct the 'string to sign':
-
Start with the algorithm designation, followed by a newline character. For this instance, the algorithm used for calculating the canonical request's digest is SHA384, denoted as AWS4-HMAC-SHA384:
-
Append the request date value, followed by a newline character. Use the ISO8601 basic format in UTC time zone (YYYYMMDD'T'HHMMSS'Z'). For instance:
20181130T120049Z\n
Note
If you are using JAVA and SimpleDateFormat then please use date format as
yyyyMMdd'T'HHMMSS'Z'
. -
Add the credential scope value, followed by a newline character. This string consists of the date (YYYYMMDD), the targeted region (eu-west-1), the service requested (AmazonPay), and the termination string aws4_request, separated by slashes:
20181130/eu-west-1/AmazonPay/aws4_request\n
-
Append the hash of the canonical request created in step 1. This value must not be followed by a newline character. Ensure that the hashed canonical request is SHA384 encoded.
316097191c79d640a0f0b434e043072c45ff0a51ab27972252e1d9ec47fcaa29f7b70ca010587390ed108513fed247f4
Sample String to Sign
AWS4-HMAC-SHA384
20181130T120049Z
20181130/eu-west-1/AmazonPay/aws4_request
316097191c79d640a0f0b434e043072c45ff0a51ab27972252e1d9ec47fcaa29f7b70ca010587390ed108513f
Calculate the Signature
Before generating a signature, it's crucial to derive a signing key from your secret key. This derived signing key provides enhanced security as it is specific to the date, service, and region. The signature isn't formed solely using your secret key; rather, it's a result of employing the signing key and the 'string to sign' created as inputs to a keyed hash function. The hex-encoded outcome from this function becomes the signature.
Follow these steps to calculate a signature:
-
To derive your signing key, use your secret key to create a sequence of hash-based message authentication codes (HMACs) as demonstrated below:
kSecret = your secret key kDate = HMAC("AWS4" + kSecret, Date) kRegion = HMAC(kDate, Region) kService = HMAC(kRegion, Service) kSigning = HMAC(kService, "aws4_request")
Note
Ensure the date used in the hashing process adheres to the YYYYMMDD format (e.g., 20150830) and does not include the time. It should match the date used in the previous steps.
-
Use the derived signing key and the 'string to sign' as inputs to the keyed hash function. After obtaining the signature, encode it using base64url encoding. Employ the following pseudocode:
This process ensures the accurate calculation of the signature, enhancing the security and integrity of the request.
Sample Codes and References to Generate and Verify Signatures
• Java
• DotNet