In order to ensure the integrity of the data being transmitted, AMWAL Payment Gateway uses SHA-256 hashing with a secret key (Merchant Secure Key). Merchants need to calculate a secure hash on their end and send it along with the payment request. Our system will validate this hash to ensure the request is authentic and has not been tampered with.
Secure hash calculation shouldn’t be handled at the client side (ex: JS side). For security reasons it should be handled at the backend and send to front end for further steps.
Follow these steps to calculate the secure hash:
Prepare the Data
- Collect all the required parameters for the payment request.
- Ensure the data is properly validated and sanitized to prevent potential attacks such as injection and length extension attacks.
Merchant Secure Key
- Use the Merchant Secure Key provided by AMWAL Payment Gateway. This key is unique to each merchant and serves as a salt to protect against rainbow table attacks.
- The key should be at least 64 bits (8 bytes) in length and kept confidential.
Concatenate the Data and the Secret Key
- Sort the data parameters alphabetically by key.
- Concatenate the sorted key-value pairs into a string in the format key=value.
- Concatenate this string with the Merchant Secure Key.
Generate the SHA-256 Hash
- Use the SHA-256 algorithm to hash the concatenated string of key-value pairs and the Merchant Secure Key.
- The resulting hash will be the secure hash for the transaction.
Transmit the Data and Hash
- Send both the original data and the calculated SHA-256 hash to AMWAL Payment Gateway.
Verification by AMWAL
- AMWAL Payment Gateway will receive the transmitted data and hash.
- On the server-side, AMWAL Payment Gateway will concatenate the same data with the merchant’s secret key and generate a SHA-256 hash.
- The system will compare the calculated hash with the hash received from the merchant. If they match, the transaction is considered secure and untampered.
Example Code
Here are some sample code snippets that demonstrate how to calculate the secure hash in different programming languages.
import * as crypto from 'crypto';
let paramsObj = {
Amount: "10",
CurrencyId: "512",
MerchantId: "48804",
MerchantReference: '',
TrxDateTime: " 2024-12-31T15:27:10.361969Z",
TerminalId: "113176",
/* if the merchant is not enabled for recurring payment, Use Empty Session token
But if Merchant is enabled for recurring payment he can
request a session token from an API (Check Merchant API Integration Doc):
You can check this section for further info Get Smartbox Session Token */
SessionToken: `eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..w__uUsJEv6GYqWSAbSHl4w.g44u9CS3Ye3DWaixF3rITecIognMFIAgg7eQUBLl7EUR76acc2km4xwfKKLJuFtZbR4A4I7JgJX3jFEqxgfERYEvbS-1UKQYIZUme
ch2K0y21LsUyQXz3tcKZWoBKHJh4NRvQr1AkWwPQkc3xhOzevGDQux4EGEeRRkchayvLBn39O_ZmuyGuz3OStoGLgKrQaN9L2ga5g54u-2SsQP_Kf2A0RRvdgioXdAxsH5j2Z0xjkc1HE1t10e3JBvwCsE8ohap5TtcXZFT4B88wql4Ut4kZRgK0VOHpl4QgNALeJBIrLN21AEc-K7FexWYCw2itGzmPODSxuBpMyL80BR9CR_1.SL9xnd_0bIDYI0RLCPtVPg`
}
function calcHash(obj: any, secret: string) {
try {
let paramSortedAndConcatenated = `Amount=${obj.Amount}&CurrencyId=512&
MerchantId=${obj.MerchantId}&
MerchantReference=${obj.MerchantReference}&
RequestDateTime=${obj.TrxDateTime}&
SessionToken=${obj.SessionToken}&TerminalId=${obj.TerminalId}`
const hmac = crypto.createHmac('sha256', Buffer.from(secret, 'hex'));
const hashValue = hmac.update(paramSortedAndConcatenated, 'utf-8').digest('hex');
return hashValue.toUpperCase();
} catch (error) {
return '';
}
}
let hash = calcHash(paramsObj, "YOUR_SECURE_HASH_KEY")
PHP Example
<?php
function encryptWithSHA256($input, $hexKey) {
// Convert the hex key to binary
$binaryKey = hex2bin($hexKey);
// Calculate the SHA-256 hash using hash_hmac
$hash = hash_hmac('sha256', $input, $binaryKey);
return $hash;
}
// Provided input text
$inputText = "Amount=36&CurrencyId=512&MerchantId=1369217&
MerchantReference=26_23122645&RequestDateTime=2023-12-26T09:42:46Z&SessionToken=&
TerminalId=6942344";
// Provided hex key
$hexKey = "9FFA1F36D6E8A136482DF921E856709226DE5A974DB2673F84DB79DA788F7E19";
// Calculate SHA-256 hash
$result = encryptWithSHA256($inputText, $hexKey);
?>
Example Secure Hash Calculation
- Merchant Secure Key 64373939653761352D343730352D343666632D623264312D3436323532346361616 5564654
- Data to be Hashed “Amount=10&CurrencyId=512&MerchantId=48804&MerchantReference=&Request DateTime=121123103839&SessionToken=&TerminalId=113176”
After performing the steps above, the resulting secure hash will be: 8A8E9F1BC2979D6D89A947008831199E76331689D5B28D41395FA1DA65FFDE7B
This secure hash should be sent along with the request to AMWAL Payment Gateway, and our system will validate it to ensure the transaction’s integrity.
Submit the Payment Request #
This section describes the parameters you need to configure before submitting the payment request. Below is a table of all the required parameters:
Field Name | Mandatory | Field Type | Constraints | Description | Sample Value |
---|---|---|---|---|---|
customerId | Yes | String | Length: 1–36 | Unique identifier for the customer. Received when the customer checks “save card” option. The completeCallBack will hold the customerId value. | 7267684c-3600-403e-81c7-87d778496e28 |
merchantId | Yes | Numeric | Length: 1–30 | AMWAL Payment Gateway MerchantID | 189903 |
requestDateTime | Yes | String | DateTime | Request Date Time | “2023-11-12T10:38:39.92000Z” |
secureHashValue | Yes | String | See section “Generate The Secure Hash” | Secure Hash Value | “84EB3BF62F25717D1E9E13C3CFB719A890980BF2631AFB8965182ADE1754” |
NOTE: Ensure that the requestDateTime matches the server time closely to avoid security validation errors.
Sample Request #
POST /Customer/GetSmartboxDirectCallSessionToken
Content-Type: application/json
{
/*customer id is the value that merchant received with the response of
the first transaction execution and with request to enable save card
checkbox at the Payment Page, the complete call back will hold the
customer Id value.
The unique CustomerId should be received in the response so that
merchant can save and use it here to generate a private session token
for the next payment.
This session token should allow the customer to see his saved cards in
order to choose from them and proceed with payment*/
"customerId":"7267684c-3600-403e-81c7-87d778496e28",
"merchantId": 7921,
"requestDateTime": "2023-11-12T10:38:39.92000Z",
"secureHashValue":"84EB3BF8F62EF25717D1E9E13C3CFB719A890980BBF2631AFD
8965182ADE1754"
}
Sample Response #
If the request is successful, the response will include a sessionToken, allowing the customer to view and select from their saved cards
{
"success": true,
"responseCode": "00",
"message": "Success",
"data": {
"sessionToken":
"eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..w__uUsJEv6GYqWSAbSHl4
w.g44u9CS3hFSYe3DWaixF3rITecIognMFIAgg7eQUBLl7EUR76acc2km4xwfKKLJuFtZbR4A4I7JgJX3jFE
qxgfERYEvbS-
},
"errorList": []
}
Generating Secure Hash #
To secure the API call, generate a hash value (secureHashValue) by concatenating and sorting the request parameters. Use a SHA-256 HMAC with your secret key to produce the hash.
Response Integrity Validation
For Integrity concerns we included a secureHashValue that you can use to make sure the response is received as expected
{
"success": true,
"responseCode": "00",
"message": "Success",
"data": {
"systemTraceNr": null,
"message": "CAPTURED - ",
"transactionId": "6b75efb6-84ab-46f2-8a32-351a23490f45",
"isOtpRequired": false,
"hostResponseData": {
"TransactionId": "202434515895614",
"Rrn": "434580000143",
"TrackId": "6b75efb684ab46f28a32351a23490f45",
"PaymentId": null,
"Auth": "537465"
},
"terminalId": 221143,
"transactionTypeId": 2,
"transactionTypeDisplayName": "Purchase",
"merchantId": 7921,
"currency": null,
"amount": 1,
"currencyId": 512,
"merchantName": "MahmoudGrocery",
"transactionTime": "2024-12-10T15:56:37.1099636Z",
"customerId": "82383bce-6e32-4f5b-b1ea-7e00d5c446ed",
"customerTokenId": "aacd0817-2246-4521-a3df-9f3971c63a22",
"secureHashValue":
"A1091C89D4C2D3E95630722DE0469DBDAB6FD01AF005E76A36ABFA2D45997B91", //
compare this value with your calculated value it should be the same
"merchantReference": "201204"
},
"errorList": []
}
Calculate the secure hash for the following parameters with their correspondent values from the response
let integrityParametrs = {
"amount" : response.data.amount,
"currencyId" : response.data.currencyId,
"customerId" : response.data.customerId,
"customerTokenId" : response.data.customerTokenId,
"merchantId" : response.data.merchantId,
"merchantReference" : response.data. merchantReference,
"responseCode" : response.responseCode,
"terminalId" : response.data.terminalId,
"transactionId" : response.data.transactionId,
"transactionTime" : response.data.transactionTime,
};
Example sorted string:
amount=1¤cyId=512&customerId=82383bce-6e32-4f5b-b1ea7e00d5c446ed&customerTokenId=aacd0817-2246-4521-a3df9f3971c63a22&merchantId=7921&merchantReference=201204&responseCode=00 &terminalId=221143&transactionId=6b75efb6-84ab-46f2-8a32- 351a23490f45&transactionTime=2024-12-10T15:56:37.1099636Z
Secure hash value output:
4E21F6F06C188F38B0B6A3CD2EFD9DC93EE83E3D5284C708B1C8930D9BCF0D11
compare this secure hash result with the one received in the response it should be the same