Skip to content

Authentication

Authentication of the requests is done through HTTP Authorization headers based on an API key that is set up in the merchant panel. In the header an HMAC signature is encoded according to the following scheme:

authorization: hmac <version>$<api-key>$<method>$<URL-path>$<timestamp>$<nonce>
x-app-signature: <signature>

For example:

authorization: hmac v1$b23a9fa61406440d868271d19d634906$GET$/MERCHANT/ORDER/STATUS$1678206688075$AB1CSA86767CVSJKLN878AS
x-app-signature: UTgPOhKP2Uqgt8K3gNwnLZvJVcN8Pxxui4z3g3pft+A=

Info

Although HTTP headers are case insensitive according tothe HTTP standard, the headers should be considered case sensitive with a lowercase header name.

HMAC calculation for requests

The integrity of each message is protected by adding an HMAC to each request and response. The way to calculate the HMAC for the request is:

  1. Construct the input value for generating the HMAC by concatenating the below elements using $ as delimiter:

    1. api-key: your API key provided by OpenApp
    2. method: the uppercased request method (GET, POST, PUT, PATCH, DELETE)
    3. path information: must be uppercase (for example /MERCHANT/ORDER/STATUS)
    4. timestamp: Unix timestamp (epoch) in miliseconds (requests are valid up to 60 seconds drift from this timestamp)
    5. nonce: a random unique string for the request, for instance a UUID v4, which can be used for replay protection. Maximum length is 64 characters.
    6. content: the Base64 encoded SHA256 hash of the request body, or nothing if the request has no body
  2. This results in a string similar to the following in case of a GET request without a body:

    b23a9fa61406440d868271d19d634906$GET$/MERCHANT/ORDER/STATUS$1678206688075$yYy123
    
    Or in case of a POST request with body:
    b23a9fa61406440d868271d19d634906$POST$/MERCHANT/ORDER/STATUS$1678206688075$xxx123$b23a9fa61406440d868271d19d634906
    

  3. Get the API Secret provided by OpenApp.

  4. Calculate HMAC of the string from step 2 using the API Secret provided by OpenApp and the SHA-256 algorithm with utf-8 encoding.

  5. Base64 encode the result of the HMAC function.

The input (excluding the SHA256 of the body, since the body is present elsewhere in the request) is placed in the authorization header and the signature is placed in the x-app-signature header:

authorization: hmac v1$<API key>$<request method>$<path uppercase>$<timestamp>$<nonce>
x-app-signature: <calculated signature>

It is highly recommended to implement validation of request signatures on requests you receive to verify they really originate from OpenApp.

HMAC calculation for responses

The response string-to-sign is a concatenated string generated from the following parts:

  1. the nonce that was sent in the Authorization header of the request;
  2. the timestamp that was sent in the Authorization header of the request;
  3. the Base64 encoded SHA256 hash of the request body, or nothing if the request has no body
  4. This results in a string similar to the following in case of a response without a body:

    yYy123$1678206688075
    

  5. This string-to-sign is signed using HMAC-SHA256 and the secret key and the resulting signature is placed in the x-server-authorization header:

    x-server-authorization: hmac v1$<timestamp>$<nonce>$<signature>
    

The OpenApp API does verify this signature so this is mandatory.

Examples

Assuming the API Key is a6ae5908051a4b599202154b5b3541e3 and the secret is 5814d9bd75ea42349483ac74266d24bc834656d743244653ba2dcc8519eed695

GET request

This example shows the calculation for a GET request on endpoint {{baseUrl}}/merchant/order/status with a JSON response.

Request signature

  1. The input parameters for the string to sign are:
    1. HTTP method GET
    2. Endpoint path in uppercase /MERCHANT/ORDER/STATUS
    3. Timestamp is 1678206688075
    4. The random nonce is AB1CSA86767CVSJKLN878AS.
    5. Since the request has no body, there is no content hash for the signature.
  2. The string to sign is:
    v1$a6ae5908051a4b599202154b5b3541e3$GET$/MERCHANT/ORDER/STATUS$1678206688075$AB1CSA86767CVSJKLN878AS
    
  3. The calculated signature in Base64 is: K/WpW/u2PRDdVPp21i1tzhs1Dmf7dUooCIkJwfCjjOw=
  4. The headers have the value:
    authorization: hmac v1$a6ae5908051a4b599202154b5b3541e3$GET$/MERCHANT/ORDER/STATUS$1678206688075$AB1CSA86767CVSJKLN878AS
    x-app-signature: K/WpW/u2PRDdVPp21i1tzhs1Dmf7dUooCIkJwfCjjOw=
    

