คู่มือการยืนยันตัวตน API
คู่มือการยืนยันตัวตน
ReceiptRoller API ใช้ OAuth 2.0 authorization code flow เมื่อนักพัฒนาฝั่งบุคคลที่สามลงทะเบียนแอป และเจ้าของธุรกิจอนุญาตการเข้าถึง นักพัฒนาจะสามารถรับโทเคนและเรียก API ได้
ขั้นตอนที่ 1: ลงทะเบียนแอป
- ล็อกอินเข้าบัญชี ReceiptRoller
- ไปที่ รายละเอียดบัญชีธุรกิจ → เมนู ⋮ → แอปนักพัฒนา
- คลิก สร้างแอป
- กรอกชื่อแอป, Redirect URI และเลือกสโคป API ที่จำเป็น
- เมื่อสร้างเสร็จ ระบบจะออก
client_idและclient_secret
client_secret จะแสดงเพียงครั้งเดียวเท่านั้น โปรดคัดลอกและเก็บไว้อย่างปลอดภัยเสมอ หากทำสูญหายต้องสร้างใหม่ (ซีเคร็ตเดิมจะใช้ไม่ได้ทันที)ขั้นตอนที่ 2: รีไดเรกต์เจ้าของธุรกิจไปยังหน้าให้สิทธิ์
เมื่อเจ้าของธุรกิจเชื่อมบัญชีเข้ากับแอป ให้รีไดเรกต์เบราว์เซอร์ไปยัง URL ต่อไปนี้:
GET https://your-domain/oauth/authorize
?client_id=YOUR_CLIENT_ID
&redirect_uri=YOUR_REDIRECT_URI
&response_type=code
&scope=store.products.read store.orders.read
&state=RANDOM_STATE_STRING
| พารามิเตอร์ | จำเป็น | คำอธิบาย |
|---|---|---|
client_id |
ใช่ | Client ID ของแอป |
redirect_uri |
ใช่ | ต้องตรงกับ Redirect URI ที่ลงทะเบียนไว้ในแอปทุกตัวอักษร |
response_type |
ใช่ | ระบุ code |
scope |
ใช่ | รายการสโคปที่คั่นด้วยช่องว่าง (ดูสโคปที่ใช้ได้ด้านล่าง) |
state |
แนะนำ | สตริงสุ่มเพื่อป้องกันการโจมตี CSRF จะถูกส่งกลับมาตามเดิมตอน callback |
code_challenge |
ไม่บังคับ | PKCE code challenge (base64url-encode ของ SHA-256 hash ของ code_verifier) |
code_challenge_method |
ไม่บังคับ | S256 (จำเป็นเมื่อใช้ PKCE) |
เจ้าของธุรกิจจะเห็นหน้ายินยอมที่แสดงชื่อแอปและสิทธิ์การเข้าถึงที่ร้องขอ สามารถเลือกอนุญาตหรือปฏิเสธได้
ขั้นตอนที่ 3: รับ authorization code
หากได้รับอนุญาต เบราว์เซอร์ของเจ้าของธุรกิจจะถูกรีไดเรกต์ไปยัง redirect_uri:
GET https://your-app.com/callback
?code=AUTHORIZATION_CODE
&state=RANDOM_STATE_STRING
กรณีถูกปฏิเสธ:
GET https://your-app.com/callback
?error=access_denied
&state=RANDOM_STATE_STRING
ขั้นตอนที่ 4: แลกโค้ดเป็นโทเคน
จากฝั่งเซิร์ฟเวอร์ (ไม่ใช่จากเบราว์เซอร์) ให้แลกโค้ดเป็นแอ็กเซสโทเคนด้วยคำขอ POST ต่อไปนี้:
POST /api/v1/auth/token
Content-Type: application/json
{
"grantType": "authorization_code",
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_CLIENT_SECRET",
"code": "AUTHORIZATION_CODE",
"redirectUri": "YOUR_REDIRECT_URI"
}
การตอบกลับสำเร็จ (200):
{
"accessToken": "aBcDeFgH1234567890...",
"refreshToken": "xYzAbCdEfG098765...",
"tokenType": "Bearer",
"expiresIn": 3600,
"scope": "store.products.read store.orders.read"
}
| ฟิลด์ | คำอธิบาย |
|---|---|
accessToken |
ใช้เมื่อเรียก API มีอายุ 1 ชั่วโมง |
refreshToken |
ใช้เพื่อรับโทเคนใหม่เมื่อแอ็กเซสโทเคนหมดอายุ มีอายุ 30 วัน |
expiresIn |
อายุของโทเคน (วินาที) 3600 = 1 ชั่วโมง |
scope |
สโคปที่เจ้าของธุรกิจอนุมัติ |
ขั้นตอนที่ 5: เรียก API
ใส่แอ็กเซสโทเคนในเฮดเดอร์ Authorization แล้วส่งคำขอ:
GET /api/v1/store/products
Authorization: Bearer aBcDeFgH1234567890...
Content-Type: application/json
API จะคืนข้อมูลที่ผูกกับบัญชีธุรกิจที่อนุมัติแอป เข้าถึงได้เฉพาะข้อมูลที่อนุญาตด้วยสโคปที่อนุมัติแล้วเท่านั้น
ขั้นตอนที่ 6: รีเฟรชโทเคนที่หมดอายุ
เมื่อแอ็กเซสโทเคนหมดอายุ ให้ใช้รีเฟรชโทเคนเพื่อรับคู่โทเคนใหม่:
POST /api/v1/auth/token
Content-Type: application/json
{
"grantType": "refresh_token",
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_CLIENT_SECRET",
"refreshToken": "xYzAbCdEfG098765..."
}
รูปแบบการตอบกลับเหมือนขั้นตอนที่ 4 แอ็กเซสโทเคนและรีเฟรชโทเคนเดิมจะถูกยกเลิก และมีการคืนคู่ใหม่มาให้
การเพิกถอนโทเคน
หากต้องการเพิกถอนแอ็กเซสโทเคนหรือรีเฟรชโทเคน:
POST /api/v1/auth/revoke
Content-Type: application/json
{
"token": "โทเคนที่ต้องการเพิกถอน",
"clientId": "YOUR_CLIENT_ID"
}
เจ้าของธุรกิจสามารถเพิกถอนการเข้าถึงของแอปได้ทุกเมื่อจากการตั้งค่าบัญชี
การตอบกลับข้อผิดพลาด
| HTTP สถานะ | ข้อผิดพลาด | คำอธิบาย |
|---|---|---|
| 400 | unsupported_grant_type |
รองรับเฉพาะ authorization_code และ refresh_token เท่านั้น |
| 400 | invalid_request |
พารามิเตอร์ที่จำเป็นขาดหาย |
| 401 | invalid_grant |
โค้ดไม่ถูกต้อง โค้ดหมดอายุ ข้อมูลรับรองไม่ตรงกัน หรือ Redirect URI ไม่ตรงกัน |
| 400 | invalid_client |
client_id ไม่ถูกต้อง |
| 400 | invalid_redirect_uri |
redirect_uri ไม่ตรงกับ URI ที่ลงทะเบียนไว้ |
สโคปที่ใช้ได้
Store (ร้านค้า)
| สโคป | คำอธิบาย |
|---|---|
store.products.read |
ดึงข้อมูลสินค้าและสต็อก |
store.products.write |
สร้างและอัปเดตสินค้า |
store.orders.read |
ดึงข้อมูลคำสั่งซื้อ |
store.orders.write |
อัปเดตสถานะคำสั่งซื้อ |
store.customers.read |
ดึงข้อมูลลูกค้า |
store.coupons.read |
ดึงข้อมูลคูปอง |
store.coupons.write |
สร้างและอัปเดตคูปอง |
store.inventory.read |
ดึงข้อมูลคลังและสต็อก |
CRM (การจัดการความสัมพันธ์ลูกค้า)
| สโคป | คำอธิบาย |
|---|---|
crm.profiles.read |
ดึงโปรไฟล์ลูกค้า CRM |
crm.segments.read |
ดึงเซกเมนต์และแรงก์ของ CRM |
SNS / การวิเคราะห์
| สโคป | คำอธิบาย |
|---|---|
sns.content.read |
ดึงข้อมูลโพสต์ SNS |
sns.audience.read |
ดึงข้อมูลผู้ชม SNS |
analytics.read |
ดึงสแนปช็อตการวิเคราะห์ |
แผนผังโฟลว์
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
│ แอปของคุณ │ │ เจ้าของ │ │ ReceiptRoller │
│ (นักพัฒนา) │ │ ธุรกิจ │ │ แพลตฟอร์ม │
└──────┬───────┘ └──────┬───────┘ └────────┬─────────┘
│ │ │
│ 1. รีไดเรกต์ไปยัง /oauth/authorize │
│────────────────────▶│────────────────────▶│
│ │ │
│ │ 2. แสดงหน้ายินยอม │
│ │◀─────────────────────│
│ │ │
│ │ 3. อนุญาต │
│ │─────────────────────▶│
│ │ │
│ 4. รีไดเรกต์ด้วย ?code=authorization code │
│◀───────────────────│◀─────────────────────│
│ │ │
│ 5. POST /api/v1/auth/token │
│ (code + client_id + client_secret) │
│───────────────────────────────────────────▶│
│ │
│ 6. { accessToken, refreshToken } │
│◀──────────────────────────────────────────│
│ │
│ 7. GET /api/v1/store/products │
│ Authorization: Bearer {accessToken} │
│───────────────────────────────────────────▶│
│ │
│ 8. { data: [...] } │
│◀──────────────────────────────────────────│
แนวปฏิบัติที่ดีด้านความปลอดภัย
- เก็บ
client_secretไว้ที่ฝั่งเซิร์ฟเวอร์เท่านั้น ห้ามใส่ไว้ในโค้ดฟรอนต์เอนด์หรือแอปมือถือโดยเด็ดขาด - เพื่อป้องกันการโจมตี CSRF โปรดตรวจสอบพารามิเตอร์
stateเสมอ - สำหรับแอปมือถือหรือแอปแบบ single-page โปรดใช้ PKCE (
code_challenge/code_verifier) - เก็บโทเคนไว้อย่างปลอดภัย อย่าบันทึกแอ็กเซสโทเคนลงล็อกหรือใส่ไว้ใน URL
- เพื่อหลีกเลี่ยงการหยุดชะงักของบริการ โปรดพัฒนาการรีเฟรชโทเคนก่อนที่จะหมดอายุ
- โปรดร้องขอเฉพาะสโคปที่แอปต้องใช้จริงเท่านั้น