Getting Started
Transactions
Information
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
Construct a header object with the following fields:
SignatureHeader header = new SignatureHeader();
header.setAlg("HS512");
header.setKey(keyId);
header.setTimestamp(Instant.now().getEpochSecond());
Convert the header to a Base64 encoded string.
Base64.getEncoder().encodeToString(objectMapper.writeValueAsString(header).getBytes())
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]"
}
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)
Base64 encode the previously obtained value (X) from step 4.
Base64(Base64(Sha-512 hashed request body))
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());
}
Concatenate the HTTP Method, API endpoint, timestamp and ‘Y’ from step 5.
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];
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];
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.
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);
}
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.
alg=“HS512”
key=“AYO8AXQW5Fwjz0qSpKixnavUfhwc87kF”
timestamp = 1635934687
The provided example shows how this process should look at each step.
alg=“HS512”
key=“AYO8AXQW5Fwjz0qSpKixnavUfhwc87kF”
timestamp = 1635934687
{
"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