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:
-
Construct the input value for generating the HMAC by concatenating the below elements using
$
as delimiter:api-key
: your API key provided by OpenAppmethod
: the uppercased request method (GET
,POST
,PUT
,PATCH
,DELETE
)path
information: must be uppercase (for example/MERCHANT/ORDER/STATUS
)timestamp
: Unix timestamp (epoch) in miliseconds (requests are valid up to 60 seconds drift from this timestamp)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.content
: the Base64 encoded SHA256 hash of the request body, or nothing if the request has no body
-
This results in a string similar to the following in case of a GET request without a body:
Or in case of a POST request with body: -
Get the API Secret provided by OpenApp.
-
Calculate HMAC of the string from step 2 using the API Secret provided by OpenApp and the SHA-256 algorithm with utf-8 encoding.
-
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:
- the
nonce
that was sent in the Authorization header of the request; - the
timestamp
that was sent in the Authorization header of the request; - the Base64 encoded SHA256 hash of the request body, or nothing if the request has no body
-
This results in a string similar to the following in case of a response without a body:
-
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:
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¶
- The input parameters for the string to sign are:
- HTTP method
GET
- Endpoint path in uppercase
/MERCHANT/ORDER/STATUS
- Timestamp is
1678206688075
- The random nonce is
AB1CSA86767CVSJKLN878AS
. - Since the request has no body, there is no content hash for the signature.
- HTTP method
- The string to sign is:
- The calculated signature in Base64 is:
K/WpW/u2PRDdVPp21i1tzhs1Dmf7dUooCIkJwfCjjOw=
- The headers have the value:
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:
- The input for the signature is thus:
- The nonce from the request
AB1CSA86767CVSJKLN878AS
- The timestamp from the request
1678206688075
- The Base64 encoded SHA-256 hash of the response body
eekP9w+TMbSUd0BnePPiT3A/DIr151xP6219xGvxpZ8=
- The nonce from the request
- The string to sign for response hmac is:
- The Base64 encoded signature calculated is:
saOtyZVgcsDph3++lHfj/EzMxQOfE8UYKXisr6DdESw=
- The server response
x-server-authorization
header has value
POST request¶
This example shows the calculation for a POST request on endpoint {{baseUrl}}/v1/orders/fulfillment
with an empty response.
Request signature¶
- The input parameters for the string to sign are:
- HTTP method
POST
- Endpoint path in uppercase
/V1/ORDERS/FULFULLMENT
- Timestamp is
1678206688075
- The random nonce is
AB1CSA86767CVSJKLN878AS
. - The request body is
SHA-256 hash from request body is:
- HTTP method
- The string to sign is:
- The calculated signature in Base64 is:
L0ipqXrr9HpQoXPwzgDRSNnJKRnnZZ58oJ0FayN5ips=
- The
authorization
headers have the value:
Response signature¶
The response from the server contains no body.
- The input for the signature is thus:
- The nonce from the request
AB1CSA86767CVSJKLN878AS
- The timestamp from the request
1678206688075
- No content digest
- The nonce from the request
- The string to sign for response hmac is:
v1$1678206688075$AB1CSA86767CVSJKLN878AS
- The Base64 encoded signature calculated is:
EQ4RqNLDmtVO1xgJlyQSI1h0ZfYvOjozyhyGHjiMqrM=
- The server response
x-server-authorization
header has value
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:
- 3.125.75.87
- 3.70.34.35
- 3.72.153.100
- 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: