Integration Guide & Specifications
This document outlines the general standards, HTTP headers, RSA signature algorithms, and key generation instructions for merchants integrating with the Bangladesh Payment Gateway.
1. General Request Standards
| Interaction Type | HTTP Method | Content-Type | Payload Format |
|---|---|---|---|
| API Requests (Order creation, queries, balance, etc.) | POST | application/json; charset=utf-8 | JSON |
| Webhook Callbacks (Pushed from platform to merchant) | POST | application/json; charset=utf-8 | JSON |
2. Common HTTP Headers
All HTTP POST requests sent to the platform, as well as asynchronous webhook notifications sent by the platform, must include the following headers:
| Header Key | Required | Type | Description |
|---|---|---|---|
merchantNo | Yes | String | Merchant ID issued by the platform |
sign | Yes | String | Base64-encoded RSA digital signature of the request body |
3. RSA Signature & Verification Algorithm
1. Signature Process (Merchant $\to$ Platform)
- Construct the request parameter map/object according to the specific API specification;
- Serialize the parameters into a standard JSON string (used as the HTTP Request Body);
- Sign the JSON string using the Merchant's Private Key with the
SHA256withRSAalgorithm; - Convert the signature byte array into a Base64-encoded string and place it in the HTTP Header
sign; - Put the merchant ID in the HTTP Header
merchantNoand execute the HTTP POST request.
2. Verification Process (Platform $\to$ Merchant Callback)
- Platform Verifies Merchant Requests: The platform uses the merchant's configured public key to verify
signagainst the raw request body; - Merchant Verifies Platform Callbacks: When receiving asynchronous notifications from the platform, the merchant must verify the
signheader using the Platform Public Key (Note: Verification should ignore case differences).
4. Platform Public Key
Sandbox / Test Channel Public Key
NOTE
The Production environment public key will be officially issued by the platform technical team after sandbox testing is completed.
text
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0kr9IpgDckceWl1g8IRAMV6hALHspEb+SzIsrcc2+Q9WSot/c9YbRZzd+yuzkazMv4HAHeW7oLkG1lcxFYxgPM2x0GbhWqy1Yk5iiARS0h3E2mbuDy7neaL9DzZ411Xwq/pcoEAaklJtwwkXwlIcJGVHUFAebX6Yc6BitcfSvjZe7ilyVX0LA2aTxRGoF490gWo3R7TEXK/Lmdh/rC6FldyexdlAoc1DYbCBFZJQXxJReBbvNj+jJi1BsrsrbrKXBHd9M7/vzBwrHGDa09Y4Yw1wVPm+ZRFFs8hC3bVlZWrpOrR9o9S9kSH47YmnHDPve8fK9/ySEHp6JZ0QxJOnd6DQ0uGdAWswWlIZ4Jjg2qJxC6PHmoRYeWjyc9BuekUtDv9Yiyi9SBfGJQJStjC9PksKsMtUCGaoszPMLhMDGCX9mvYKuxK+vHDK3csWu2iRtX9TIulk/ojNsoZkSKV9tnsmiPFKb9vD79k2RiRyKYVlwpLe9Gyq/joN32i6qIyuN7h5iyms+mxya3DiGNNGdrYwaRGK+nwyJtuZJ9LI8GvWjcq5hVDeAgYnUs16N/ujCbWzHpvzDpmZxgJHXxHPk9TAFzrbTUJQ4p6TBpY87NHb2ozJcOFkFzoYEmqMhivM7vn4gqmd/r1z7PNfjNpJK2dv7pjUQ28S9FEZnsnnJecCAwEAAQ==5. Java Code Examples
1. Signature & Verification Utility (SignUtil.java)
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class SignUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(SignUtil.class);
/**
* Verifies the signature of the payload
* @param param The JSON payload string
* @param sign Base64 encoded signature string from HTTP header
* @param publicKey Base64 encoded public key
* @return true if valid, false otherwise
*/
public static boolean checkSign(String param, String sign, String publicKey) {
try {
Signature signature = Signature.getInstance("SHA256withRSA");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
signature.initVerify(keyFactory.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey))));
signature.update(param.getBytes());
return signature.verify(Base64.getDecoder().decode(sign));
} catch (Exception e) {
LOGGER.error("Signature verification error: ", e);
}
return false;
}
/**
* Generates a digital signature for the payload
* @param param The JSON payload string to sign
* @param privateKey Base64 encoded private key
* @return Base64 encoded signature string
*/
public static String sign(String param, String privateKey) {
try {
Signature signature = Signature.getInstance("SHA256withRSA");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
signature.initSign(keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey))));
signature.update(param.getBytes());
byte[] bytes = signature.sign();
return Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
LOGGER.error("Signature generation error: ", e);
}
return null;
}
}2. Request Demo
java
import com.google.gson.Gson;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
import java.util.HashMap;
import java.util.Map;
public class RequestDemo {
public static void main(String[] args) {
String url = "https://api.example.com/payin/create";
String merchantNo = "M1639466186292";
String privateKey = "YOUR_PRIVATE_KEY_BASE64";
Map<String, Object> map = new HashMap<>();
map.put("timestamp", System.currentTimeMillis());
map.put("merchantOrderNo", "ORDER_" + System.currentTimeMillis());
map.put("amount", "200.00");
map.put("payType", "BKASH");
map.put("notifyUrl", "https://yourdomain.com/payin/notify");
Gson gson = new Gson();
String body = gson.toJson(map);
String sign = SignUtil.sign(body, privateKey);
HttpResponse<String> response = Unirest.post(url)
.header("Content-Type", "application/json; charset=utf-8")
.header("merchantNo", merchantNo)
.header("sign", sign)
.body(body)
.asString();
System.out.println("HTTP Status: " + response.getStatus());
System.out.println("Response Body: " + response.getBody());
}
}3. RSA KeyPair Generation Demo
Merchants must generate an RSA-4096 (or RSA-2048) key pair before integration. Provide the generated public key to the platform operations team:
java
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
public class KeyPairGenDemo {
public static void main(String[] args) throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096);
KeyPair keyPair = keyPairGenerator.genKeyPair();
PublicKey publicKey = keyPair.getPublic();
String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKey.getEncoded());
System.out.println("--- Merchant Public Key (Provide to Platform) ---");
System.out.println(publicKeyBase64);
PrivateKey privateKey = keyPair.getPrivate();
String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKey.getEncoded());
System.out.println("--- Merchant Private Key (Keep strictly confidential) ---");
System.out.println(privateKeyBase64);
}
}