Skip to main content

Security & Encryption

TLS Requirements

It is recommended that the URL domain is compatible for both testing and production to ensure that during the testing stage, notification configuration meets PayNet requirements.

info

Our APIs only support TLS 1.2

Signature Generation

info

You can also find our message signature SDK or sample apps in resources section.

The following steps describe how a message signature is generated. The following list of message body parameters and values will be used for this example:

Parameter NameParameter Value
payerbanknum100033061
payerbanknameAGROBANK
billerbanknum100002144
billerbanknameSTANDARD CHART. BANK
accounttype1
billercode1123
billercodenameMaxis
nbpsref3598D772
channel3
debittimestamp2016-05-09T08:07:39.0000000+00:00
repeatmsgN
rrn1230
rrn2
currencycodeMYR
amount4550
extdatanull

Step 1: Retrieve the timestamp

The message timestamp for the operation will need to be retrieved in UTC time, e.g. 2016-05-09T08:07:05.2199272Z from message header.

Step 2: Rearrange the Message Body Parameters

All the parameters of the message body are sorted alphabetically using their parameter names. Using the parameter list above as an example, the result would be as follows:

Parameter NameParameter Value
accounttype1
amount4550
billerbanknameSTANDARD CHART. BANK
billerbanknum100002144
billercode1123
billercodenameMaxis
channel3
currencycodeMYR
debittimestamp2016-05-09T08:07:39.0000000+00:00
extdatanull
nbpsref3598D772
payerbanknameAGROBANK
payerbanknum100033061
repeatmsgN
rrn1230
rrn2

Step 3: Concatenate the Parameter Values

Each of the message body parameter values are joined together to form one string. Any empty parameters can be left out from their place in the order.

1 + 4550 + STANDARD CHART. BANK + 100002144 + 1123 + Maxis + 3 + MYR + 2016-05-09T08:07:39.0000000+00:00 + 3598D772 + AGROBANK + 100033061 + N + 1230

This will result in the following string being generated:

14550STANDARD CHART. BANK1000021441123Maxis3MYR2016-05-09T08:07:39.0000000+00:003598D772AGROBANK100033061N1230

Step 4: Insert the timestamp in front of the concatenated parameter values

The timestamp obtained from Step 1 is attached to the concatenated string from Step 3 as a prefix with the following format: yyyyMMddHHmmss

The definition of the format is as follows:

Format
yyyy4 digit Year
MM2 digit Month, therefore single digit months are padded with a zero in front, e.g. February is 02
dd2 digit Day, single digit days are padded with a zero
HH2 digit Hour in 24 hour format, zero padded
mm2 digit Minute, zero padded
ss2 digit Seconds, zero padded

Give the example above, the time stamp of 2016-05-09T08:07:05.2199272Z will become: 20160509080705

This string is placed as a prefix in front of the parameter values obtained in Step 3, which results in the following:

2016050908070514550STANDARD CHART. BANK1000021441123Maxis3MYR2016-05-09T08:07:39.0000000+00:003598D772AGROBANK100033061N1230

Step 5: Insert the Pass Key provided to the Biller at the end of the string

Each Biller is provided a secret Pass Key for use with BNS. For this example, we will use the pass key = “JQDSHALPKX”, and this value will be appended to the end of the string obtained from Step 4 as a suffix. This will result in the following string:

2016050908070514550STANDARD CHART. BANK1000021441123Maxis3MYR2016-05-09T08:07:39.0000000+00:003598D772AGROBANK100033061N1230JQDSHALPKX

Step 6: Calculate SHA256 of the string and encode the results in Base64

The SHA256 hash of the string obtained from Step 5 encoded in Base64 is: EFddam1Y/dvhBh2Nvytw2XvZMQHB3sONuWeEMzP9CuA=

This is message signature for the message. It is either inserted in message header when generating a message, or validated against message signature contained in a message response.

Example Request Message

Using the fictional example above, the request message would be as follows:


{
"header": {
"sig": "EFddam1Y/dvhBh2Nvytw2XvZMQHB3sONuWeEMzP9CuA=",
"timestamp": "2016-05-09T08:07:05.2199272Z"
},
"body": {
"payerbanknum": "100033061",
"payerbankname": "AGROBANK",
"billerbanknum": "100002144",
"billerbankname": "STANDARD CHART. BANK",
"accounttype": "1",
"billercode": "1123",
"billercodename": "Maxis",
"nbpsref": "3598D772",
"channel": "3",
"debittimestamp": "2016-05-09T08:07:39.0000000+00:00",
"repeatmsg": "N",
"rrn": "1230",
"rrn2": "",
"currencycode": "MYR",
"amount": 4550,
"extdata": null
}
}

Sample Code

package com.paynet.signer.ui.signer_jompay_ui;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class JomPaySignature {

private final static String SHA256 = "SHA-256";

public static String genSignature(String clearText) throws NoSuchAlgorithmException {
return new String(
Base64.getEncoder().encode(MessageDigest.getInstance(SHA256).digest(clearText.getBytes(StandardCharsets.UTF_8))));
}
}