การยืนยันตัวตน B2B
EasySlip API ใช้การยืนยันตัวตนด้วย HMAC-SHA256 signature สำหรับทั้ง endpoint ตรวจสอบสลิป/ข้อมูล และ endpoint จัดการ B2B ทุก request จะต้องลงนามด้วย secret key เพื่อรับรองความถูกต้องและความสมบูรณ์ของข้อมูล
Key 2 ประเภท
Header X-API-Key รับ key ได้ 2 รูปแบบ รูปแบบของ key จะกำหนดว่าสามารถเข้าถึง endpoint ใดได้:
| ประเภท Key | รูปแบบ | ใช้สำหรับ | ตัวอย่าง |
|---|---|---|---|
| Branch UUID | UUID v4 (36 ตัวอักษร) | /verify/bank, /verify/truewallet, /info | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| B2B Client Key | hex 64 ตัวอักษร | /b2b/* endpoint จัดการ | abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789 |
วิธีการทำงาน
- สำหรับ endpoint ตรวจสอบสลิป/ข้อมูล: ใช้ Branch UUID เป็น
X-API-Keyเซิร์ฟเวอร์จะค้นหาสาขา หา B2B client ที่เชื่อมโยงกับบริการ และใช้ secret ของ B2B client ตรวจสอบ HMAC signature คุณต้องการเพียง Branch UUID และ secret key ของบริการ - สำหรับ endpoint จัดการ (
/b2b/*): ใช้ B2B client key (hex 64 ตัวอักษร) เป็นX-API-Keyเซิร์ฟเวอร์จะค้นหา B2B client โดยตรงและตรวจสอบ HMAC signature
ทั้งสองกรณีใช้ secret key เดียวกัน (จาก B2B client) ในการลงนาม request
การรับ API Key
- เข้าสู่ระบบ EasySlip Developer Portal
- ไปที่การตั้งค่าแอปพลิเคชัน
- สร้างคู่ B2B API Key และ Secret Key
- จดบันทึก Branch UUID จากการตั้งค่าสาขา
- เก็บ Secret Key ไว้อย่างปลอดภัย — จะแสดงให้เห็นเพียงครั้งเดียว
DANGER
อย่าเปิดเผย Secret Key ในโค้ดฝั่ง client, repository สาธารณะ หรือ logs Secret Key ควรใช้ในแอปพลิเคชันฝั่ง server เท่านั้น
Headers ที่จำเป็น
ทุก API request ต้องแนบ headers เหล่านี้:
| Header | รูปแบบ | คำอธิบาย |
|---|---|---|
X-API-Key | string | Branch UUID หรือ B2B Client hex key (ดู Key 2 ประเภท) |
X-Timestamp | string | Unix timestamp เป็นวินาที |
X-Nonce | string | UUID v4 ไม่ซ้ำกันในแต่ละ request |
X-Signature | string | HMAC-SHA256 hex signature |
การคำนวณ Signature
รูปแบบ String-to-Sign
{METHOD}\n{PATH}\n{TIMESTAMP}\n{NONCE}\n{BODY_SHA256}| ส่วนประกอบ | คำอธิบาย |
|---|---|
METHOD | HTTP method ตัวพิมพ์ใหญ่ (GET, POST, PATCH, PUT, DELETE) |
PATH | เส้นทาง request รวมเครื่องหมาย / นำหน้า (เช่น /b2b/branches) |
TIMESTAMP | ค่าเดียวกับ header X-Timestamp |
NONCE | ค่าเดียวกับ header X-Nonce |
BODY_SHA256 | SHA-256 hex digest ของ request body |
Body Hash
- สำหรับ request ที่มี body (POST, PUT, PATCH): คำนวณ SHA-256 ของ raw JSON body string
- สำหรับ request ที่ไม่มี body (GET, DELETE): คำนวณ SHA-256 ของ empty string (
"")
TIP
SHA-256 ของ empty string จะเป็นค่าคงที่: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Signature
HMAC-SHA256(secretKey, stringToSign)ผลลัพธ์เป็น lowercase hex string
ค่าเผื่อ Timestamp
เซิร์ฟเวอร์ยอมรับ timestamp ภายใน ±5 นาที จากเวลาปัจจุบันของเซิร์ฟเวอร์ request ที่อยู่นอกช่วงนี้จะถูกปฏิเสธด้วย INVALID_TIMESTAMP
ความเป็นเอกลักษณ์ของ Nonce
แต่ละ nonce ต้องเป็น UUID v4 และต้องไม่ซ้ำกัน เซิร์ฟเวอร์จะติดตาม nonce ล่าสุดและจะปฏิเสธ nonce ที่ซ้ำด้วย DUPLICATE_NONCE ต้องสร้าง UUID ใหม่สำหรับทุก request
ตัวอย่างโค้ด
Endpoint ตรวจสอบสลิป/ข้อมูล (Branch UUID)
import crypto from 'crypto'
function signRequest({ method, path, body, apiKey, secretKey }) {
const timestamp = Math.floor(Date.now() / 1000).toString()
const nonce = crypto.randomUUID()
const bodyString = body ? JSON.stringify(body) : ''
const bodyHash = crypto.createHash('sha256').update(bodyString).digest('hex')
const stringToSign = `${method}\n${path}\n${timestamp}\n${nonce}\n${bodyHash}`
const signature = crypto.createHmac('sha256', secretKey).update(stringToSign).digest('hex')
return {
'X-API-Key': apiKey,
'X-Timestamp': timestamp,
'X-Nonce': nonce,
'X-Signature': signature,
...(body ? { 'Content-Type': 'application/json' } : {}),
}
}
// ตัวอย่าง: ดูข้อมูลแอปพลิเคชัน (ใช้ Branch UUID)
const headers = signRequest({
method: 'GET',
path: '/info',
body: null,
apiKey: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', // Branch UUID
secretKey: 'your_secret_key',
})
const response = await fetch('https://api.easyslip.com/v2/info', { headers })
const result = await response.json()
console.log(result.data)import hashlib
import hmac
import json
import time
import uuid
import requests
def sign_request(method, path, body, api_key, secret_key):
timestamp = str(int(time.time()))
nonce = str(uuid.uuid4())
body_string = json.dumps(body, separators=(',', ':')) if body else ''
body_hash = hashlib.sha256(body_string.encode()).hexdigest()
string_to_sign = f'{method}\n{path}\n{timestamp}\n{nonce}\n{body_hash}'
signature = hmac.new(
secret_key.encode(),
string_to_sign.encode(),
hashlib.sha256
).hexdigest()
return {
'X-API-Key': api_key,
'X-Timestamp': timestamp,
'X-Nonce': nonce,
'X-Signature': signature,
}
# ตัวอย่าง: ดูข้อมูลแอปพลิเคชัน (ใช้ Branch UUID)
headers = sign_request(
method='GET',
path='/info',
body=None,
api_key='a1b2c3d4-e5f6-7890-abcd-ef1234567890', # Branch UUID
secret_key='your_secret_key',
)
response = requests.get('https://api.easyslip.com/v2/info', headers=headers)
result = response.json()
print(result['data'])<?php
function signRequest(string $method, string $path, ?array $body, string $apiKey, string $secretKey): array
{
$timestamp = (string) time();
$nonce = sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
$bodyString = $body ? json_encode($body, JSON_UNESCAPED_UNICODE) : '';
$bodyHash = hash('sha256', $bodyString);
$stringToSign = implode("\n", [$method, $path, $timestamp, $nonce, $bodyHash]);
$signature = hash_hmac('sha256', $stringToSign, $secretKey);
return [
'X-API-Key' => $apiKey,
'X-Timestamp' => $timestamp,
'X-Nonce' => $nonce,
'X-Signature' => $signature,
];
}
// ตัวอย่าง: ดูข้อมูลแอปพลิเคชัน (ใช้ Branch UUID)
$headers = signRequest('GET', '/info', null, 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', 'your_secret_key');
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.easyslip.com/v2/info',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array_map(
fn($k, $v) => "$k: $v",
array_keys($headers),
array_values($headers)
),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);#!/bin/bash
# Branch UUID สำหรับ endpoint ตรวจสอบสลิป/ข้อมูล
API_KEY="a1b2c3d4-e5f6-7890-abcd-ef1234567890"
SECRET_KEY="your_secret_key"
METHOD="GET"
PATH_URL="/info"
TIMESTAMP=$(date +%s)
NONCE=$(uuidgen | tr '[:upper:]' '[:lower:]')
# สำหรับ GET/DELETE request ให้ hash empty string
BODY_HASH=$(printf '' | shasum -a 256 | cut -d' ' -f1)
STRING_TO_SIGN="${METHOD}\n${PATH_URL}\n${TIMESTAMP}\n${NONCE}\n${BODY_HASH}"
SIGNATURE=$(printf "${STRING_TO_SIGN}" | openssl dgst -sha256 -hmac "${SECRET_KEY}" | cut -d' ' -f2)
curl -X GET "https://api.easyslip.com/v2${PATH_URL}" \
-H "X-API-Key: ${API_KEY}" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-H "X-Signature: ${SIGNATURE}"Endpoint จัดการ (B2B Client Key)
// ตัวอย่าง: ดูรายการสาขา (ใช้ B2B client key hex 64 ตัวอักษร)
const headers = signRequest({
method: 'GET',
path: '/b2b/branches',
body: null,
apiKey: 'abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789', // B2B Client key
secretKey: 'your_secret_key',
})
const response = await fetch('https://api.easyslip.com/b2b/branches', { headers })
const result = await response.json()
console.log(result.data)# ตัวอย่าง: ดูรายการสาขา (ใช้ B2B client key hex 64 ตัวอักษร)
headers = sign_request(
method='GET',
path='/b2b/branches',
body=None,
api_key='abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789', # B2B Client key
secret_key='your_secret_key',
)
response = requests.get('https://api.easyslip.com/b2b/branches', headers=headers)
result = response.json()
print(result['data'])// ตัวอย่าง: ดูรายการสาขา (ใช้ B2B client key hex 64 ตัวอักษร)
$headers = signRequest(
'GET',
'/b2b/branches',
null,
'abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789', // B2B Client key
'your_secret_key'
);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.easyslip.com/b2b/branches',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array_map(
fn($k, $v) => "$k: $v",
array_keys($headers),
array_values($headers)
),
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result['data']);#!/bin/bash
# B2B Client key hex 64 ตัวอักษร สำหรับ endpoint จัดการ
API_KEY="abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
SECRET_KEY="your_secret_key"
METHOD="GET"
PATH_URL="/b2b/branches"
TIMESTAMP=$(date +%s)
NONCE=$(uuidgen | tr '[:upper:]' '[:lower:]')
# สำหรับ GET/DELETE request ให้ hash empty string
BODY_HASH=$(printf '' | shasum -a 256 | cut -d' ' -f1)
STRING_TO_SIGN="${METHOD}\n${PATH_URL}\n${TIMESTAMP}\n${NONCE}\n${BODY_HASH}"
SIGNATURE=$(printf "${STRING_TO_SIGN}" | openssl dgst -sha256 -hmac "${SECRET_KEY}" | cut -d' ' -f2)
curl -X GET "https://api.easyslip.com${PATH_URL}" \
-H "X-API-Key: ${API_KEY}" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-H "X-Signature: ${SIGNATURE}"สิทธิ์การใช้งาน (Permissions)
แต่ละ B2B API key จะมีชุดสิทธิ์ที่กำหนดว่าสามารถทำอะไรได้บ้าง:
| Permission | คำอธิบาย |
|---|---|
branch:read | ดูรายการและข้อมูลสาขา |
branch:write | สร้าง แก้ไข และลบสาขา |
quota:read | ดูข้อมูลโควตา |
quota:write | กำหนด ปรับ และรีเซ็ตโควตา |
bank-account:read | ดูบัญชีธนาคารที่เชื่อมต่อกับสาขา |
bank-account:write | สร้าง เชื่อมต่อ และยกเลิกการเชื่อมต่อบัญชีธนาคาร |
WARNING
หาก API key ของคุณไม่มีสิทธิ์ที่จำเป็นสำหรับ endpoint นั้น request จะถูกปฏิเสธด้วย 403 Forbidden