Skip to content

การยืนยันตัวตน B2B

EasySlip API ใช้การยืนยันตัวตนด้วย HMAC-SHA256 signature สำหรับทั้ง endpoint ตรวจสอบสลิป/ข้อมูล และ endpoint จัดการ B2B ทุก request จะต้องลงนามด้วย secret key เพื่อรับรองความถูกต้องและความสมบูรณ์ของข้อมูล

Key 2 ประเภท

Header X-API-Key รับ key ได้ 2 รูปแบบ รูปแบบของ key จะกำหนดว่าสามารถเข้าถึง endpoint ใดได้:

ประเภท Keyรูปแบบใช้สำหรับตัวอย่าง
Branch UUIDUUID v4 (36 ตัวอักษร)/verify/bank, /verify/truewallet, /infoa1b2c3d4-e5f6-7890-abcd-ef1234567890
B2B Client Keyhex 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

  1. เข้าสู่ระบบ EasySlip Developer Portal
  2. ไปที่การตั้งค่าแอปพลิเคชัน
  3. สร้างคู่ B2B API Key และ Secret Key
  4. จดบันทึก Branch UUID จากการตั้งค่าสาขา
  5. เก็บ Secret Key ไว้อย่างปลอดภัย — จะแสดงให้เห็นเพียงครั้งเดียว

DANGER

อย่าเปิดเผย Secret Key ในโค้ดฝั่ง client, repository สาธารณะ หรือ logs Secret Key ควรใช้ในแอปพลิเคชันฝั่ง server เท่านั้น

Headers ที่จำเป็น

ทุก API request ต้องแนบ headers เหล่านี้:

Headerรูปแบบคำอธิบาย
X-API-KeystringBranch UUID หรือ B2B Client hex key (ดู Key 2 ประเภท)
X-TimestampstringUnix timestamp เป็นวินาที
X-NoncestringUUID v4 ไม่ซ้ำกันในแต่ละ request
X-SignaturestringHMAC-SHA256 hex signature

การคำนวณ Signature

รูปแบบ String-to-Sign

{METHOD}\n{PATH}\n{TIMESTAMP}\n{NONCE}\n{BODY_SHA256}
ส่วนประกอบคำอธิบาย
METHODHTTP method ตัวพิมพ์ใหญ่ (GET, POST, PATCH, PUT, DELETE)
PATHเส้นทาง request รวมเครื่องหมาย / นำหน้า (เช่น /b2b/branches)
TIMESTAMPค่าเดียวกับ header X-Timestamp
NONCEค่าเดียวกับ header X-Nonce
BODY_SHA256SHA-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)

javascript
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)
python
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
<?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']);
bash
#!/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)

javascript
// ตัวอย่าง: ดูรายการสาขา (ใช้ 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)
python
# ตัวอย่าง: ดูรายการสาขา (ใช้ 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'])
php
// ตัวอย่าง: ดูรายการสาขา (ใช้ 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']);
bash
#!/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

Bank Slip Verification API for Thai Banking