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);
}
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.
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:
eyJhbGciOiJIUzUxMiIsImtleSI6IkFZTzhBWFFXNUZ3anowcVNwS2l4bmF2VWZod2M4N2tGIiwidGltZXN0YW1wIjoxNjM1OTM0Njg3fQ==
3. Request body after removeEscapeSequenceAndWhiteSpace:
requestBody ={"amount":10000,"currency":"EUR"}
4. Base64(Sha hashed request body):
“W1k4yX8MwyWOxS+KxvdjnCeMmYv6E8U/XzYiCkbOfGz+Qauo/sHgUJHUduzUH7j38MRSk8BC3+ESasbGy++kog==“
5. Base64(Base64(Sha hashed request body)):
“VzFrNHlYOE13eVdPeFMrS3h2ZGpuQ2VNbVl2NkU4VS9YellpQ2tiT2ZHeitRYXVvL3NIZ1VKSFVkdXpVSDdqMzhNUlNrOEJDMytFU2FzYkd5Kytrb2c9PQ==”
6. String signature:
“POST/api/v1/merchant/payment1635934687VzFrNHlYOE13eVdPeFMrS3h2ZGpuQ2VNbVl2NkU4VS9YellpQ2tiT2ZHeitRYXVvL3NIZ1VKSFVkdXpVSDdqMzhNUlNrOEJDMytFU2FzYkd5Kytrb2c9PQ==“
7. Base64 encoded HMAC encoded signature:
"1EVBn9oETR04ITdAcGajQYjVHY9L1J4336BJlWF5JQ6rNzhv/CmdfxoGSmzsHYsQaTTo4+WuPNUkRqeLohpMUg=="
8. X-signature:
“eyJhbGciOiJIUzUxMiIsImtleSI6IkFZTzhBWFFXNUZ3anowcVNwS2l4bmF2VWZod2M4N2tGIiwidGltZXN0YW1wIjoxNjM1OTM0Njg3fQ==.1EVBn9oETR04ITdAcGajQYjVHY9L1J4336BJlWF5JQ6rNzhv/CmdfxoGmzsHYsQaTTo4+WuPNUkRqeLohpMUg==”
Content-type: APPLICATION-JSON