Signing requests


You must secure all API requests to Amazon Pay by signing them with your private key. The signature is used to verify the identity of the requestor and protect the data during transit. Follow these steps to sign a request:

Step 1: Generate a canonical request
Arrange the contents of your request (host, action, headers, etc.) into a standard (canonical) format.

Step 2: Create a String to Sign
Create a string to sign by concatenating the hashing algorithm designation (AMZN-PAY-RSASSA-PSS) and the digest (hash) of the canonical request.

Step 3: Calculate the Signature
Sign the string to sign using RSASSA-PSS algorithm with SHA256 hashing and then Base64 encode the result.

Step 4: Add the Signature to the HTTP Request
After you calculate the signature, add it as a request header.

Step 1. Generate a canonical request

Create a string that includes information from your request in a standardized (canonical) format.

Example canonical request pseudo-code:

CanonicalRequest =
  HTTPRequestMethod + '\n' +
  CanonicalURI + '\n' +
  CanonicalQueryString + '\n' +
  CanonicalHeaders + '\n' +
  SignedHeaders + '\n' +
  HexEncode(Hash(CanonicalRequest))

Example request:

POST 
/live/v1/checkoutSessions

accept:application/json 
content-type:application/json 
x-amz-pay-date:20190923T231908Z 
x-amz-pay-host:pay-api.amazon.com 
x-amz-pay-idempotency-key:cllHyiNvS8cJ8Zas 
x-amz-pay-region:us 

accept;content-type;x-amz-pay-date;x-amz-pay-host;x-amz-pay-idempotency-key;x-amz-pay-region 
0b6c19dc5bc1883ebd68d3c77ee929922c6b4a59e0a506d96c45e0c024c3295b

To create a canonical request, concatenate the following components from each step into a single string:

1. Start with the HTTP request method (GET, PUT, POST, etc.), followed by a newline character.

2. Add the canonical URI, followed by a newline character. The canonical URI is everything in the URI from the HTTP host to the question mark character ("?") before the query string parameters (if any). Normalize URI paths according to RFC 3986. Remove redundant and relative path components. Each path segment must be URI-encoded.

3. Add an empty string (essentially, a blank line), followed by a newline character. Note that this step may change in the future if Amazon Pay API requests start using query strings.

4. Add the canonical headers, followed by a newline character. The canonical headers is a list of all the HTTP headers that you are including with the signed request. To create the canonical headers list:

  1. Convert all header names to lowercase, remove leading spaces and trailing spaces, and convert sequential spaces in the header value to a single space.
  2. Sort headers by character code
  3. Iterate through header names and construct each header entry using the follow rules:
    • Append the lowercase header name followed by a colon.
    • Append a comma-separated list of values for that header.
    • Do not sort the values in headers that have multiple values. Append a new line ('\n').

Pseudo-code for constructing the canonical list of headers:

CanonicalHeadersEntry0 = Lowercase(HeaderName) + ':' + Trim(HeaderValue) + '\n'
CanonicalHeaders = CanonicalHeadersEntry0 + CanonicalHeadersEntry1 + ... + CanonicalHeadersEntryN

Lowercase represents a function that converts all characters to lowercase. Trim removes excess white space before and after values, and converts sequential spaces to a single space.

5. Add the signed headers, followed by a newline character. This value is the list of headers that you included in the canonical headers.

6. Use SHA256 to create a hash of the HTTPS request body. The hashed payload must be represented as a lowercase hexadecimal string.

7. Construct the finished canonical request by combining components from each step into a single string. Note that each component except for the last component ends with a newline character.

Step 2. Create a String to Sign

Psuedo-code structure of string to sign:

StringToSign =
    Algorithm + \n +
    LowerCase(Hex(Hash(CanonicalRequest)))

Example string to sign:

AMZN-PAY-RSASSA-PSS 
c5c55b2d523738b72c0b96f6d5e0d712d9496573490125b191eeb6840c052ffb

To create the string to sign, concatenate the algorithm and digest of the canonical request:

1. Start with the algorithm designation, followed by a newline character. This value is the hashing algorithm that you use to calculate the digests in the canonical request:

AMZN-PAY-RSASSA-PSS 

2. Append SHA256 hash of the canonical request created in the previous step. This value is not followed by a newline character. The hashed canonical request must be lowercase base-16 encoded, as defined by Section 8 of RFC 4648:

f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59

Step 3. Calculate the Signature

To calculate the signature, sign the string to sign created in Step 2 with your private key. Use RSASSA-PSS algorithm with SHA256 hashing and default salt length then Base64 encode the result.

Pseudo-code for calculating the signature:

signature = RSASSA-PSS(privateKey, StringToSign); 
base64_encoded_signature = Base64Encode(signature);

Calculated signature example:

o/THnkmKYB+jCPOo3Qchux3T/dKmOqLTiL2MMmfshGIgATo3206BlJVjAIqL8LhuEu9c70conBoMsfc5ZWvdijTQ893fIXA7WjEKFqTwyBOQz2EIjep7f8Yf4g5bgWzKLJYK3ABTptoND96yjo3IZVTQLHW+G2FQs8X/lSW8XUjHgobcSUKF4X2/3ukZQ+QEtw5vLZcpzcvyhdwBZakgqcXQRuaryS3iekZXUsdajOd+pMMSOw5yQXLE3qXukxiWXNcDnc3bCw+8JtynfcVYUX+Q3Z6/J0p9nODmfNAuvhTgpfnFpXKRUTGuhANiOyOSN8orWSx1MVPPwHSyZhhpPA==

Step 4. Add the Signature to the HTTP request

After you calculate the signature, add it to the request as an HTTP header named Authorization in this format: Algorithm + PublicKeyId + SignedHeaders + Signature.

  • Algorithm will always be AMZN-PAY-RSASSA-PSS
  • PublicKeyId is the credential provided by your Amazon Pay. See Get you publicKeyId for more info.
  • SignedHeader is a list of all headers included in the signature. Note that the Authorization header should not be included in the list of signed headers.
  • Signature is the value calculated in Step 3.

Pseudo-code for constructing the header:

Authorization: algorithm PublicKeyId=publicKeyId, SignedHeaders=x-amz-pay-date, Signature=base64_encoded_signature

Finished Authorization header example:

Authorization: AMZN-PAY-RSASSA-PSS PublicKeyId=AHEGSJCM3L2S637RBGABLAFW, SignedHeaders=accept;content-type;x-amz-pay-date;x-amz-pay-host;x-amz-pay-idempotency-key;x-amz-pay-region, Signature=o/THnkmKYB+jCPOo3Qchux3T/dKmOqLTiL2MMmfshGIgATo3206BlJVjAIqL8LhuEu9c70conBoMsfc5ZWvdijTQ893fIXA7WjEKFqTwyBOQz2EIjep7f8Yf4g5bgWzKLJYK3ABTptoND96yjo3IZVTQLHW+G2FQs8X/lSW8XUjHgobcSUKF4X2/3ukZQ+QEtw5vLZcpzcvyhdwBZakgqcXQRuaryS3iekZXUsdajOd+pMMSOw5yQXLE3qXukxiWXNcDnc3bCw+8JtynfcVYUX+Q3Z6/J0p9nODmfNAuvhTgpfnFpXKRUTGuhANiOyOSN8orWSx1MVPPwHSyZhhpPA==