คำอธิบายทั่วไป
ส่วนนี้อธิบายถึงมาตรฐานการสื่อสารทั่วไปของ RivaaPay API รวมถึงวิธีการร้องขอ (Request Methods), พารามิเตอร์ส่วนหัว (Request Headers), อัลกอริทึมการลงลายมือชื่อ (Signature Algorithms) และตัวอย่างโค้ด
1. วิธีการร้องขอ (Request Method)
| ประเภทธุรกรรม | วิธีการ | Content-Type | หมายเหตุ |
|---|---|---|---|
| การสร้างและตรวจสอบคำสั่งซื้อ | POST | application/json; charset=utf-8 | การร้องขอจากร้านค้าไปยังแพลตฟอร์ม |
| การส่งการแจ้งเตือนแบบอะซิงโครนัส | POST | application/json; charset=utf-8 | การส่งข้อมูลการแจ้งเตือนจากแพลตฟอร์มไปยังร้านค้า |
2. พารามิเตอร์ส่วนหัว (Request Headers)
สำหรับการส่งคำขอ API ทุกครั้ง จะต้องส่งพารามิเตอร์ต่อไปนี้ใน HTTP Header เพื่อวัตถุประสงค์ในการตรวจสอบสิทธิ์:
| พารามิเตอร์ | จำเป็น | ประเภท | คำอธิบาย |
|---|---|---|---|
| merchantNo | ใช่ | string | หมายเลขอ้างอิงร้านค้า (Merchant Number) ที่จัดสรรโดยแพลตฟอร์ม |
| sign | ใช่ | string | ค่าลายมือชื่อ RSA-SHA256 (เข้ารหัส Base64) ของสตริง JSON ในส่วนข้อมูลการร้องขอ |
3. อัลกอริทึมการลงลายมือชื่อ (Signature Algorithm)
- การสร้างพารามิเตอร์: สร้างออบเจ็กต์ข้อมูลตามข้อกำหนดของแต่ละอินเทอร์เฟซ API
- การแปลงเป็น JSON: แปลงพารามิเตอร์เหล่านั้นให้อยู่ในรูปแบบสตริง JSON มาตรฐาน
- การลงลายมือชื่อและตรวจสอบ:
- การส่งคำขอจากร้านค้า: ร้านค้าลงลายมือชื่อข้อมูล JSON โดยใช้ คีย์ส่วนตัว (RSA Private Key) ของร้านค้าเอง และส่งผลลัพธ์การเข้ารหัส Base64 ใน Header
signแพลตฟอร์มจะตรวจสอบลายมือชื่อโดยใช้ คีย์สาธารณะ (RSA Public Key) ที่ร้านค้าได้ลงทะเบียนไว้ - การแจ้งเตือนผลจากแพลตฟอร์ม: แพลตฟอร์มลงลายมือชื่อข้อมูลโดยใช้คีย์ส่วนตัวของแพลตฟอร์ม และร้านค้าจะต้องตรวจสอบลายมือชื่อนี้โดยใช้ คีย์สาธารณะของแพลตฟอร์ม (Platform Public Key)
- การส่งคำขอจากร้านค้า: ร้านค้าลงลายมือชื่อข้อมูล JSON โดยใช้ คีย์ส่วนตัว (RSA Private Key) ของร้านค้าเอง และส่งผลลัพธ์การเข้ารหัส Base64 ใน Header
คีย์สาธารณะสำหรับทดสอบของแพลตฟอร์ม
IMPORTANT
ด้านล่างนี้คือคีย์สาธารณะของแพลตฟอร์มในสภาพแวดล้อมทดสอบสำหรับการตรวจสอบความถูกต้องของลายมือชื่อการเรียกกลับ (คีย์ในสภาพแวดล้อมจริงจะได้รับจากแพลตฟอร์มหลังการเชื่อมต่อระบบเสร็จสิ้น):
text
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0kr9IpgDckceWl1g8IRAMV6hALHspEb+SzIsrcc2+Q9WSot/c9YbRZzd+yuzkazMv4HAHeW7oLkG1lcxFYxgPM2x0GbhWqy1Yk5iiARS0h3E2mbuDy7neaL9DzZ411Xwq/pcoEAaklJtwwkXwlIcJGVHUFAebX6Yc6BitcfSvjZe7ilyVX0LA2aTxRGoF490gWo3R7TEXK/Lmdh/rC6FldyexdlAoc1DYbCBFZJQXxJReBbvNj+jJi1BsrsrbrKXBHd9M7/vzBwrHGDa09Y4Yw1wVPm+ZRFFs8hC3bVlZWrpOrR9o9S9kSH47YmnHDPve8fK9/ySEHp6JZ0QxJOnd6DQ0uGdAWswWlIZ4Jjg2qJxC6PHmoRYeWjyc9BuekUtDv9Yiyi9SBfGJQJStjC9PksKsMtUCGaoszPMLhMDGCX9mvYKuxK+vHDK3csWu2iRtX9TIulk/ojNsoZkSKV9tnsmiPFKb9vD79k2RiRyKYVlwpLe9Gyq/joN32i6qIyuN7h5iyms+mxya3DiGNNGdrYwaRGK+nwyJtuZJ9LI8GvWjcq5hVDeAgYnUs16N/ujCbWzHpvzDpmZxgJHXxHPk9TAFzrbTUJQ4p6TBpY87NHb2ozJcOFkFzoYEmqMhivM7vn4gqmd/r1z7PNfjNpJK2dv7pjUQ28S9FEZnsnnJecCAwEAAQ==4. ตัวอย่างโค้ดเครื่องมือลงลายมือชื่อภาษา 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);
/**
* ตรวจสอบลายมือชื่อ (Verify Signature)
*
* @param param สตริง JSON ต้นฉบับ
* @param sign ค่าลายมือชื่อแบบ Base64
* @param publicKey คีย์สาธารณะ RSA (Base64)
* @return ผลการตรวจสอบผ่านหรือไม่
*/
public static boolean checkSign(String param, String sign, String publicKey) {
try {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey))));
signature.update(param.getBytes());
return signature.verify(Base64.getDecoder().decode(sign));
} catch (Exception e) {
LOGGER.error("Sign Check Error: ", e);
}
return false;
}
/**
* สร้างลายมือชื่อ (Generate Signature)
*
* @param param สตริง JSON ที่ต้องการลงนาม
* @param privateKey คีย์ส่วนตัว RSA (Base64)
* @return ลายมือชื่อแบบ Base64 ที่ได้
*/
public static String sign(String param, String privateKey) {
try {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(KeyFactory.getInstance("RSA").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 Generate Error: ", e);
}
return null;
}
}5. ตัวอย่างการส่งคำขอภาษา Java
java
Map<String, Object> map = new HashMap<>();
map.put("timestamp", String.valueOf(System.currentTimeMillis()));
map.put("merchantOrderNo", "ORDER_123456789");
// ... เพิ่มพารามิเตอร์อื่นๆ ของคำสั่งซื้อ
String body = gson.toJson(map);
String sign = SignUtil.sign(body, merchantPrivateKey);
HttpResponse<String> stringHttpResponse = Unirest.post("https://api.xxx.com/payin/create")
.header("Content-Type", "application/json; charset=utf-8")
.header("merchantNo", "M1639466186292")
.header("sign", sign)
.body(body)
.asString();6. ตัวอย่างการสร้างคู่คีย์ RSA สำหรับร้านค้าภาษา Java
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 KeyPairGen {
public static void main(String[] args) throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096);
KeyPair keyPair = keyPairGenerator.genKeyPair();
// คีย์สาธารณะ (Public Key)
PublicKey publicKey = keyPair.getPublic();
String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKey.getEncoded());
System.out.println("----- Public Key (Provide to Platform) -----");
System.out.println(publicKeyBase64);
// คีย์ส่วนตัว (Private Key)
PrivateKey privateKey = keyPair.getPrivate();
String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKey.getEncoded());
System.out.println("----- Private Key (Keep Secret) -----");
System.out.println(privateKeyBase64);
}
}