Skip to main content

Notification

After completing a payment, the BBMSL payment system will send the relevant payment result to the Merchant. When this happens, the Merchant’s backend will need to receive the result and return a reply to the BBMSL payment system.

Note:

  1. When interacting with this API, if the 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 avoid receiving fake notifications, merchants must verify the signature of the notification. Please check Verify 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="
}

Verify 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: BBMSL sit public key: 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);
?>