ইন্টিগ্রেশন নির্দেশিকা ও প্রযুক্তিগত বিবরণ (Integration Guide)
এই নথিতে বাংলাদেশ পেমেন্ট গেটওয়েতে মার্চেন্ট ইন্টিগ্রেশনের সাধারণ নিয়মাবলী, HTTP হেডার স্ট্যান্ডার্ড, RSA ডিজিটাল স্বাক্ষর অ্যালগরিদম এবং কী (Key) তৈরির নিয়মাবলী বর্ণনা করা হয়েছে।
১. সাধারণ রিকোয়েস্ট স্পেসিফিকেশন
| যোগাযোগের ধরন | HTTP মেথড | Content-Type হেডার | পেলোড ফরম্যাট |
|---|---|---|---|
| API রিকোয়েস্ট (অর্ডার তৈরি, অনুসন্ধান, ব্যালেন্স ইত্যাদি) | POST | application/json; charset=utf-8 | JSON |
| কলব্যাক নোটিফিকেশন (প্ল্যাটফর্ম থেকে মার্চেন্ট সিস্টেমে পুশ) | POST | application/json; charset=utf-8 | JSON |
২. সাধারণ রিকোয়েস্ট হেডার (HTTP Headers)
প্ল্যাটফর্মে পাঠানো সমস্ত API রিকোয়েস্ট এবং প্ল্যাটফর্ম কর্তৃক প্রেরিত কলব্যাক নোটিফিকেশনে নিম্নলিখিত হেডার থাকা বাধ্যতামূলক:
| হেডার প্যারামিটার | বাধ্যতামূলক | ধরন (Type) | বিবরণ |
|---|---|---|---|
merchantNo | হ্যাঁ (Yes) | String | প্ল্যাটফর্ম কর্তৃক প্রদত্ত মার্চেন্ট নম্বর |
sign | হ্যাঁ (Yes) | String | রিকোয়েস্ট বডির Base64 এনকোডেড RSA ডিজিটাল স্বাক্ষর |
৩. RSA ডিজিটাল স্বাক্ষর এবং যাচাইকরণ অ্যালগরিদম
১. স্বাক্ষর তৈরি প্রক্রিয়া (মার্চেন্ট $\to$ প্ল্যাটফর্ম)
১. নির্দিষ্ট এপিআই স্পেসিফিকেশন অনুযায়ী রিকোয়েস্ট প্যারামিটার তৈরি করুন;
২. প্যারামিটারগুলোকে একটি প্রমিত JSON স্ট্রিং-এ রূপান্তর করুন (রিকোয়েস্ট বডি হিসেবে ব্যবহৃত হবে);
৩. মার্চেন্টের নিজস্ব প্রাইভেট কি (Private Key) ব্যবহার করে SHA256withRSA অ্যালগরিদমের মাধ্যমে উক্ত JSON স্ট্রিং স্বাক্ষর করুন;
৪. স্বাক্ষরিত বাইট অ্যারে-টিকে Base64-এ রূপান্তর করে HTTP হেডার sign-এ যুক্ত করুন;
৫. মার্চেন্ট নম্বরটি HTTP হেডার merchantNo-তে যুক্ত করে HTTP POST রিকোয়েস্ট প্রেরণ করুন।
২. স্বাক্ষর যাচাইকরণ প্রক্রিয়া (প্ল্যাটফর্ম $\to$ মার্চেন্ট কলব্যাক)
১. মার্চেন্টের রিকোয়েস্ট প্ল্যাটফর্ম কর্তৃক যাচাই: মার্চেন্টের নিবন্ধিত পাবলিক কি ব্যবহার করে প্ল্যাটফর্ম রিকোয়েস্ট বডি ও sign যাচাই করে;
২. প্ল্যাটফর্মের কলব্যাক মার্চেন্ট কর্তৃক যাচাই: প্ল্যাটফর্ম থেকে পাঠানো অ্যাসিনক্রোনাস কলব্যাক গ্রহণের পর মার্চেন্ট সিস্টেমকে অবশ্যই প্ল্যাটফর্মের পাবলিক কি (Public Key) ব্যবহার করে sign যাচাই করতে হবে (দ্রষ্টব্য: যাচাইয়ের সময় অক্ষরের বড়/ছোট হাতের পার্থক্য বা কেস সংবেদনশীলতা উপেক্ষা করুন)।
৪. প্ল্যাটফর্মের পাবলিক কি (Public Key)
টেস্ট চ্যানেল পাবলিক কি (Sandbox)
NOTE
টেস্ট চ্যানেল ইন্টিগ্রেশন সম্পন্ন হওয়ার পর অফিশিয়াল প্রোডাকশন পাবলিক কি প্ল্যাটফর্মের টেকনিক্যাল টিম প্রদান করবে।
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0kr9IpgDckceWl1g8IRAMV6hALHspEb+SzIsrcc2+Q9WSot/c9YbRZzd+yuzkazMv4HAHeW7oLkG1lcxFYxgPM2x0GbhWqy1Yk5iiARS0h3E2mbuDy7neaL9DzZ411Xwq/pcoEAaklJtwwkXwlIcJGVHUFAebX6Yc6BitcfSvjZe7ilyVX0LA2aTxRGoF490gWo3R7TEXK/Lmdh/rC6FldyexdlAoc1DYbCBFZJQXxJReBbvNj+jJi1BsrsrbrKXBHd9M7/vzBwrHGDa09Y4Yw1wVPm+ZRFFs8hC3bVlZWrpOrR9o9S9kSH47YmnHDPve8fK9/ySEHp6JZ0QxJOnd6DQ0uGdAWswWlIZ4Jjg2qJxC6PHmoRYeWjyc9BuekUtDv9Yiyi9SBfGJQJStjC9PksKsMtUCGaoszPMLhMDGCX9mvYKuxK+vHDK3csWu2iRtX9TIulk/ojNsoZkSKV9tnsmiPFKb9vD79k2RiRyKYVlwpLe9Gyq/joN32i6qIyuN7h5iyms+mxya3DiGNNGdrYwaRGK+nwyJtuZJ9LI8GvWjcq5hVDeAgYnUs16N/ujCbWzHpvzDpmZxgJHXxHPk9TAFzrbTUJQ4p6TBpY87NHb2ozJcOFkFzoYEmqMhivM7vn4gqmd/r1z7PNfjNpJK2dv7pjUQ28S9FEZnsnnJecCAwEAAQ==৫. জাভা কোড উদাহরণ (Java Code Examples)
১. সাইন ইউটিলিটি ক্লাস (SignUtil.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);
/**
* ডিজিটাল স্বাক্ষর যাচাইকরণ মেথড
* @param param JSON বডি স্ট্রিং
* @param sign HTTP হেডারের Base64 সাইন
* @param publicKey Base64 পাবলিক কি
* @return স্বাক্ষর সঠিক হলে true, অন্যথায় false
*/
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("Sign যাচাইকরণে ত্রুটি: ", e);
}
return false;
}
/**
* ডিজিটাল স্বাক্ষর তৈরির মেথড
* @param param স্বাক্ষরের জন্য JSON বডি
* @param privateKey Base64 প্রাইভেট কি
* @return Base64 সাইন স্ট্রিং
*/
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("Sign তৈরিতে ত্রুটি: ", e);
}
return null;
}
}২. রিকোয়েস্ট পাঠানোর উদাহরণ
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 স্ট্যাটাস: " + response.getStatus());
System.out.println("রেসপন্স বডি: " + response.getBody());
}
}৩. RSA কী-পেয়ার (KeyPair) তৈরির উদাহরণ
ইন্টিগ্রেশন শুরু করার পূর্বে মার্চেন্টকে অবশ্যই একটি RSA-4096 (বা RSA-2048) কী জোড়া তৈরি করতে হবে এবং পাবলিক কি-টি প্ল্যাটফর্মে জমা দিতে হবে:
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("--- মার্চেন্ট পাবলিক কি (প্ল্যাটফর্মে জমা দিন) ---");
System.out.println(publicKeyBase64);
PrivateKey privateKey = keyPair.getPrivate();
String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKey.getEncoded());
System.out.println("--- মার্চেন্ট প্রাইভেট কি (গোপনে নিরাপদে রাখুন) ---");
System.out.println(privateKeyBase64);
}
}