Skip to main content

Notification

After completing an order, BBMSL Online Payment Gateway will send the successful result back to the merchant if corresponding information is given. Merchant's backend will need to handle the result and reply an acknowledgement.

Remarks:

  1. If the BBMSL Online Payment Gateway does not receive the acknowledgement from the Merchant, it will consider it as an unreceived notification and initiate further payment result notifications at a regular interval, such as 12 times in an hour, to increase success receiving rate. However, the BBMSL Online Payment Gateway cannot ensure successful receipt of payment notifications. (Notification frequency: 5 minutes)
  1. As payment result notifications may be sent to the Merchant’s backend multiple times, the Merchant's system must be able to perform deduplication to the notifications properly.
  1. To ensure the integrity of the notification message, merchant must verify the signature of the notification. Please check Verifying Signature section below.

Receiving Notification#

The merchant needs to provide a REST API endpoint for the BBMSL Online Payment Gateway to notify the success order result, the result will be constructed as the API request body.

  • Request URL: This URL may be configured via callbackUrl.notify or notifyUrl as a parameter value submitted through the APIs.

  • Request Method: POST

  • Expected Acknowledgement Response: OK

Two notification request body example is given below,

Example Payment Success Result Notification (hosted-checkout/direct model):#

{
"amount": "699.00",
"maskedPan": "400000XXXXXX1000",
"orderId": "489825",
"signature": "TBiLEQLljyNfG5B7JyC0sknXlCSr/BJz8knKfSv6ZYRCxMN2tVE9pd95pTmW19bP49GjsefFs+Ae2yD6rImFda0UBf7XUjUawcZJxXIcEyxl9uTJp4bJ+YuJv4JVd4xRZ0KAqeigF6izaYsOsB4rqOrfX4pMZhh1FouLKwCc4to31ONHLr7QwnGad0YP0678s7Et5UVM7o4uI1M4HAGRftya6vl7DBxHWbaws7FPFjoA/pV2tmg43rrDxqmQIUxAdDvSLLCSi3b7MHz4fKcHOeFEIFdfXEy68E6Ju3DnX3zuzoLxgEeSNwESR0pp3Rv3RCjkuEJk6VCXhWSxGD16lg==",
"cardType": "VISA",
"updateTime": "2022-11-11T08:34:46+0000",
"merchantReference": "202211113141643461113734009044",
"status": "SUCCESS"
}

Example Add Token Success Result Notification:#

{
"userId": "userName",
"tokenId": "12541",
"type": "AddToken",
"maskedPan": "4325xxxxxxxx2654",
"signature": "c1hTR2RBNHRSNEIwd25GNk5yOFNocGZOTXRISVNXdXpMcGRLb05Xc2tJZ0Njc3BNVkZGemdrZXo0QnJtdFlYa01xWmgxdHl6LzhzTk5VM0YyVlR1MGZPeCtaUDRDbm1Wak51OGJjaXU0aFR0bnl0QTNZMUdaL3lYQVVEK21WWUdYZXlETzNmSHJxRGRJN2szeFYvUThGQ09kMGN1bFRzTjZSUk14TVpxK29xUjJ4K0VqT1hWb2ZwN0JaSndoUUU4VXM0QWw1NzNGUXo1RUhEdkNMeDM1bHEyaG9NaFhMQ1ZMVkRCSGNwQ2dvdHVZNG1nOTFNWGgvcXFjRkdZL2hRS2hHZFdBYlo5dGNwMlE1czJFU2gzN3JxeG5Pd1pycmVwSzhOQzZ2TUJQVWlTUHhRZWZwZXYybkcwSnpBSE9qUlBiQlhZdzFYQlM2UkJZS0FtdWZaWmlRPT0="
}

Verifying Signature#

Like using PayAPI, each notification comes with a signature, you may perform the following steps to verify it:

  1. Remove the signature field

  2. Sort the remaining fields in alphabetical order

  3. Join all array values with the character of &. You will get similar content like the following,

amount=10&cardType=VISA&merchantReference=2021120210310101&orderId=20873&status=SUCCESS
  1. Use the RSA2/RSA verification method to verify the signature

Below is BBMSL test host public key for verifying notification:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkDecXu4GFMxCqp4pjfwtN1nSQiV9kmdcBMnKq5IeLB6BYWOENqeY+JFftnNaxHOgnhOrbrl71D6G57G7rhNLClgBNerB7mINDBwvENkEVq6zNbJsjOJekJtTVkxs7KoBip44odCBmElCFrUsr0qOr10kzUzYHXXEUpTqQon3jDGm+EkFoNv3RLwn0ZWuwid5kuk6tZ0Xj3OxiKTrzXK2STjzJ8Q25e9CKbO03fpaMSpBRrkuA1NHRQoSO0ew6lGE4swQ+dseVbh+z7YFVUWqDyjJ6pB+F3p4vDniw4r9/rE+ikP0eLMg99vWDjuQbPtUHYaQtMYNSzrmcTkBCGkt6QIDAQAB

Example code#

To connect all array values to pre-verify string:

signature.java
public static String createPreVerifyString(Map<String, String> params) {
List<String> keys = new ArrayList<>(params.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}

The verify code snippet:

signature.java
private static final String KEY_ALGORITHM = "RSA";
private static final String SIGNATURE_ALGORITHM = "SHA256WithRSA";
private static final String DEFAULT_CHARSET = "UTF-8";
public static boolean verify(String content, String publicKey, String sign) throws Exception {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(content.getBytes(DEFAULT_CHARSET));
return signature.verify(Base64.decode(sign));
}