Scroll to top

To safeguard the interactions between your backend systems and the Luxon API, we employ a robust authentication system. This authentication method employs a specific signing mechanism to ensure that the API calls originated from authentic sources and haven’t been tampered with during transit. Below is a step-by-step guide on how to create this authentication signature.

SIGNATURE FORMAT

AAA.BBB

Generate signature header part one: AAA

1. Header Creation:

Construct a header object with the following fields:

  • Algorithm (alg)
  • Key
  • Timestamp

Java Example

SignatureHeader header = new SignatureHeader();
header.setAlg("HS512");
header.setKey(keyId);
header.setTimestamp(Instant.now().getEpochSecond());

2. Encoding the Header (AAA):

Convert the header to a Base64 encoded string.

Java

Base64.getEncoder().encodeToString(objectMapper.writeValueAsString(header).getBytes())


Generate signature header part two: BBB

3. Preparing the Payload (Request Body - after removeEscapeSequenceAndWhiteSpace):

Make sure the request body does not have any white spaces or escape sequences.

{
"merchantTransactionId":"[value]",
"merchantUserId":"[value]",
"redirectUrl":"string",
"comment":"[value]",
"amount":[value],
"currency":"[value]"
}

4. SHA-512 Hashing of Payload (X):

Compute the SHA-512 hash of the request body, even if it is empty and then Base64 encode it.

Base64(Sha-512 hashed request body)

5. Double Base64 Encoding (Y):

Base64 encode the previously obtained value (X) from step 4.

Base64(Base64(Sha-512 hashed request body))

Java

var payloadHashedBase64Base64 = Base64.getEncoder().encodeToString(encodeWithSha(requestBody).getBytes());

where encodeWithSha(String requestBody) ->
public static String encodeWithSha(String requestBody) throws NoSuchAlgorithmException {
	String unEscaped = StringUtils.removeEscapeSequenceAndWhitespace(requestBody);
	MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
	messageDigest.update(unEscaped.getBytes());
	return Base64.getEncoder().encodeToString(messageDigest.digest());
}

6. Constructing the Signature String:

Concatenate the HTTP Method, API endpoint, timestamp and ‘Y’ from step 5.

Java Example

String requestMethod = "POST";
String requestPath = "/api/v1/merchant/payment";
String requestQueryString = requestQueryString == null ? "" : requestQueryString;
String timestampValue = header.getTimestamp();

String stringSignature = POST/api/v1/merchant/payment[timestampValue][Y];

Java Example

String requestMethod = "POST";
String requestPath = "/api/v1/merchant/payment";
String requestQueryString = requestQueryString == null ? "" : requestQueryString;
String timestampValue = header.getTimestamp();

String stringSignature = POST/api/v1/merchant/payment[timestampValue][Y];

7. Generating HMAC and Encoding (BBB):

Using the merchant’s key and the HMAC SHA-512 algorithm, compute the HMAC of the signature string from step 6 and then Base64 to encode the result.

Java Example for how to create BBB

String B = signWithHmac(keyValue, stringSignature, header.getAlg());

where ->
public static String signWithHmac(String keyValue, String stringSignature, String algorithm) throws NoSuchAlgorithmException, InvalidKeyException {
String alg = "HmacSHA512"; // algorithm is HS512
Key signingKey = new SecretKeySpec(keyValue.getBytes(), alg);
Mac mac = Mac.getInstance(alg);
mac.init(signingKey);
byte[] encoded = mac.doFinal(stringSignature.getBytes());
return Base64.getEncoder().encodeToString(encoded);
}


Final Signature (AAA.BBB):

8. Concatenate AAA from step 2 and BBB from step 7, separated by a dot ‘.’.

This signature is then added to the headers of the HTTP request when making a call to the Luxon API, allowing Luxon to validate the authenticity and integrity of the incoming request.

Always ensure to include the Content-type: APPLICATION-JSON header in the API request.

Note: Care should be taken to keep the key confidential and to ensure that the timestamp used in the signature is synchronized with the server time for accuracy.


Header

alg=“HS512”
key=“AYO8AXQW5Fwjz0qSpKixnavUfhwc87kF”
timestamp = 1635934687

Auth Process Example

The provided example shows how this process should look at each step.

Header

alg=“HS512”
key=“AYO8AXQW5Fwjz0qSpKixnavUfhwc87kF”
timestamp = 1635934687

Request body

{
"amount": 10000,
"currency": "EUR"
}

1. SignatureHeader:
(alg=HS512, key=AYO8AXQW5Fwjz0qSpKixnavUfhwc87kF,
timestamp= 1635934687)

2. Base64 encoded header:
eyJhbGciOiJIUzUxMiIsImtleSI6IkFZTzhBWFFXNUZ3anowcVNwS2l4bmF2VWZod2
M4N2tGIiwidGltZXN0YW1wIjoxNjM1OTM0Njg3fQ==

3. Request body after removeEscapeSequenceAndWhiteSpace:
requestBody ={"amount":10000,"currency":"EUR"}

4. Base64(Sha hashed request body):
“W1k4yX8MwyWOxS+KxvdjnCeMmYv6E8U/XzYiCkbOfGz+Qauo/sHgUJHUduzUH7
j38MRSk8BC3+ESasbGy++kog==“

5. Base64(Base64(Sha hashed request body)):
“VzFrNHlYOE13eVdPeFMrS3h2ZGpuQ2VNbVl2NkU4VS9YellpQ2tiT2ZHeitRYXVvL 3NIZ1VKSFVkdXpVSDdqMzhNUlNrOEJDMytFU2FzYkd5Kytrb2c9PQ==”

6. String signature:
“POST/api/v1/merchant/payment1635934687VzFrNHlYOE13eVdPeFMrS3h2ZGpuQ
2VNbVl2NkU4VS9YellpQ2tiT2ZHeitRYXVvL3NIZ1VKSFVkdXpVSDdqMzhNUlNrOE
JDMytFU2FzYkd5Kytrb2c9PQ==“

7. Base64 encoded HMAC encoded signature:
“HkVb2s/Ee65rqNjmCO20CpKEXGNVQ9TpVyInj/afFhMb5oV8cPFYp3+o5ywVGylc
+pozpN89m4wSJXGgW08C1w==“

8. X-signature:
“eyJhbGciOiJIUzUxMiIsImtleSI6IkFZTzhBWFFXNUZ3anowcVNwS2l4bmF2VWZod2
M4N2tGIiwidGltZXN0YW1wIjoxNjM1OTM0Njg3fQ==.HkVb2s/Ee65rqNjmCO20CpK
EXGNVQ9TpVyInj/afFhMb5oV8cPFYp3+o5ywVGylc+pozpN89m4wSJXGgW08C1w
==”

Content-type: APPLICATION-JSON