คู่มือ API โปรไฟล์ผู้ใช้ — สำหรับนักพัฒนา
API นี้ให้แอปพลิเคชันภายนอกตรวจสอบสิทธิ์ผู้ใช้กับฐานข้อมูล ImpAcc และอ่านข้อมูล โปรไฟล์ของผู้ใช้รายนั้น ใช้ระบบ bearer token ของ Laravel Sanctum
- Base URL:
https://usr.impacc.work/api - รูปแบบการยืนยันตัวตน: Bearer token (ออกโดย
POST /api/login) - รูปแบบ Request:
application/json - รูปแบบ Response:
application/json - เขตเวลา: เวลาตามเครื่องเซิร์ฟเวอร์ ใช้รูปแบบ ISO‑8601
โทเค็นที่ออกจาก
/api/loginจะไม่หมดอายุอัตโนมัติ หากต้องการยกเลิก ให้เรียก/api/logout
1. ขั้นตอนการยืนยันตัวตน
┌──────────────┐ 1. POST /api/login ┌────────────────┐
│ │ citizen_id + password │ │
│ แอปของคุณ │ ─────────────────────► │ API โปรไฟล์ │
│ (ภายนอก) │ ◄───────────────────── │ (usr.impacc) │
│ │ bearer token │ │
└──────────────┘ └────────────────┘
│ 2. เก็บ token (memory / secure storage)
│
│ 3. ทุกคำขอครั้งต่อไปแนบ header:
│ Authorization: Bearer <token>
▼
GET /api/profile
GET /api/permissions
POST /api/logout
วิธีขอ bearer token มี 2 ทาง:
POST /api/login— ด้วยcitizen_id+password(หัวข้อ 2.1)POST /api/sso/exchange— ด้วยmTokenแบบใช้ครั้งเดียวที่ออกโดยพอร์ทัล imPACC สำหรับแอปที่เปิดผ่าน Single Sign-On (หัวข้อ 2.5) โดยไม่ต้องจัดการรหัสผ่าน
ทั้งสองทางคืนค่า { token, token_type, user } รูปแบบเดียวกัน ขั้นตอนหลังจากนั้นเหมือนกันทุกประการ
Header ที่ต้องส่ง
| Header | ค่า | เมื่อไร |
|---|---|---|
Accept |
application/json |
ทุกครั้ง |
Content-Type |
application/json |
เมื่อ POST/PUT |
Authorization |
Bearer <token> |
เมื่อเรียก EP ที่ป้องกัน |
หากไม่ส่ง Accept: application/json Laravel อาจตอบกลับเป็นหน้า HTML
แทน JSON เมื่อยืนยันตัวตนล้มเหลว ต้องส่ง header นี้เสมอ
2. รายการ Endpoint
2.1 POST /api/login
แลกเปลี่ยน credentials เป็น bearer token
ฟิลด์ใน Request body
| ฟิลด์ | ชนิด | จำเป็น | คำอธิบาย |
|---|---|---|---|
citizen_id |
string | ใช่ | เลขประจำตัวประชาชน 13 หลักของผู้ใช้ |
password |
string | ใช่ | รหัสผ่านของผู้ใช้ (ส่งผ่าน HTTPS) |
device_name |
string | ไม่ | ป้ายกำกับบันทึกไว้กับ token เช่น "mobile-app-ios" |
ตัวอย่าง
curl -X POST https://usr.impacc.work/api/login \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"citizen_id": "1234567890123",
"password": "user-secret",
"device_name": "partner-app-web"
}'
สำเร็จ — 200 OK
{
"token": "12|H7c0gQ9b3l...redacted...XyZ",
"token_type": "Bearer",
"user": {
"id": 1234,
"citizen_id": "1234567890123",
"title": "นาย",
"firstname": "สมชาย",
"lastname": "ใจดี",
"email": "somchai@example.com",
"mobile": "0812345678",
"workgroup_id": 39,
"division_id": 2,
"status": "1",
"roles": ["user"],
"last_login": "2026-05-19T08:42:11.000000Z",
"current_profile": { "...": "ดูโครงสร้างใน profiles[] ด้านล่าง" },
"profiles": [
{
"id": 1,
"label": "ต้นสังกัด",
"kind": "home",
"dept1": "สำนักงาน ป.ป.ท.",
"dept2": "สำนักงาน ป.ป.ท.",
"dept3": null,
"officer_type_id": 4,
"officer_type_name": "ทั่วไป",
"position_type_id": 3,
"position_type_name": "วิชาการ",
"position": "นักวิชาการ",
"level": "ปฏิบัติการ",
"is_default": true,
"is_active": true,
"is_temporary": false,
"status": "approved"
},
{
"id": 4,
"label": "คณะทำงานพิเศษ",
"kind": "mission",
"dept1": "รองเลขาธิการ ป.ป.ท. (คนที่ 1)",
"dept2": "งานรองเลขาธิการ ป.ป.ท. (คนที่ 1)",
"officer_type_name": "เจ้าหน้าที่ ป.ป.ท.",
"is_default": false,
"is_active": false,
"is_temporary": true,
"mission_title": "สืบสวน",
"mission_note": "ช่วยราชการคณะทำงาน X",
"mission_start_date": "2026-01-01",
"mission_end_date": "2026-06-30",
"mission_order_no": "123/2569",
"mission_order_file": "orders/2569-123.pdf",
"status": "approved"
}
]
}
}
profiles[] ถูกเรียงโดยให้โปรไฟล์ที่กำลังใช้งาน (is_active=true)
ขึ้นก่อน ตามด้วยโปรไฟล์หลัก (is_default=true) ส่วนที่เหลือเรียงตาม
id current_profile คือทางลัดชี้ไปยังแถวเดียวกันกับที่ผู้ใช้กำลังใช้งาน
อยู่ (ถ้าไม่มี is_active จะ fallback เป็น is_default)
หากผู้ใช้ยังไม่มีแถวใน user_profiles เลย ค่า current_profile จะเป็น
null และ profiles[] จะเป็น array ว่าง
อ็อบเจกต์ user ยังมีบล็อก permissions ด้วย — คือสิทธิ์การเข้าถึง
แอปพลิเคชัน/เมนู/ส่วนย่อย ที่ผู้ใช้มีจริง โครงสร้างอธิบายไว้ใน
หัวข้อ 2.4 GET /api/permissions ตัวอย่างด้านบน
ตัดบล็อกนี้ออกเพื่อความกระชับ แต่จะมีอยู่เสมอในการตอบกลับจริง
เก็บ token ไว้ในที่ปลอดภัยและส่งใน header Authorization: Bearer <token>
ทุกครั้งที่เรียก endpoint ที่ต้องยืนยันตัวตน
ล้มเหลว — 422 Unprocessable Entity (credential ไม่ถูกต้องหรือบัญชีถูกปิด)
{
"message": "The provided credentials are incorrect.",
"errors": {
"citizen_id": ["The provided credentials are incorrect."]
}
}
ล้มเหลว — 422 Unprocessable Entity (ส่งข้อมูลไม่ครบ)
{
"message": "The citizen id field is required. (and 1 more error)",
"errors": {
"citizen_id": ["The citizen id field is required."],
"password": ["The password field is required."]
}
}
2.2 GET /api/profile
ดึงข้อมูลโปรไฟล์ของผู้ใช้ที่ล็อกอินอยู่ อ็อบเจกต์ user เหมือนกับที่ได้จาก
POST /api/login ทุกประการ — รวมถึง current_profile, profiles[] ทั้งหมด
และบล็อก permissions (ดูหัวข้อ 2.4) ตัวอย่างด้านล่างแสดงเฉพาะฟิลด์ระดับผู้ใช้
เพื่อความกระชับ
Headers
Accept: application/json
Authorization: Bearer <token>
ตัวอย่าง
curl https://usr.impacc.work/api/profile \
-H "Accept: application/json" \
-H "Authorization: Bearer 12|H7c0gQ9b3l...XyZ"
สำเร็จ — 200 OK (โครงสร้างเหมือนฟิลด์ user ใน login response)
{
"user": {
"id": 1234,
"citizen_id": "1234567890123",
"firstname": "สมชาย",
"lastname": "ใจดี",
"email": "somchai@example.com",
"mobile": "0812345678",
"workgroup": "IT",
"workgroup_id": 39,
"division_id": 2,
"organization": "Impacc",
"status": "1",
"roles": ["user"],
"last_login": "2026-05-19T08:42:11.000000Z"
}
}
ล้มเหลว — 401 Unauthenticated (ไม่มี token, token ผิด หรือถูกยกเลิก)
{ "message": "Unauthenticated." }
2.3 POST /api/logout
ยกเลิก bearer token ที่ใช้กับ request นี้ หลังเรียกแล้ว token จะใช้ไม่ได้อีก
Headers
Accept: application/json
Authorization: Bearer <token>
ตัวอย่าง
curl -X POST https://usr.impacc.work/api/logout \
-H "Accept: application/json" \
-H "Authorization: Bearer 12|H7c0gQ9b3l...XyZ"
สำเร็จ — 200 OK
{ "message": "Logged out" }
2.4 GET /api/permissions
คืนค่า สิทธิ์การเข้าถึงที่มีผลจริง ของผู้ใช้ที่ล็อกอินอยู่ ครอบคลุม
3 ระดับ: แอปพลิเคชัน → เมนู → ส่วนย่อย (section) อ็อบเจกต์เดียวกันนี้
ถูกฝังไว้เป็น user.permissions ในการตอบกลับของ login และ profile ด้วย
endpoint นี้คืนเฉพาะอ็อบเจกต์นั้นเมื่อคุณต้องการแค่ข้อมูลสิทธิ์
วิธีคำนวณสิทธิ์
สิทธิ์จะ มีผล กับผู้ใช้เมื่อได้รับอนุญาตในระดับนั้นและไม่ถูกบล็อก:
สิทธิ์ที่มีผล = ( สิทธิ์จากกลุ่มของผู้ใช้ ) ← กลุ่มมาจากทั้งสองทาง
∪ ( สิทธิ์ที่ให้ผู้ใช้โดยตรง ) users.workgroup_id → workgroup_groups
∖ ( รายการบล็อกของผู้ใช้ ) และการเป็นสมาชิกโดยตรงใน user_groups
- กลุ่ม คือยูเนียนของกลุ่มที่ได้จากกลุ่มงาน (
workgroup_groupsผ่านusers.workgroup_id) และการเป็นสมาชิกโดยตรง (user_groups) - สิทธิ์ที่ให้ มาจาก
group_*_permissions(ตามกลุ่ม) และuser_*_permissions(ตามผู้ใช้) - การบล็อก (
user_application_blocks,user_menu_blocks) จะถอด แอป/เมนูออกจากผู้ใช้รายนั้น แม้กลุ่มจะให้สิทธิ์ก็ตาม ส่วนระดับ section ไม่มีตารางบล็อก
เมนูจะซ้อนอยู่ใต้แอปก็ต่อเมื่อแอปนั้นมีผลกับผู้ใช้ และ section จะซ้อนอยู่ ใต้เมนูที่มีผลในทำนองเดียวกัน
ระดับ section มีอยู่ใน schema แต่ปัจจุบันยังไม่มีข้อมูล ดังนั้น
sectionsจึงเป็น[]สำหรับทุกเมนูในตอนนี้ และจะถูกเติมอัตโนมัติเมื่อมีการกำหนด สิทธิ์ section — ฝั่ง client ไม่ต้องแก้ไขใด ๆ
Headers
Accept: application/json
Authorization: Bearer <token>
ตัวอย่าง
curl https://usr.impacc.work/api/permissions \
-H "Accept: application/json" \
-H "Authorization: Bearer 12|H7c0gQ9b3l...XyZ"
สำเร็จ — 200 OK
{
"permissions": {
"group_ids": [1, 2, 3, 22, 23],
"applications": [
{
"id": 22,
"app_id": "11-22",
"name": "ระบบDIDC",
"link": "/miniapp/didc",
"menus": [
{
"id": 81,
"name": "จัดการ Dashboard",
"path": "/dashboard-management",
"level": 2,
"parent": 75,
"sections": []
}
]
},
{
"id": 13,
"app_id": "11-13",
"name": "ระบบประชาสัมพันธ์-ภายนอก",
"link": "/miniapp/xcms",
"menus": []
}
]
}
}
แอปที่ไม่มีเมนูที่มีผลจะคืนค่า "menus": [] (ผู้ใช้เข้าถึงแอปได้แต่ยังไม่มี
เมนูใดถูกให้สิทธิ์/มีผลใต้แอปนั้น)
ล้มเหลว — 401 Unauthenticated
{ "message": "Unauthenticated." }
2.5 POST /api/sso/exchange
การแลกโทเค็นแบบ Single Sign-On — เป็น ทางเลือกแทน POST /api/login
สำหรับแอปที่ถูกเปิดจากพอร์ทัล imPACC (impacc.work) โดยไม่ต้องรับรหัสผ่าน
เมื่อผู้ใช้ที่ล็อกอินพอร์ทัลอยู่แล้วเปิดแอปที่เชื่อมโยง พอร์ทัลจะสร้าง
mToken แบบใช้ครั้งเดียวบนข้อมูลผู้ใช้ และ redirect เบราว์เซอร์มาที่แอป
พร้อมโทเค็นนั้น (เช่น https://your-app?appId=...&mToken=...) แอปจะ POST
mToken มาที่นี่เพื่อรับ bearer token และข้อมูลโปรไฟล์ โดยไม่ต้องจัดการ
credential ของผู้ใช้
mTokenใช้ได้ครั้งเดียว จะถูกล้างทันทีที่แลกสำเร็จครั้งแรก จึงนำมาใช้ซ้ำ ไม่ได้ พอร์ทัลจะสร้างmTokenใหม่ทุกครั้งที่เปิดแอป ควรแลกโดยเร็ว
ฟิลด์ใน Request body
| ฟิลด์ | ชนิด | จำเป็น | คำอธิบาย |
|---|---|---|---|
mToken |
string | ใช่ | โทเค็นครั้งเดียวจากการ redirect ของพอร์ทัล |
device_name |
string | ไม่ | ป้ายกำกับบันทึกไว้กับ token เช่น "sso-web" |
ตัวอย่าง
curl -X POST https://usr.impacc.work/api/sso/exchange \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{ "mToken": "0f3a…โทเค็น 64 ตัว…d9", "device_name": "sso-web" }'
สำเร็จ — 200 OK
โครงสร้างเหมือน POST /api/login ทุกประการ — มี token, token_type และ
อ็อบเจกต์ user แบบเต็ม (รวม current_profile, profiles[] และบล็อก
permissions จากหัวข้อ 2.4):
{
"token": "9|iU7SMJ2TjJ7feNnG…redacted…",
"token_type": "Bearer",
"user": { "id": 1, "citizen_id": "…", "permissions": { "…": "ดูหัวข้อ 2.4" } }
}
ล้มเหลว — 422 Unprocessable Entity (mToken ไม่ถูกต้อง ถูกใช้ไปแล้ว
หมดอายุ หรือบัญชีถูกปิด)
{
"message": "Invalid or expired SSO token.",
"errors": { "mToken": ["Invalid or expired SSO token."] }
}
หลังแลกสำเร็จ ให้ใช้ token ที่ได้เหมือนกับโทเค็นจาก /login ทุกประการ คือแนบ
Authorization: Bearer <token> ในทุกคำขอถัดไป และเรียก POST /api/logout
เพื่อเพิกถอนโทเค็น
3. คำอธิบายฟิลด์ในโปรไฟล์
3.1 ฟิลด์ระดับผู้ใช้
| ฟิลด์ | ชนิด | คำอธิบาย |
|---|---|---|
id |
integer | รหัสภายในระบบ |
citizen_id |
string | เลขประจำตัวประชาชน 13 หลัก ใช้เป็น identifier หลัก |
title |
string | คำนำหน้าภาษาไทย (นาย / นาง / นางสาว …) |
firstname |
string | ชื่อจริงภาษาไทย |
lastname |
string | นามสกุลภาษาไทย |
title_english |
string | คำนำหน้าภาษาอังกฤษ |
firstname_english |
string | ชื่อจริงภาษาอังกฤษ |
lastname_english |
string | นามสกุลภาษาอังกฤษ |
email |
string | อีเมล |
mobile |
string | เบอร์มือถือ |
born_date |
date | YYYY-MM-DD |
workgroup |
string | กลุ่มงาน / ทีม (จาก row users) |
workgroup_id |
integer/null | FK ตาราง workgroups ใช้คำนวณกลุ่ม/สิทธิ์ (ดูหัวข้อ 2.4) |
division_id |
integer/null | FK ตาราง divisions — สังกัด/กองของผู้ใช้ |
organization |
string | ชื่อหน่วยงาน (จาก row users) |
role_type1..3 |
string | ประเภทบทบาท (เนื้อหาขึ้นกับโปรเจกต์) |
status |
string | "1" = ใช้งานได้, ค่าอื่น = ถูกระงับ |
roles |
string[] | ชื่อ role จาก Spatie permission |
last_login |
datetime | เวลา login ล่าสุด (ISO‑8601) |
current_profile |
object/null | ทางลัด: โปรไฟล์ที่ผู้ใช้กำลังใช้งานอยู่ (มีโครงสร้างเหมือนรายการใน profiles[]) |
profiles[] |
object[] | รายการสังกัด/ภารกิจทั้งหมดของผู้ใช้ ดูหัวข้อ 3.2 |
permissions |
object | สิทธิ์แอป/เมนู/section ที่ผู้ใช้มีจริง ดูหัวข้อ 2.4 และ 3.3 |
password, remember_token และไฟล์อัปโหลดจะไม่ถูกส่งกลับ
3.2 ฟิลด์ของโปรไฟล์ (OU / ภารกิจพิเศษ)
แต่ละรายการใน profiles[] คือสังกัดหนึ่งของผู้ใช้
- โปรไฟล์ ต้นสังกัด จะมี
is_default=true(มีได้เพียงแถวเดียว) - โปรไฟล์ สังกัดเพิ่มเติม คือแถวที่
is_default=falseและis_temporary=false - โปรไฟล์ ภารกิจพิเศษ จะมี
is_temporary=trueและฟิลด์mission_*จะถูกเติม
| ฟิลด์ | ชนิด | คำอธิบาย |
|---|---|---|
id |
integer | รหัส row ของโปรไฟล์ (คงที่ระหว่าง request) |
label |
string | ป้ายกำกับ เช่น "ต้นสังกัด", "สังกัดเพิ่มเติม", "ภารกิจพิเศษ" |
kind |
enum | ตัวจำแนกเชิงโครงสร้าง: "home", "secondary", "mission" |
dept1 |
string | กรมหรือสำนัก (DivisionLevel1) |
dept2 |
string | กอง (DivisionLevel2) |
dept3 |
string | กลุ่มงาน (DivisionLevel3) |
officer_type_id |
integer | FK ตาราง officer_types |
officer_type_name |
string | ชื่อจาก officer_types |
position_type_id |
integer | FK ตาราง ds_positions_types |
position_type_name |
string | ชื่อจาก ds_positions_types |
position |
string | ชื่อตำแหน่ง |
description |
string | คำอธิบายตำแหน่ง |
level |
string | ระดับ เช่น "ปฏิบัติการ", "ชำนาญการ" |
management_position |
string | ตำแหน่งสายบริหาร (ถ้ามี) |
is_default |
bool | true คือต้นสังกัด มีได้เพียงแถวเดียวต่อผู้ใช้ |
is_active |
bool | true คือโปรไฟล์ที่ผู้ใช้กำลังใช้งานในระบบ |
is_temporary |
bool | true แสดงว่าเป็นภารกิจพิเศษ มีฟิลด์ mission_* ประกอบ |
mission_title |
string | ชื่อภารกิจ (เช่น "สืบสวน") |
mission_note |
string | บันทึกเพิ่มเติม |
mission_start_date |
date | YYYY-MM-DD |
mission_end_date |
date | YYYY-MM-DD หลังจากนี้ถือว่าภารกิจสิ้นสุด |
mission_order_no |
string | เลขที่คำสั่ง |
mission_order_file |
string | path ของไฟล์คำสั่ง relative จาก storage |
status |
string | "approved", "pending", "ended", … |
approved_at |
datetime | เวลาที่อนุมัติ |
การตีความ kind
kind |
เงื่อนไข | ความหมาย |
|---|---|---|
"home" |
is_default=true |
ต้นสังกัด/สังกัดถาวร |
"mission" |
is_default=false, is_temporary=true |
ภารกิจพิเศษมีกำหนดเวลา |
"secondary" |
is_default=false, is_temporary=false |
สังกัดเพิ่มเติมที่ไม่ใช่ภารกิจ |
แอปที่ต้องการเฉพาะสังกัดหลักของผู้ใช้ สามารถใช้ current_profile ตรง ๆ
ส่วนแอปที่ต้องแสดงรายการสังกัด (เช่น เมนู "สลับสังกัด") ให้วน profiles[]
3.3 ฟิลด์สิทธิ์ (permissions)
อ็อบเจกต์ permissions (คืนเดี่ยว ๆ จากหัวข้อ 2.4 และฝังอยู่ใน
user.permissions) มีโครงสร้างดังนี้:
| ฟิลด์ | ชนิด | คำอธิบาย |
|---|---|---|
group_ids |
int[] | ทุกกลุ่มที่ผู้ใช้สังกัด (จากกลุ่มงาน ∪ โดยตรง) |
applications[] |
object[] | แอปที่มีผล เรียงตาม sequence แล้วตาม id |
applications[].id |
integer | รหัสแอปภายใน (applications.id) |
applications[].app_id |
string | รหัสแอปภายนอก (เช่น "11-22") |
applications[].name |
string | ชื่อแอปที่แสดงผล |
applications[].link |
string | path/URL เข้าแอป (ถ้ามี) |
applications[].menus[] |
object[] | เมนูที่มีผลใต้แอปนี้ ([] ถ้าไม่มี) |
menus[].id |
integer | รหัสเมนูภายใน (menu_applications.id) |
menus[].name |
string | ชื่อเมนูที่แสดงผล |
menus[].path |
string | path/route ของเมนู |
menus[].level |
int/null | ระดับชั้นของเมนู (1 = ระดับบนสุด) |
menus[].parent |
int/null | รหัสเมนูแม่ ใช้จัดซ้อนใน sidebar |
menus[].sections[] |
object[] | section ที่มีผลใต้เมนูนี้ ([] จนกว่าจะมีข้อมูล section) |
sections[].id |
integer | รหัส section ภายใน (section_menus.id) |
sections[].name |
string | ชื่อ section ที่แสดงผล |
จะปรากฏเฉพาะรายการที่ ได้รับสิทธิ์และไม่ถูกบล็อก เท่านั้น การที่ไม่มี
แอป เมนู หรือ section ใด หมายความว่าผู้ใช้ไม่มีสิทธิ์เข้าถึงรายการนั้น
แนะนำให้สร้างชุด "path ที่อนุญาต" จาก menus[].path ไว้ใช้คุม route guard
ฝั่ง client
4. รหัสสถานะ HTTP
| สถานะ | ความหมาย |
|---|---|
| 200 | สำเร็จ |
| 401 | ไม่มี/token ผิด/ถูกยกเลิก — ให้ผู้ใช้ login ใหม่ |
| 419 | CSRF/session ไม่ตรง — มักเกิดจากไม่ใส่ Accept: application/json |
| 422 | Validation ผิด (credential ผิด / ส่งข้อมูลไม่ครบ) |
| 429 | เรียกเกินอัตราที่อนุญาต (ค่าเริ่มต้น 60 req/min/IP) |
| 500 | เซิร์ฟเวอร์ผิดพลาด — ให้บันทึก response body แล้วแจ้งทีม API |
5. แนวทางการจัดการ Token
- ห้าม ใส่ token ใน URL ให้ใส่ใน header เท่านั้น
- ใช้ HTTPS ทุกครั้ง — credential และ token ถูกส่งแบบ plain ใน body/header
- เก็บ token ใน secure storage (iOS Keychain, Android Keystore, server-side encrypted session, หรือ httpOnly cookie)
- เรียก
POST /api/logoutเมื่อผู้ใช้ออกจากระบบ เพื่อไม่ให้ token เก่าใช้ได้อีก - หนึ่ง token ต่อหนึ่งอุปกรณ์ — ส่ง
device_nameต่างกัน เพื่อให้ติดตามและยกเลิกได้แยกเครื่อง - เมื่อได้
401ให้ถือว่า session สิ้นสุด ล้าง token ที่เก็บไว้และให้ผู้ใช้ login ใหม่
6. ตัวอย่างการเชื่อมต่อ
6.1 JavaScript (fetch)
async function login(citizenId, password) {
const r = await fetch('https://usr.impacc.work/api/login', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
citizen_id: citizenId,
password,
device_name: 'web-partner-app',
}),
});
if (!r.ok) throw new Error(`Login failed: ${r.status}`);
return r.json(); // { token, token_type, user }
}
async function getProfile(token) {
const r = await fetch('https://usr.impacc.work/api/profile', {
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${token}`,
},
});
if (r.status === 401) throw new Error('Token expired');
return r.json();
}
6.2 PHP (Guzzle)
use GuzzleHttp\Client;
$http = new Client(['base_uri' => 'https://usr.impacc.work/api/']);
$login = $http->post('login', [
'headers' => ['Accept' => 'application/json'],
'json' => [
'citizen_id' => '1234567890123',
'password' => $userPassword,
'device_name' => 'partner-backend',
],
]);
$token = json_decode((string) $login->getBody(), true)['token'];
$profile = $http->get('profile', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => "Bearer {$token}",
],
]);
6.3 Python (requests)
import requests
BASE = "https://usr.impacc.work/api"
def login(citizen_id, password):
r = requests.post(f"{BASE}/login", json={
"citizen_id": citizen_id,
"password": password,
"device_name": "partner-python",
}, headers={"Accept": "application/json"})
r.raise_for_status()
return r.json()["token"]
def profile(token):
r = requests.get(f"{BASE}/profile", headers={
"Accept": "application/json",
"Authorization": f"Bearer {token}",
})
r.raise_for_status()
return r.json()["user"]
7. การติดต่อทีมงาน
หากต้องการขอสิทธิ์เข้าใช้งานบน production หรือต้องการ allow‑list IP/โดเมน กรุณาติดต่อทีม API ของ ImpAcc พร้อมระบุข้อมูลต่อไปนี้
- ชื่อแอปพลิเคชันที่จะเรียกใช้งาน
- IP สาธารณะหรือโดเมนที่จะใช้เรียก API
- ปริมาณ request ที่คาดว่าจะใช้
Generated 2026-06-06 05:32 · ImpAcc User Profile API