Response signature

The response from the server contains a message body with data. This data is encoded in JSON and the SHA 256 hadh needs to be generated after that serialization to JSON:

{
    "status": "CANCELLED"
}
{"status":"CANCELLED"}
  1. The input for the signature is thus:
    1. The nonce from the request AB1CSA86767CVSJKLN878AS
    2. The timestamp from the request 1678206688075
    3. The Base64 encoded SHA-256 hash of the response body eekP9w+TMbSUd0BnePPiT3A/DIr151xP6219xGvxpZ8=
  2. The string to sign for response hmac is:
    v1$1678206688075$AB1CSA86767CVSJKLN878AS$NzllOTBmZjcwZjkzMzFiNDk0Nzc0MDY3NzhmM2UyNGY3MDNmMGM4YWY1ZTc1YzRmZWI2ZDdkYzQ2YmYxYTU5Zg==
    
  3. The Base64 encoded signature calculated is: saOtyZVgcsDph3++lHfj/EzMxQOfE8UYKXisr6DdESw=
  4. The server response x-server-authorization header has value
    x-server-authorization: hmac v1$1678206688075$AB1CSA86767CVSJKLN878AS$saOtyZVgcsDph3++lHfj/EzMxQOfE8UYKXisr6DdESw=
    

POST request

This example shows the calculation for a POST request on endpoint {{baseUrl}}/v1/orders/fulfillment with an empty response.

Request signature

  1. The input parameters for the string to sign are:
    1. HTTP method POST
    2. Endpoint path in uppercase /V1/ORDERS/FULFULLMENT
    3. Timestamp is 1678206688075
    4. The random nonce is AB1CSA86767CVSJKLN878AS.
    5. The request body is
    {
        "oaOrderId": "OA12345678901234",
        "shopOrderId": "WS1213ASDZXC231A",
        "status": "CANCELLED"
    }
    
    {"oaOrderId":"OA12345678901234","shopOrderId":"WS1213ASDZXC231A","status":"CANCELLED"}
    

    SHA-256 hash from request body is:

    lexq/vv5iQNLIuV/n7+8JYg7aAkk55imrq6M4fuToqs=
    

  2. The string to sign is:
    v1$a6ae5908051a4b599202154b5b3541e3$POST$/V1/ORDERS/FULFULLMENT$1678206688075$AB1CSA86767CVSJKLN878AS$lexq/vv5iQNLIuV/n7+8JYg7aAkk55imrq6M4fuToqs=
    
  3. The calculated signature in Base64 is: L0ipqXrr9HpQoXPwzgDRSNnJKRnnZZ58oJ0FayN5ips=
  4. The authorization headers have the value:
    authorization: hmac v1$a6ae5908051a4b599202154b5b3541e3$POST$/V1/ORDERS/FULFULLMENT$1678206688075$AB1CSA86767CVSJKLN878AS
    x-app-signature: L0ipqXrr9HpQoXPwzgDRSNnJKRnnZZ58oJ0FayN5ips=
    

Response signature

The response from the server contains no body.

  1. The input for the signature is thus:
    1. The nonce from the request AB1CSA86767CVSJKLN878AS
    2. The timestamp from the request 1678206688075
    3. No content digest
  2. The string to sign for response hmac is: v1$1678206688075$AB1CSA86767CVSJKLN878AS
  3. The Base64 encoded signature calculated is: EQ4RqNLDmtVO1xgJlyQSI1h0ZfYvOjozyhyGHjiMqrM=
  4. The server response x-server-authorization header has value
    x-server-authorization: hmac v1$1678206688075$AB1CSA86767CVSJKLN878AS$EQ4RqNLDmtVO1xgJlyQSI1h0ZfYvOjozyhyGHjiMqrM=
    

Network configuration

If you need to configure your network allow access from OpenApp, you can configure the following IP addresses from which OpenApp will connect to your infrastructure:

  1. 3.125.75.87
  2. 3.70.34.35
  3. 3.72.153.100
  4. 3.72.163.248

Testing Authentication

Once you have finished implementation of your HMAC calculation, make sure to test it.

OpenApp offers 2 test endpoints that you can use to verify that you correctly calculate HMAC signatures. They require proper hmac authentication request and return x-server-authorization headers.

GET requests

Send your requests to GET {{OpenAppUrl}}merchant/v1/test

POST requests

Send your requests to POST {{OpenAppUrl}}merchant/v1/test You can include any body, for instance:

{
    "message": "any string you can imagine"
}