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:
- 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)
- 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.
- 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
ornotifyUrl
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:
Remove the signature field
Sort the remaining fields in alphabetical order
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
- 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:
- Java
- PHP
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;
}
<?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:
- Java
- PHP
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));
}
<?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);
?>