Integration setup
PayAPI is the set of APIs provided by BBMSL for processing payment requests from merchants. PayAPI allows sensitive payment data to be exchanged between a merchant's backend and BBMSL accurately and securely.
All PayAPI endpoints share the following characteristics regardless of integration model.
Security model
Merchant identification
Every onboarded merchant receives a unique merchant ID. You must include this ID in every PayAPI request.
Connection security
All APIs are protected by Transport Layer Security (TLS) and an IP whitelisting strategy. Requests must be sent over HTTPS; HTTP requests will not be processed.
Request authentication
Each PayAPI request must be signed with your RSA private key. BBMSL verifies the digital signature using your registered public key to confirm request integrity and non-repudiation.
- Key algorithm: RSA (2048-bit)
- Signature algorithm: SHA256WithRSA
Generate your RSA key pair
You may use any tool that produces a 2048-bit RSA key pair. The steps below use OpenSSL.
- Generate the private key:
$ openssl genrsa -out rsa_private_key.pem 2048
- Export the public key:
$ openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
Register your public key with BBMSL
After generating the key pair, share your public key with BBMSL by following these steps:
-
Remove the PEM header, footer, and all line breaks (
\n) from the public key string.Raw key (with header/footer):
-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxm/VrrMFmczDa+l+21UcwYU+wDdL074DnIRsaLCVqcVRPMPrQiq1og3N1Li9rneMWALHAhXKyH101BNOGYW2uiZgWLPkz6dcYgd1WiCKsOcks7E8Kn9jH0PB+1issv9qk8aLHysiscIajWU69phoGhGcsJu9uk2GdW0zo6I+9vBSE2l8wfG0Sy3sVZeYzm/nmCC9UgI1oWMCLrO3Y43l896dItR9z8SAo3Ao77gz6UmJs32zHRM6UA5lv+ssYAZiS8OkVLCTx/DVcKyNvFAKaoBDYvy1wOX+2o62cANrj0J7ybQ9M1VurQuEVeOuKFjT8GCO9DcvCcUaj3WxNlf3/QIDAQAB-----END PUBLIC KEY-----Processed key (header, footer, and line breaks removed):
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxm/VrrMFmczDa+l+21UcwYU+wDdL074DnIRsaLCVqcVRPMPrQiq1og3N1Li9rneMWALHAhXKyH101BNOGYW2uiZgWLPkz6dcYgd1WiCKsOcks7E8Kn9jH0PB+1issv9qk8aLHysiscIajWU69phoGhGcsJu9uk2GdW0zo6I+9vBSE2l8wfG0Sy3sVZeYzm/nmCC9UgI1oWMCLrO3Y43l896dItR9z8SAo3Ao77gz6UmJs32zHRM6UA5lv+ssYAZiS8OkVLCTx/DVcKyNvFAKaoBDYvy1wOX+2o62cANrj0J7ybQ9M1VurQuEVeOuKFjT8GCO9DcvCcUaj3WxNlf3/QIDAQAB -
Upload the processed key string to BBMSL Business Portal and activate it.
-
Obtain the BBMSL public key. You will need this key to verify incoming notification signatures. See Verify notification signature.
Contact your relationship manager to obtain the BBMSL public key.
Sign a request
Prepare your request parameters as a JSON object, then follow these steps:
-
Serialize the JSON object to a JSON string (the
requestvalue).example request body{"merchantId": "111","amount": 11.5,"merchantReference": "OnlineReference1649431783807","callbackUrl": {"success": "https://yourDomain/online-test/success","fail": "https://yourDomain/online-test/fail","cancel": "https://yourDomain/online-test/cancel","notify": "https://yourBackendApiEndpoint/online-test/notify"},"isRecurring": false,"lineItems": [{"quantity": 1,"priceData": {"unitAmount": 1.5,"name": "Test online"}},{"quantity": 1,"priceData": {"unitAmount": 10,"name": "Ten dollars"}}]} -
Sign the JSON string with your RSA private key (2048 bits) using the SHA256WithRSA signature algorithm.
-
Base64-encode the resulting signature bytes. A sample encoded signature:
mRcV8hQPP60VVPtve3Zwkvxt0lLuAEwKaheuNypq6u4mXkJN1LTiJ9xoZcO1rIba8q94Lsp1yDTkpjWWz964uYKSxhSw0CqFaXVz77zTeltWa59d6GpEyHwJBrzLKN5GhcVIYibbehd4805Z/nnomwteQuuCyBHbD5HNcodj3VAoNxvNuw8QeVKin81umpKl/bx9XRumUtLcTJ92E+Ob+d1Y75r9Xd4OT3WEU6XfaLau/1oAb33Jxvcj4r1cxyEXPnx+SUF/nNZHQPPSyfpdnS5pf8Ew55mAIXt1eCZQF0LKXtS10QstBfT3RDXPmugPiy0JXtX8HJ9s7hDsfdFocQ== -
Set the encoded string as the value of the
signaturefield. Submit the request as follows:{"request": "{\"merchantId\":\"111\",\"amount\":11.5,\"merchantReference\":\"OnlineReference1649431783807\",\"callbackUrl\":{\"success\":\"https://yourDomain/online-test/success\",\"fail\":\"https://yourDomain/online-test/fail\",\"cancel\":\"https://yourDomain/online-test/cancel\",\"notify\":\"https://yourBackendApiEndpoint/online-test/notify\"},\"isRecurring\":false,\"lineItems\":[{\"quantity\":1,\"priceData\":{\"unitAmount\":1.5,\"name\":\"Test online\"}},{\"quantity\":1,\"priceData\":{\"unitAmount\":10,\"name\":\"Ten dollars\"}}]}","signature": "mRcV8hQPP60VVPtve3Zwkvxt0lLuAEwKaheuNypq6u4mXkJN1LTiJ9xoZcO1rIba8q94Lsp1yDTkpjWWz964uYKSxhSw0CqFaXVz77zTeltWa59d6GpEyHwJBrzLKN5GhcVIYibbehd4805Z/nnomwteQuuCyBHbD5HNcodj3VAoNxvNuw8QeVKin81umpKl/bx9XRumUtLcTJ92E+Ob+d1Y75r9Xd4OT3WEU6XfaLau/1oAb33Jxvcj4r1cxyEXPnx+SUF/nNZHQPPSyfpdnS5pf8Ew55mAIXt1eCZQF0LKXtS10QstBfT3RDXPmugPiy0JXtX8HJ9s7hDsfdFocQ=="}
The value of the request field must be a JSON string (with escaped quotes), not a JSON object.
Code samples
Signing a request
- Java
- PHP
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "SHA256WithRSA";
public String sign(String content, String privateKey) throws GeneralSecurityException {
final Base64.Encoder encoder = Base64.getEncoder();
final Base64.Decoder decoder = Base64.getDecoder();
byte[] keyBytes = decoder.decode(privateKey);
byte[] data = content.getBytes(StandardCharsets.UTF_8);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(data);
return encoder.encodeToString(signature.sign());
}
Apply the same header/footer/line-break removal to your private key PEM before passing it to this method.
Example usage:
String request = "{\"merchantId\":\"3000001\",\"amount\":100.2,\"isRecurring\":0,\"callbackUrl\":{\"fail\":\"https://www.bbmsl.com/fail\",\"success\":\"https://www.bbmsl.com/success\",\"cancel\":\"https://www.bbmsl.com/cancel\"},\"merchantReference\":\"Martin0331\",\"lineItems\":[{\"quantity\":1,\"priceData\":{\"unitAmount\":1.22,\"name\":\"Book\"}}]}";
String privateKey = "Your private key (remove header, footer and line breaks)";
String signature = sign(request, privateKey);
<?php
// 1. if you put your key in the code
$privateKey = "YOUR_PRIVATE_KEY";
$privateKeyPem = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($privateKey, 64, "\n", true). "\n-----END RSA PRIVATE KEY-----";
$key = openssl_get_privatekey($privateKeyPem);
// 2. if you include the .pem file
$key = openssl_pkey_get_private(file_get_contents('./key.pem'));
if (!$key) {
echo "Invalid key format".PHP_EOL;
exit;
}
echo '==========================='.PHP_EOL;
echo 'sign request'.PHP_EOL;
echo '==========================='.PHP_EOL;
openssl_sign($request_content, $encrypted, $key, OPENSSL_ALGO_SHA256);
$signature = base64_encode($encrypted);
?>