api_auth_otp.txt 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. # EsimLao Authentication API Documentation
  2. ## Overview
  3. API xác thực người dùng qua email với OTP (One-Time Password).
  4. URL_UAT : http://149.28.132.56:8360/
  5. ---
  6. ## 1. Request OTP
  7. Gửi mã OTP đến email người dùng để xác thực đăng nhập.
  8. ### Endpoint
  9. ```
  10. POST /apis/auth/request-otp
  11. ```
  12. ### Request Headers
  13. | Header | Value | Required |
  14. |--------|-------|----------|
  15. | Content-Type | application/json | Yes |
  16. ### Request Body
  17. ```json
  18. {
  19. "email": "user@example.com",
  20. "lang": "lo" // Default: "lo" / en
  21. }
  22. ```
  23. ### Parameters
  24. | Field | Type | Required | Default | Description |
  25. |-------|------|----------|---------|-------------|
  26. | email | string | Yes | - | Email address của người dùng |
  27. | lang | string | No | "vi" | Ngôn ngữ email: `vi` (Tiếng Việt), `en` (English), `lo` (ລາວ) |
  28. ### Response Success (200)
  29. ```json
  30. {
  31. "errorCode": "0",
  32. "message": "<Config: OTP_SENT_SUCCESS>",
  33. "data": {
  34. "email": "user@example.com",
  35. "expireInSeconds": 300
  36. }
  37. }
  38. ```
  39. ### Response Error (200)
  40. ```json
  41. // Email không được cung cấp
  42. {
  43. "errorCode": "-801",
  44. "message": "<Config: EMAIL_REQUIRED>",
  45. "data": {}
  46. }
  47. // Lỗi hệ thống
  48. {
  49. "errorCode": "-6",
  50. "message": "<Config: SYSTEM_FAILURE>",
  51. "data": {}
  52. }
  53. ```
  54. ### Response Fields
  55. | Field | Type | Description |
  56. |-------|------|-------------|
  57. | errorCode| string | "0" = Success, khác "0" = Error (xem Error Codes) |
  58. | message | string | Thông báo từ CONFIG table (theo ngôn ngữ) |
  59. | data.email | string | Email đã gửi OTP |
  60. | data.expireInSeconds | int | Thời gian OTP hết hạn (giây) |
  61. ### Notes
  62. - OTP gồm 6 chữ số
  63. - OTP có hiệu lực trong 5 phút
  64. - Mỗi lần request mới sẽ hủy các OTP cũ chưa sử dụng
  65. - Nếu email chưa tồn tại, hệ thống tự động tạo tài khoản mới
  66. ---
  67. ## 2. Verify OTP
  68. Xác thực mã OTP và hoàn tất đăng nhập.
  69. ### Endpoint
  70. ```
  71. POST /apis/auth/verify-otp
  72. ```
  73. ### Request Headers
  74. | Header | Value | Required |
  75. |--------|-------|----------|
  76. | Content-Type | application/json | Yes |
  77. ### Request Body
  78. ```json
  79. {
  80. "email": "user@example.com",
  81. "otpCode": "123456",
  82. "lang": "lo" // Default: "lo" / en
  83. }
  84. ```
  85. ### Parameters
  86. | Field | Type | Required | Default | Description |
  87. |-------|------|----------|---------|-------------|
  88. | email | string | Yes | - | Email đã nhận OTP |
  89. | otpCode | string | Yes | - | Mã OTP 6 số |
  90. | lang | string | No | "lo" | Ngôn ngữ thông báo: `lo` (ລາວ), `en` (English) |
  91. ### Response Success (200)
  92. ```json
  93. {
  94. "errorCode": "0",
  95. "message": "<Config: LOGIN_SUCCESS>",
  96. "data": {
  97. "userId": 12345,
  98. "email": "user@example.com",
  99. "fullName": "Nguyen Van A",
  100. "avatarUrl": "https://example.com/avatar.jpg",
  101. "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  102. "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
  103. "expiresAt": "2024-12-30T10:00:00Z"
  104. }
  105. }
  106. ```
  107. ### Response Error Cases
  108. ```json
  109. // Thiếu email hoặc OTP
  110. {
  111. "errorCode": "-801",
  112. "message": "<Config: EMAIL_OTP_REQUIRED>",
  113. "data": {}
  114. }
  115. // OTP không hợp lệ
  116. {
  117. "errorCode": "-201",
  118. "message": "<Config: OTP_INVALID>",
  119. "data": {}
  120. }
  121. // OTP đã được sử dụng
  122. {
  123. "errorCode": "-203",
  124. "message": "<Config: OTP_ALREADY_USED>",
  125. "data": {}
  126. }
  127. // OTP đã hết hạn
  128. {
  129. "errorCode": "-202",
  130. "message": "<Config: OTP_EXPIRED>",
  131. "data": {}
  132. }
  133. // Không tìm thấy người dùng
  134. {
  135. "errorCode": "-300",
  136. "message": "<Config: USER_NOT_FOUND>",
  137. "data": {}
  138. }
  139. // Lỗi hệ thống
  140. {
  141. "errorCode": "-6",
  142. "message": "<Config: SYSTEM_FAILURE>",
  143. "data": {}
  144. }
  145. ```
  146. ### Response Fields
  147. | Field | Type | Description |
  148. |-------|------|-------------|
  149. | errorCode| string | "0" = Success, khác "0" = Error (xem Error Codes) |
  150. | message | string | Thông báo từ CONFIG table (theo ngôn ngữ) |
  151. | data.userId | int | ID người dùng |
  152. | data.email | string | Email người dùng |
  153. | data.fullName | string | Họ tên đầy đủ |
  154. | data.avatarUrl | string | URL ảnh đại diện (nullable) |
  155. | data.accessToken | string | JWT access token |
  156. | data.refreshToken | string | Refresh token để làm mới access token |
  157. | data.expiresAt | datetime | Thời điểm access token hết hạn |
  158. ### Notes
  159. - Access token có hiệu lực 24 giờ
  160. - Refresh token có hiệu lực 30 ngày
  161. - Mỗi lần đăng nhập thành công, các token cũ sẽ bị thu hồi
  162. ---
  163. ## Error Codes
  164. ### Success
  165. | errorCode| Constant | Description |
  166. |------|----------|-------------|
  167. | "0" | Success | Thành công (mọi request thành công đều trả về "0") |
  168. ### General Errors (-1 to -99)
  169. | errorCode| Constant | Description |
  170. |------|----------|-------------|
  171. | "-1" | Error | Lỗi chung |
  172. | "-6" | SystemError | Lỗi hệ thống |
  173. ### OTP Errors (-200 to -299)
  174. | errorCode| Constant | Description |
  175. |------|----------|-------------|
  176. | "-200" | OtpRequired | Yêu cầu OTP |
  177. | "-201" | OtpInvalid | OTP không hợp lệ |
  178. | "-202" | OtpExpired | OTP đã hết hạn |
  179. | "-203" | OtpAlreadyUsed | OTP đã được sử dụng |
  180. | "-204" | OtpMaxAttemptsExceeded | Vượt quá số lần thử |
  181. | "-205" | OtpSendFailed | Gửi OTP thất bại |
  182. | "-206" | OtpTooManyRequests | Request quá nhiều |
  183. ### User Errors (-300 to -399)
  184. | errorCode| Constant | Description |
  185. |------|----------|-------------|
  186. | "-300" | UserNotFound | Không tìm thấy người dùng |
  187. | "-304" | InvalidEmail | Email không hợp lệ |
  188. ### Validation Errors (-800 to -899)
  189. | errorCode| Constant | Description |
  190. |------|----------|-------------|
  191. | "-801" | RequiredFieldMissing | Thiếu trường bắt buộc |
  192. ---
  193. ## Authentication
  194. Sau khi đăng nhập thành công, sử dụng `accessToken` trong header cho các API yêu cầu xác thực:
  195. ```
  196. Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
  197. ```
  198. ---
  199. ## Flow Diagram
  200. ```
  201. ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
  202. │ Client │ │ API │ │ Email │
  203. └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
  204. │ │ │
  205. │ POST /request-otp │ │
  206. │──────────────────>│ │
  207. │ │ │
  208. │ │ Generate OTP │
  209. │ │ Save to DB │
  210. │ │ Queue Email │
  211. │ │ │
  212. │ Response │ │
  213. │<──────────────────│ │
  214. │ │ │
  215. │ │ Send OTP Email │
  216. │ │──────────────────>│
  217. │ │ │
  218. │ │ │ OTP Email
  219. │<──────────────────────────────────────│
  220. │ │ │
  221. │ POST /verify-otp │ │
  222. │──────────────────>│ │
  223. │ │ │
  224. │ │ Verify OTP │
  225. │ │ Generate JWT │
  226. │ │ │
  227. │ Token Response │ │
  228. │<──────────────────│ │
  229. │ │ │
  230. ```
  231. ---
  232. ## Example Usage (cURL)
  233. ### Request OTP
  234. ```bash
  235. curl -X POST https://api.esimlao.com/apis/auth/request-otp \
  236. -H "Content-Type: application/json" \
  237. -d '{
  238. "email": "user@example.com",
  239. "lang": "vi"
  240. }'
  241. ```
  242. ### Verify OTP
  243. ```bash
  244. curl -X POST https://api.esimlao.com/apis/auth/verify-otp \
  245. -H "Content-Type: application/json" \
  246. -d '{
  247. "email": "user@example.com",
  248. "otpCode": "123456"
  249. }'
  250. ```
  251. ### Use Token
  252. ```bash
  253. curl -X GET https://api.esimlao.com/apis/user/profile \
  254. -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  255. ```
  256. ---
  257. ## 3. Article Category
  258. Lấy danh sách danh mục bài viết.
  259. ### Endpoint
  260. ```
  261. POST /apis/article/category
  262. ```
  263. ### Request
  264. ```json
  265. {
  266. "lang": "lo",
  267. "pageNumber": 0,
  268. "pageSize": 10,
  269. "parentId": null
  270. }
  271. ```
  272. | Field | Type | Default | Description |
  273. |-------|------|---------|-------------|
  274. | lang | string | "lo" | Ngôn ngữ: "lo", "en" (có thể truyền qua header Accept-Language) |
  275. | pageNumber | int | 0 | Trang hiện tại |
  276. | pageSize | int | 10 | Số item mỗi trang |
  277. | parentId | int? | null | ID danh mục cha (null = root) |
  278. ### Response Success
  279. ```json
  280. {
  281. "errorCode": "0",
  282. "message": "Success",
  283. "data": {
  284. "categories": [
  285. {
  286. "id": 1,
  287. "categoryName": "Cẩm nang du lịch",
  288. "categorySlug": "cam-nang-du-lich",
  289. "description": "Mô tả...",
  290. "iconUrl": "/icons/travel.png",
  291. "parentId": null,
  292. "displayOrder": 1
  293. }
  294. ],
  295. "pagination": {
  296. "pageNumber": 0,
  297. "pageSize": 10,
  298. "totalCount": 5,
  299. "totalPages": 1
  300. }
  301. }
  302. }
  303. ```
  304. ---
  305. ## 4. Article Load
  306. Lấy danh sách bài viết hoặc chi tiết 1 bài viết.
  307. ### Endpoint
  308. ```
  309. POST /apis/article/load
  310. ```
  311. ### Request (danh sách)
  312. ```json
  313. {
  314. "lang": "lo",
  315. "pageNumber": 0,
  316. "pageSize": 10,
  317. "categoryId": 1,
  318. "isFeatured": false
  319. }
  320. ```
  321. ### Request (chi tiết)
  322. ```json
  323. {
  324. "lang": "lo",
  325. "slug": "huong-dan-cai-dat-esim"
  326. }
  327. ```
  328. | Field | Type | Default | Description |
  329. |-------|------|---------|-------------|
  330. | lang | string | "lo" | Ngôn ngữ (hoặc header Accept-Language) |
  331. | pageNumber | int | 0 | Trang hiện tại |
  332. | pageSize | int | 10 | Số item mỗi trang |
  333. | categoryId | int? | null | Lọc theo danh mục |
  334. | isFeatured | bool? | null | Lọc bài viết nổi bật |
  335. | slug | string? | null | Slug để lấy chi tiết bài viết |
  336. ### Response Success (danh sách)
  337. ```json
  338. {
  339. "errorCode": "0",
  340. "message": "Success",
  341. "data": {
  342. "articles": [
  343. {
  344. "id": 1,
  345. "title": "Hướng dẫn cài đặt eSIM",
  346. "slug": "huong-dan-cai-dat-esim",
  347. "summary": "Tóm tắt...",
  348. "thumbnailUrl": "/images/article1.jpg",
  349. "categoryId": 1,
  350. "viewCount": 150,
  351. "isFeatured": true,
  352. "isPinned": false,
  353. "publishedDate": "2024-12-25"
  354. }
  355. ],
  356. "pagination": {...}
  357. }
  358. }
  359. ```
  360. ### Response Success (chi tiết)
  361. ```json
  362. {
  363. "errorCode": "0",
  364. "message": "Success",
  365. "data": {
  366. "article": {
  367. "id": 1,
  368. "title": "Hướng dẫn cài đặt eSIM",
  369. "slug": "huong-dan-cai-dat-esim",
  370. "summary": "Tóm tắt...",
  371. "content": "<p>Nội dung HTML...</p>",
  372. "thumbnailUrl": "/images/article1.jpg",
  373. "coverImageUrl": "/images/cover1.jpg",
  374. "metaDescription": "SEO description",
  375. "metaKeywords": "esim, laos",
  376. "categoryId": 1,
  377. "viewCount": 151,
  378. "isFeatured": true,
  379. "publishedDate": "2024-12-25",
  380. "createdDate": "2024-12-20"
  381. }
  382. }
  383. }
  384. ```
  385. ---
  386. ## 5. Banner Load
  387. Lấy danh sách banner.
  388. ### Endpoint
  389. ```
  390. POST /apis/content/banner
  391. ```
  392. ### Request
  393. ```json
  394. {
  395. "lang": "lo",
  396. "pageNumber": 0,
  397. "pageSize": 10,
  398. "position": "home"
  399. }
  400. ```
  401. | Field | Type | Default | Description |
  402. |-------|------|---------|-------------|
  403. | lang | string | "lo" | Ngôn ngữ (hoặc header Accept-Language) |
  404. | pageNumber | int | 0 | Trang hiện tại |
  405. | pageSize | int | 10 | Số item mỗi trang |
  406. | position | string? | null | Vị trí: "home", "sidebar"... |
  407. ### Response
  408. ```json
  409. {
  410. "errorCode": "0",
  411. "data": {
  412. "banners": [
  413. {
  414. "id": 1,
  415. "title": "Banner Title",
  416. "subtitle": "Subtitle",
  417. "imageUrl": "/images/banner1.jpg",
  418. "imageMobileUrl": "/images/banner1_m.jpg",
  419. "linkUrl": "/promo",
  420. "linkTarget": "_blank",
  421. "position": "home",
  422. "displayOrder": 1
  423. }
  424. ],
  425. "pagination": {...}
  426. }
  427. }
  428. ```
  429. ---
  430. ## 6. Customer Review Load
  431. Lấy đánh giá của khách hàng.
  432. ### Endpoint
  433. ```
  434. POST /apis/content/review
  435. ```
  436. ### Request
  437. ```json
  438. {
  439. "lang": "lo",
  440. "pageNumber": 0,
  441. "pageSize": 10,
  442. "isFeatured": true
  443. }
  444. ```
  445. | Field | Type | Default | Description |
  446. |-------|------|---------|-------------|
  447. | lang | string | "lo" | Ngôn ngữ |
  448. | pageNumber | int | 0 | Trang |
  449. | pageSize | int | 10 | Số item |
  450. | isFeatured | bool? | null | Lọc review nổi bật |
  451. ### Response
  452. ```json
  453. {
  454. "errorCode": "0",
  455. "data": {
  456. "reviews": [
  457. {
  458. "id": 1,
  459. "customerName": "Nguyen Van A",
  460. "avatarUrl": "/avatars/user1.jpg",
  461. "rating": 1,
  462. "reviewContent": "Dich vu rat tot...",
  463. "destination": "Vientiane, Laos",
  464. "isFeatured": true,
  465. "createdDate": "2024-12-25"
  466. }
  467. ],
  468. "pagination": {...}
  469. }
  470. }
  471. ```
  472. ---
  473. ## 6.1 Customer Review Create
  474. Khách hàng gửi đánh giá (chờ duyệt).
  475. ### Endpoint
  476. ```
  477. POST /apis/content/review/create
  478. ```
  479. ### Request
  480. ```json
  481. {
  482. "lang": "lo",
  483. "customerName": "Nguyen Van A",
  484. "reviewContent": "Dich vu rat tot, toi rat hai long!",
  485. "destination": "Vientiane, Laos",
  486. "rating": 5
  487. }
  488. ```
  489. | Field | Type | Required | Description |
  490. |-------|------|----------|-------------|
  491. | lang | string | No | Ngôn ngữ |
  492. | customerName | string | Yes | Tên khách hàng |
  493. | reviewContent | string | Yes | Nội dung đánh giá |
  494. | destination | string | No | Địa điểm |
  495. | rating | int | No | Đánh giá (1-5) |
  496. ### Response Success
  497. ```json
  498. {
  499. "errorCode": "0",
  500. "message": "Review submitted successfully",
  501. "data": {
  502. "reviewId": 123
  503. }
  504. }
  505. ```
  506. ### Note
  507. - Review mới sẽ có `Status = false` (chờ admin duyệt)
  508. ---
  509. ## 7. FAQ Category Load
  510. Lấy danh mục FAQ.
  511. ### Endpoint
  512. ```
  513. POST /apis/content/faq-category
  514. ```
  515. ### Request
  516. ```json
  517. {
  518. "lang": "lo",
  519. "pageNumber": 0,
  520. "pageSize": 10
  521. }
  522. ```
  523. ### Response
  524. ```json
  525. {
  526. "errorCode": "0",
  527. "data": {
  528. "categories": [
  529. {
  530. "id": 1,
  531. "categoryName": "Cài đặt eSIM",
  532. "categorySlug": "cai-dat-esim",
  533. "description": "Hướng dẫn cài đặt",
  534. "iconUrl": "/icons/setup.png",
  535. "displayOrder": 1
  536. }
  537. ],
  538. "pagination": {...}
  539. }
  540. }
  541. ```
  542. ---
  543. ## 8. FAQ Load
  544. Lấy danh sách câu hỏi thường gặp.
  545. ### Endpoint
  546. ```
  547. POST /apis/content/faq
  548. ```
  549. ### Request
  550. ```json
  551. {
  552. "lang": "lo",
  553. "pageNumber": 0,
  554. "pageSize": 10,
  555. "categoryId": 1,
  556. "isFeatured": false
  557. }
  558. ```
  559. | Field | Type | Default | Description |
  560. |-------|------|---------|-------------|
  561. | lang | string | "lo" | Ngôn ngữ |
  562. | pageNumber | int | 0 | Trang |
  563. | pageSize | int | 10 | Số item |
  564. | categoryId | int? | null | Lọc theo danh mục |
  565. | isFeatured | bool? | null | Lọc FAQ nổi bật |
  566. ### Response
  567. ```json
  568. {
  569. "errorCode": "0",
  570. "data": {
  571. "faqs": [
  572. {
  573. "id": 1,
  574. "question": "Làm sao để cài đặt eSIM?",
  575. "answer": "<p>Hướng dẫn chi tiết...</p>",
  576. "categoryId": 1,
  577. "viewCount": 100,
  578. "isFeatured": true
  579. }
  580. ],
  581. "pagination": {...}
  582. }
  583. }
  584. ```