Security is of utmost importance when processing customer and payment data. This is why the PAYONE Commerce Platform is build in such a way that allows secure processing.
The API Key and API Secret provide a unique signature to protect incoming and outgoing requests between your system and our platform. The API Key and API Secret can be retrieved and managed in the Commerce Portal. Any server-to-server request from your system to our platform needs to contain API Key and should be hashed using the API Secret. The platform will authenticate the request by checking the API Key and the signature.
In this guide we explain the necessary steps in order to securely integrate the PAYONE Commerce Platform.
API Key and api Secret configuration
The API Key and API Secret are required for a successful authentication of the request. The key pair can be retrieved, updated, and deleted in the PAYONE Commerce Portal under Configuration > API Configuration:
Primary
This label indicates the primary key pair that should be used. The primary key pair will be used for webhooks.
Primary keys cannot be deactivated. For this purpose a different key pair has to be selected as "Primary" first.
Expiration Date
Indicates the date and time when a key pair will expire. Per default a key pair is valid for two years.
Status
Indicates whether a key pair is Active or Inactive (expired / deactivated)
Make sure that only authorized employees with the required role have access to the API Configuration. In case of security breaches you should deactivate the existing key pair and create a new one.
Server to server authentication
The API credentials should be used to send requests directly against the endpoints of the Commerce Platform. This requires the following authentication mechanism:
HTTP headers must be hashed using your API Secret (also called signature contents or signed-data)
This hash ist called signature and will be used together with your API Key to verify the authentication
For a better understanding of the authentication there will be GET, POST and DELETE examples in the following chapters.
General authentication process
A successful GET/POST/PATCH/DELETE request is a three step approach:
1. Create a string-to-hash, consisting of several HTTP headers
2. Calculate the signature using the algorithm HMAC-SHA256 with your API Secret
3. Send the actual request to our platform, including the headers, the signature and your API Key
1. Creating a string-to-hash
Compose the string-to-hash (the signature contents or signed-data) by following these rules:
Order of the header: The string-to-hash consists of the following headers, listed in a specific order:
Apply the following conventions for the content of the headers:
Headers
Conventions
<HTTP Method>
Use either "GET", "POST", "PATCH" or "DELETE" (always in uppercase) depending on the desired HTTP method used.
<Content-Type>
Use the fixed value "application/json; charset=utf-8" for POST and PATCH requests and use an empty string for GET or DELETE requests.
<Date>
Use the "Date" header in RFC1123 format.
<CanonicalizedHeaders>
Include custom headers specific to your application, these headers always start with X-GCS, such as X-GCS-ClientMetaInfo
<CanonicalizedResource>
Include the target URI without the HTTP method, and include all decoded query parameters.
Unwrap Header Values
If a header value is wrapped over multiple lines, unwrap each line as described here. Unwrap by replacing a new line or multiple spaces by a single white space. Example:
A very long line<CR><LF>
<SPACE><SPACE><SPACE><SPACE>that does not fit on a single line
will become
A very long line that does not fit on a single line
Trim Whitespaces
Trim all whitespaces which exist at the start and end of the value. Example:
Although the same rules apply for either HTTP method, you need to take the differences for GET/DELETE/PATCH requests into account when creating the string-to-hash (i.e. missing content type, addition of query parameters to the request URI).
Have a look at the GET example or the DELETE example in the next chapters for instructions
2. Calculate signature
Once you have created the string-to-hash (the signature contents or signed-data), you need to hash it via the MAC algorithm HMAC-SHA256 with your API Secret.
The result of the hashing is the signature you need to provide in the authorization header of your request.
---end
Example-Code (Java)
public static String createEncodedSignature(String stringToHash, String yourApiSecret) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
// Convert stringToHash + key into byte array
String algorithm = "HmacSHA256";
byte[] keyAsBytes = yourApiSecret.getBytes("UTF-8");
byte[] stringToHashAsBytes = stringToHash.getBytes("UTF-8");
SecretKeySpec secretKeySpec = new SecretKeySpec(keyAsBytes, algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(stringToHashAsBytes);
return Base64.encodeBase64String(hash);
}
As the general requirements for a GET/POST/DELETE/PATCH request differ, the construction of the string-to-hash does as well. Have a look at the following examples to learn how to implement them in your system
POST Request
The string-to-hash (the signature contents or signed-data) for a CommerceCase request:
POST
application/json; charset=utf-8
Wed, 02 Mar 2023 11:15:51 GMT
/v1/yourMerchantId/commerce-cases
Be aware that there is a new line (line feed) after the last header (URI resource) which you also need to consider when hashing the string
GET Request
The string-to-hash (the signature contents or signed-data) for a GetCheckout request:
GET
application/json; charset=utf-8
Wed, 02 Mar 2023 11:15:51 GMT
/v1/yourMerchantId/commerce-cases/yourCommerceCaseId/checkouts/yourCheckoutId
Be aware that there is an empty string for Content-Type header, as GET request do not have a request body. There is a new line (line feed) after the last header (URI resource) which you also need to consider when hashing the string.
DELETE Request
The string-to-hash (the signature contents or signed-data) for a DeleteCheckout request:
DELETE
application/json; charset=utf-8
Wed, 02 Mar 2022 11:15:51 GMT
/v1/yourMerchantId/commerce-cases/yourCommerceCaseId/checkouts/yourCheckoutId
Be aware that there is an empty string for Content-Type header, as GET request do not have a request body. There is a new line (line feed) after the last header (URI resource) which you also need to consider when hashing the string.
Patch Request
The string-to-hash (the signature contents or signed-data) for a PatchCheckout request:
PATCH
application/json; charset=utf-8
Wed, 02 Mar 2022 11:15:51 GMT
/v1/yourMerchantId/commerce-cases/yourCommerceCaseId/checkouts/yourCheckoutId
Be aware that there is a new line (line feed) after the last header (URI resource) which you also need to consider when hashing the string