Skip to main content

Connect to PayAPI

BBMSL Online Payment Service provides various APIs, which are named PayAPI for processing payment requests from the merchant. The APIs allow sensitive payment data to be exchanged between the merchant's backend and BBMSL accurately and securely.

While there are number of APIs available under different integration models, they are all standardized with the following characteristics,

Identification

Every onboarded merchant will be assigned to a merchant account with a unique merchant ID. The merchant is required to provide the merchant ID in every PayAPI request.

Connection Security

All APIs are protected by Transport Layer Security (TLS) protocol and whitelisting strategy. The request can only function properly over HTTPS connection, HTTP connection should not work.

Authentication and Message Security

Each message request to PayAPI is signed by the RSA key pair for verification. BBMSL authenticates the integrity of the merchant request by its digital signature. The signing details are included in the next section.

Signing PayAPI request

Each PayAPI request should include a signature signed by the merchant. Before performing any API request, the merchant needs to generate its own RSA key pairs (public and private key) and share the public key with BBMSL. The merchant should use the private key to sign the request message, and BBMSL will verify the signature with the shared public key.

Signature is not an independent API. It is a cryptographic measure to ensure integrity and non-repudiation.

About the signing
  • Signing algorithm: 2048 bits RSA
  • Hashing algorithm: SHA256

Key Generation using OpenSSL

You are not limited to use OpenSSL, you can use any tools to generate the key pair.

  1. Generate a new RSA keys pair
$ openssl genrsa -out rsa_private_key.pem 2048
  1. Export public key
$ openssl rsa -in rsa_private_key.pem -pubout -out  rsa_public_key.pem

Exchange Public Key

After the RSA key pair is generated, you must exchange the public key with the BBMSL for signature verification by completing the following steps:

  1. Remove the public key header, footer and all line break \n from the following key string.
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxm/VrrMFmczDa+l+21Uc
wYU+wDdL074DnIRsaLCVqcVRPMPrQiq1og3N1Li9rneMWALHAhXKyH101BNOGYW2
uiZgWLPkz6dcYgd1WiCKsOcks7E8Kn9jH0PB+1issv9qk8aLHysiscIajWU69pho
GhGcsJu9uk2GdW0zo6I+9vBSE2l8wfG0Sy3sVZeYzm/nmCC9UgI1oWMCLrO3Y43l
896dItR9z8SAo3Ao77gz6UmJs32zHRM6UA5lv+ssYAZiS8OkVLCTx/DVcKyNvFAK
aoBDYvy1wOX+2o62cANrj0J7ybQ9M1VurQuEVeOuKFjT8GCO9DcvCcUaj3WxNlf3
/QIDAQAB
-----END PUBLIC KEY-----
  1. Upload the processed key string below to BBMSL Merchant Portal and activate the key.
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxm/VrrMFmczDa+l+21UcwYU+wDdL074DnIRsaLCVqcVRPMPrQiq1og3N1Li9rneMWALHAhXKyH101BNOGYW2uiZgWLPkz6dcYgd1WiCKsOcks7E8Kn9jH0PB+1issv9qk8aLHysiscIajWU69phoGhGcsJu9uk2GdW0zo6I+9vBSE2l8wfG0Sy3sVZeYzm/nmCC9UgI1oWMCLrO3Y43l896dItR9z8SAo3Ao77gz6UmJs32zHRM6UA5lv+ssYAZiS8OkVLCTx/DVcKyNvFAKaoBDYvy1wOX+2o62cANrj0J7ybQ9M1VurQuEVeOuKFjT8GCO9DcvCcUaj3WxNlf3/QIDAQAB
  1. Obtain BBMSL public key. Use the BBMSL public key to verify the notification signature. See Verify notification signature.
note

Please contact your relationship manager for the public key

Signing the Request

Prepare the request parameters in JSON format, and perform the following steps to sign the message,

  1. Prepare the content to be signed like the following,
{
  "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"
      }
    }
  ]
}
  1. Hash the JSON content by using SHA256withRSA algorithm. Then use the merchant's RSA private key to sign it as the signature. The length of the RSA key must be 2048 bits.

  2. Base64 encode the signature, a sample result is shown below,

mRcV8hQPP60VVPtve3Zwkvxt0lLuAEwKaheuNypq6u4mXkJN1LTiJ9xoZcO1rIba8q94Lsp1yDTkpjWWz964uYKSxhSw0CqFaXVz77zTeltWa59d6GpEyHwJBrzLKN5GhcVIYibbehd4805Z/nnomwteQuuCyBHbD5HNcodj3VAoNxvNuw8QeVKin81umpKl/bx9XRumUtLcTJ92E+Ob+d1Y75r9Xd4OT3WEU6XfaLau/1oAb33Jxvcj4r1cxyEXPnx+SUF/nNZHQPPSyfpdnS5pf8Ew55mAIXt1eCZQF0LKXtS10QstBfT3RDXPmugPiy0JXtX8HJ9s7hDsfdFocQ==
  1. Use the obtained string as the value of the signature parameter. The following sample shows a whole API request,
{
  "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=="
}
signing the request

The value of request key must be in JSON string with backslash \ instead of JSON object.

Example Code

Code Snippet for signing

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

To use above Java code, you need to perform same public key manual edit on the private key PEM file.

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