Appendix 1
Security Control
Response Page SHValue
Merchant and PayMaster will share a SECRET KEY, which will be used by both parties to create a Secure Hash Value for the transaction data.
- The Secret Key shall be obtained from the PayMaster Gateway.
The payment response message will include the SHAlgorithmType
and SHValue
. The Merchant shall use these two values to verify the response message sent by PayMaster to ensure that the data has not been tampered with.
To verify this, the Merchant should remove the Trailer Fields (t001_SHT
and t002_SHV
) from the response message, append the remaining message with the Merchant's Secret Key, and then encode the string using the SHA-256 HMAC hashing algorithm.
Once the encoded result is obtained, compare it with the value in SHValue
.
- The values must be equal.
Example
Step 1 : Remove trailer fields
Remove the trailer fields (the last two lines) from the response message returned by the PayMaster Gateway.
h001_MTI=0290&h002_VNO=06&h003_TDT=20230811&h004_TTM=16241856&f001_MID=000010000012639&f004_PAN=545301XXXXXX5323&f005_ExpDate=2710&f006_TxnDtTm=20230811162418&f007_TxnAmt=000000000100&f009_RespCode=00&f010_CurrCode=458&f011_AuthIDResp=774585&f019_ExpTxnAmt=2&f023_RRN=322382167159&f024_OrgRespCode=00&f254_DDRespCode=00&f256_FICode=&f257_PGRN=230811162420AC069FNX&f258_TxnStatDetCde=0000&f259_TxnStatMsg=SUCCESS&f260_ServID=FNX&f261_HostID=&f262_SessID=&f263_MRN=20230811162418FNX&f270_ORN=&f277_DDRN=&f283_UPP_PM=00&f286_OrgDDRespCode=22&f350_CrdTyp=MST&f352_AcqBank=&f353_IPPTenure=&f325_ECommMercInd=1&f339_TokenFlg=N&f344_MercCustId=&f346_Token=&f347_TokenShrtNm=&f348_MaskPAN=&f365_POSEnvFlg=&t001_SHT=SH2&t002_SHV=FC63B34696B77153044E6D353D0241088A44EC13CCF5C414FFC30CE815C96614
h001_MTI=0290&h002_VNO=06&h003_TDT=20230811&h004_TTM=16241856&f001_MID=000010000012639&f004_PAN=545301XXXXXX5323&f005_ExpDate=2710&f006_TxnDtTm=20230811162418&f007_TxnAmt=000000000100&f009_RespCode=00&f010_CurrCode=458&f011_AuthIDResp=774585&f019_ExpTxnAmt=2&f023_RRN=322382167159&f024_OrgRespCode=00&f254_DDRespCode=00&f256_FICode=&f257_PGRN=230811162420AC069FNX&f258_TxnStatDetCde=0000&f259_TxnStatMsg=SUCCESS&f260_ServID=FNX&f261_HostID=&f262_SessID=&f263_MRN=20230811162418FNX&f270_ORN=&f277_DDRN=&f283_UPP_PM=00&f286_OrgDDRespCode=22&f350_CrdTyp=MST&f352_AcqBank=&f353_IPPTenure=&f325_ECommMercInd=1&f339_TokenFlg=N&f344_MercCustId=&f346_Token=&f347_TokenShrtNm=&f348_MaskPAN=&f365_POSEnvFlg=
Step 2 : Append the Secret Key to the response message
Append the Secret Key to the response message after removing the trailer fields. This will result in a string formatted as Response Message without Trailer Fields + Secret Key
. Encode this string using the algorithm specified in SHAlgorithmType
. In this example, SHA-256 is used.
Step 3 : Compare the encoding result with the hash value
Compare the encoded result with the hash value in SHValue
. The two values must match.
In this example:
- Assuming secret key is
00112233445566778899AABBCCDDEEFF
, the hash value isE73CEDA9D9A8D1AAF59BDB919EF7C82D52671A4B457CE816BCE91AFF31485259
.
The Merchant MUST reject any non-matching results and report them to PayMaster.
Sample Code
public void resPayment() throws Exception {
String secretKey = "B96856FA91749A259F71340E3C6BC3478524320F218587D22071A35DD4E7BXXX";
String response = "h001_MTI=0290&h002_VNO=06&h003_TDT=20230811&h004_TTM=16241856&f001_MID=000010000012639&
f004_PAN=545301XXXXXX5323&f005_ExpDate=2710&f006_TxnDtTm=20230811162418&f007_TxnAmt=000000000100&f009_Resp
Code=00&f010_CurrCode=458&f011_AuthIDResp=774585&f019_ExpTxnAmt=2&f023_RRN=322382167159&f024_OrgRespCode=0
0&f254_DDRespCode=00&f256_FICode=&f257_PGRN=230811162420AC069FNX&f258_TxnStatDetCde=0000&f259_TxnStatMsg=S
UCCESS&f260_ServID=FNX&f261_HostID=&f262_SessID=&f263_MRN=20230811162418FNX&f270_ORN=&f277_DDRN=&f283_UPP_
PM=00&f286_OrgDDRespCode=22&f350_CrdTyp=MST&f352_AcqBank=&f353_IPPTenure=&f325_ECommMercInd=1&f339_TokenFl
g=N&f344_MercCustId=&f346_Token=&f347_TokenShrtNm=&f348_MaskPAN=&f365_POSEnvFlg=" + secretKey;
SecretKeySpec byteSecretKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
Mac sha256_MAC = Mac.getInstance("HmacSHA256");
sha256_MAC.init(byteSecretKey);
String hashed = this.bytesToHex(sha256_MAC.doFinal(response.getBytes()));
System.out.println(hashed.equalsIgnoreCase("FCXX3469XX7715304XX6XX53XX241088XX4EXX3CCXXC41XXFXX0CXX15XX6614"));
}
public String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
byte[] var6 = bytes;
int var5 = bytes.length;
for(int var4 = 0; var4 < var5; ++var4) {
byte b = var6[var4];
sb.append(String.format("%02x", b));
}
return sb.toString();// 31
}