Skip to main content

Notification

Notifying Result#

After completing a payment, BBMSL payment gateway will send the corresponding result back to the merchant. Merchant's backend will need to handle the result and reply an acknowledgement.

Note:

  1. When interacting with this API, if BBMSL payment system does not receive a response from the Merchant backend indicating success or timeout, the BBMSL payment system will consider it as an unreceived notification and initiate further payment result notifications at a regular interval, such as 12 times in 60 minutes, so as to ensure successful receipt. However, the BBMSL payment system cannot ensure successful receipt of payment notifications in every case. (Notification frequency: 5 minutes)
  1. As payment result notifications may be sent from the BBMSL payment system to the Merchant’s backend multiple times, a single payment result might be notified to the Merchant's backend multiple times. For this reason, the Merchant's system must be able to handle duplicate notifications properly.
  1. To ensure the integrity of the notification message, merchant must verify the signature of the notification. Please check Verifying notification signature below.

Request Url: This URL may be configured via callbackUrl.notify, a parameter submitted via the APIs of online-hosted and online-tokenization.

Request Method: POST

Expected Response: "OK", if the BBMSL payment system does not receive this response from the Merchant backend indicating received, the BBMSL payment system will treat it as an unreceived notification and initiate further payment result notifications 5 minutes later.

Payment Success Result Notification:

{
"orderId": "20873",
"amount": 100.6,
"cardType": "VISA",
"status": "SUCCESS",
"merchantReference": "REF-2021120210310101",
"signature": "c1hTR2RBNHRSNEIwd25GNk5yOFNocGZOTXRISVNXdXpMcGRLb05Xc2tJZ0Njc3BNVkZGemdrZXo0QnJtdFlYa01xWmgxdHl6LzhzTk5VM0YyVlR1MGZPeCtaUDRDbm1Wak51OGJjaXU0aFR0bnl0QTNZMUdaL3lYQVVEK21WWUdYZXlETzNmSHJxRGRJN2szeFYvUThGQ09kMGN1bFRzTjZSUk14TVpxK29xUjJ4K0VqT1hWb2ZwN0JaSndoUUU4VXM0QWw1NzNGUXo1RUhEdkNMeDM1bHEyaG9NaFhMQ1ZMVkRCSGNwQ2dvdHVZNG1nOTFNWGgvcXFjRkdZL2hRS2hHZFdBYlo5dGNwMlE1czJFU2gzN3JxeG5Pd1pycmVwSzhOQzZ2TUJQVWlTUHhRZWZwZXYybkcwSnpBSE9qUlBiQlhZdzFYQlM2UkJZS0FtdWZaWmlRPT0="
}

Add Token Result Notification:

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

Verifying notification signature#

After receiving notification, perform the following steps to verify the signature:

  1. Remove the signature field.

  2. Sort the remaining fields in alphabetical order from A to Z.

  3. Connect all array values by the character of "&". You can get the following similar content to be verified:

    amount=10&cardType=VISA&merchantReference=2021120210310101&orderId=20873&status=SUCCESS
  4. 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

The code to connect all array values to pre-verify string in Java:

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 in Java:

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));
}

The code to connect all array values to pre-verify string in PHP:

signature.php
<?php
function createPreVerifyString($params){
ksort($params);
$str = json_encode($params);
$prestr = '';
$index = 0;
foreach($params as $key => $value) {
echo "{$key} => {$value} ";
if ($index == count($params) - 1) {
$prestr = $prestr . $key . "=" . $value;
} else {
$prestr = $prestr . $key . "=" . $value . "&";
}
$index++;
}
return $prestr;
}
?>

The verify code snippet in PHP:

signature.php
<?php
$publicKey = "BBMSL public key";
$publicKeyPem = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($publicKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
$signature = "Signature in notification";
$signature = base64_decode($signature);
$result = openssl_verify($content, $signature, $publicKeyPem, OPENSSL_ALGO_SHA256);
?>