คำอธิบายทั่วไป
ส่วนนี้อธิบายถึงมาตรฐานการสื่อสารทั่วไปของ 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
ด้านล่างนี้คือคีย์สาธารณะของแพลตฟอร์มในสภาพแวดล้อมทดสอบสำหรับการตรวจสอบความถูกต้องของลายมือชื่อการเรียกกลับ (คีย์ในสภาพแวดล้อมจริงสามารถดูได้ที่ระบบหลังบ้านของร้านค้า - ข้อมูลบัญชี):
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0kr9IpgDckceWl1g8IRAMV6hALHspEb+SzIsrcc2+Q9WSot/c9YbRZzd+yuzkazMv4HAHeW7oLkG1lcxFYxgPM2x0GbhWqy1Yk5iiARS0h3E2mbuDy7neaL9DzZ411Xwq/pcoEAaklJtwwkXwlIcJGVHUFAebX6Yc6BitcfSvjZe7ilyVX0LA2aTxRGoF490gWo3R7TEXK/Lmdh/rC6FldyexdlAoc1DYbCBFZJQXxJReBbvNj+jJi1BsrsrbrKXBHd9M7/vzBwrHGDa09Y4Yw1wVPm+ZRFFs8hC3bVlZWrpOrR9o9S9kSH47YmnHDPve8fK9/ySEHp6JZ0QxJOnd6DQ0uGdAWswWlIZ4Jjg2qJxC6PHmoRYeWjyc9BuekUtDv9Yiyi9SBfGJQJStjC9PksKsMtUCGaoszPMLhMDGCX9mvYKuxK+vHDK3csWu2iRtX9TIulk/ojNsoZkSKV9tnsmiPFKb9vD79k2RiRyKYVlwpLe9Gyq/joN32i6qIyuN7h5iyms+mxya3DiGNNGdrYwaRGK+nwyJtuZJ9LI8GvWjcq5hVDeAgYnUs16N/ujCbWzHpvzDpmZxgJHXxHPk9TAFzrbTUJQ4p6TBpY87NHb2ozJcOFkFzoYEmqMhivM7vn4gqmd/r1z7PNfjNpJK2dv7pjUQ28S9FEZnsnnJecCAwEAAQ==4. ตัวอย่างโค้ดเครื่องมือลงลายมือชื่อภาษา 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
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
6.1 เครื่องมือสร้างคีย์ออนไลน์
a. ลิงก์เครื่องมือสร้างคีย์สาธารณะและคีย์ส่วนตัว (เลือก 1024 บิต, 2048 บิต, 4096 บิต / รูปแบบ PKCS#8): https://www.bejson.com/enc/rsa/#18
b. ใช้ลิงก์นี้เพื่อลบการขึ้นบรรทัดใหม่ก่อนอัปโหลด: http://www.wuqianling.top/software/notepad/compress.html
ใช้เครื่องมือสร้างคีย์เพื่อสร้างคู่คีย์ ความยาวต้องเป็น 1024 บิต, 2048 บิต หรือ 4096 บิต และรูปแบบต้องเป็น PKCS#8
คัดลอกคีย์สาธารณะจากคู่คีย์ที่สร้างขึ้นหลังจากลบการขึ้นบรรทัดใหม่ และอัปโหลดไปยังระบบหลังบ้านของร้านค้า ห้ามใส่ -----BEGIN *** KEY----- และ -----END *** KEY-----
หลังจากอัปโหลดคีย์สาธารณะเรียบร้อยแล้ว โปรดเก็บรักษาคีย์ส่วนตัวของคุณให้ปลอดภัย
หากมีปัญหาเกี่ยวกับการเชื่อมต่อหรือการเข้ารหัส คุณสามารถส่งพารามิเตอร์การร้องขอไปที่กลุ่มและแท็กฝ่ายบริการลูกค้าหรือเจ้าหน้าที่ฝ่ายเทคนิคของเรา
สำหรับลายเซ็นการเรียกกลับ (callback signature) โปรดใช้คีย์สาธารณะของแพลตฟอร์มในการถอดรหัสและตรวจสอบ ห้ามใช้คีย์สาธารณะของร้านค้า (คีย์สาธารณะที่คุณสร้างขึ้นเอง)
6.2 ตัวอย่างโค้ด 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);
}
}