| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682 |
- # EsimLao Authentication API Documentation
- ## Overview
- API xác thực người dùng qua email với OTP (One-Time Password).
- URL_UAT : http://149.28.132.56:8360/
- ---
- ## 1. Request OTP
- Gửi mã OTP đến email người dùng để xác thực đăng nhập.
- ### Endpoint
- ```
- POST /apis/auth/request-otp
- ```
- ### Request Headers
- | Header | Value | Required |
- |--------|-------|----------|
- | Content-Type | application/json | Yes |
- ### Request Body
- ```json
- {
- "email": "user@example.com",
- "lang": "lo" // Default: "lo" / en
- }
- ```
- ### Parameters
- | Field | Type | Required | Default | Description |
- |-------|------|----------|---------|-------------|
- | email | string | Yes | - | Email address của người dùng |
- | lang | string | No | "vi" | Ngôn ngữ email: `vi` (Tiếng Việt), `en` (English), `lo` (ລາວ) |
- ### Response Success (200)
- ```json
- {
- "errorCode": 0,
- "message": "<Config: OTP_SENT_SUCCESS>",
- "data": {
- "email": "user@example.com",
- "expireInSeconds": 300
- }
- }
- ```
- ### Response Error (200)
- ```json
- // Email không được cung cấp
- {
- "errorCode": -801,
- "message": "<Config: EMAIL_REQUIRED>",
- "data": {}
- }
- // Lỗi hệ thống
- {
- "errorCode": -6,
- "message": "<Config: SYSTEM_FAILURE>",
- "data": {}
- }
- ```
- ### Response Fields
- | Field | Type | Description |
- |-------|------|-------------|
- | errorCode| int | 0 = Success, khác 0 = Error (xem Error Codes) |
- | message | string | Thông báo từ CONFIG table (theo ngôn ngữ) |
- | data.email | string | Email đã gửi OTP |
- | data.expireInSeconds | int | Thời gian OTP hết hạn (giây) |
- ### Notes
- - OTP gồm 6 chữ số
- - OTP có hiệu lực trong 5 phút
- - Mỗi lần request mới sẽ hủy các OTP cũ chưa sử dụng
- - Nếu email chưa tồn tại, hệ thống tự động tạo tài khoản mới
- ---
- ## 2. Verify OTP
- Xác thực mã OTP và hoàn tất đăng nhập.
- ### Endpoint
- ```
- POST /apis/auth/verify-otp
- ```
- ### Request Headers
- | Header | Value | Required |
- |--------|-------|----------|
- | Content-Type | application/json | Yes |
- ### Request Body
- ```json
- {
- "email": "user@example.com",
- "otpCode": "123456",
- "lang": "lo" // Default: "lo" / en
- }
- ```
- ### Parameters
- | Field | Type | Required | Default | Description |
- |-------|------|----------|---------|-------------|
- | email | string | Yes | - | Email đã nhận OTP |
- | otpCode | string | Yes | - | Mã OTP 6 số |
- | lang | string | No | "lo" | Ngôn ngữ thông báo: `lo` (ລາວ), `en` (English) |
- ### Response Success (200)
- ```json
- {
- "errorCode": 0,
- "message": "<Config: LOGIN_SUCCESS>",
- "data": {
- "userId": 12345,
- "email": "user@example.com",
- "fullName": "Nguyen Van A",
- "avatarUrl": "https://example.com/avatar.jpg",
- "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
- "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
- "expiresAt": "2024-12-30T10:00:00Z"
- }
- }
- ```
- ### Response Error Cases
- ```json
- // Thiếu email hoặc OTP
- {
- "errorCode": -801,
- "message": "<Config: EMAIL_OTP_REQUIRED>",
- "data": {}
- }
- // OTP không hợp lệ
- {
- "errorCode": -201,
- "message": "<Config: OTP_INVALID>",
- "data": {}
- }
- // OTP đã được sử dụng
- {
- "errorCode": -203,
- "message": "<Config: OTP_ALREADY_USED>",
- "data": {}
- }
- // OTP đã hết hạn
- {
- "errorCode": -202,
- "message": "<Config: OTP_EXPIRED>",
- "data": {}
- }
- // Không tìm thấy người dùng
- {
- "errorCode": -300,
- "message": "<Config: USER_NOT_FOUND>",
- "data": {}
- }
- // Lỗi hệ thống
- {
- "errorCode": -6,
- "message": "<Config: SYSTEM_FAILURE>",
- "data": {}
- }
- ```
- ### Response Fields
- | Field | Type | Description |
- |-------|------|-------------|
- | errorCode| int | 0 = Success, khác 0 = Error (xem Error Codes) |
- | message | string | Thông báo từ CONFIG table (theo ngôn ngữ) |
- | data.userId | int | ID người dùng |
- | data.email | string | Email người dùng |
- | data.fullName | string | Họ tên đầy đủ |
- | data.avatarUrl | string | URL ảnh đại diện (nullable) |
- | data.accessToken | string | JWT access token |
- | data.refreshToken | string | Refresh token để làm mới access token |
- | data.expiresAt | datetime | Thời điểm access token hết hạn |
- ### Notes
- - Access token có hiệu lực 24 giờ
- - Refresh token có hiệu lực 30 ngày
- - Mỗi lần đăng nhập thành công, các token cũ sẽ bị thu hồi
- ---
- ## Error Codes
- ### Success
- | errorCode| Constant | Description |
- |------|----------|-------------|
- | 0 | Success | Thành công (mọi request thành công đều trả về 0) |
- ### General Errors (-1 to -99)
- | errorCode| Constant | Description |
- |------|----------|-------------|
- | -1 | Error | Lỗi chung |
- | -6 | SystemError | Lỗi hệ thống |
- ### OTP Errors (-200 to -299)
- | errorCode| Constant | Description |
- |------|----------|-------------|
- | -200 | OtpRequired | Yêu cầu OTP |
- | -201 | OtpInvalid | OTP không hợp lệ |
- | -202 | OtpExpired | OTP đã hết hạn |
- | -203 | OtpAlreadyUsed | OTP đã được sử dụng |
- | -204 | OtpMaxAttemptsExceeded | Vượt quá số lần thử |
- | -205 | OtpSendFailed | Gửi OTP thất bại |
- | -206 | OtpTooManyRequests | Request quá nhiều |
- ### User Errors (-300 to -399)
- | errorCode| Constant | Description |
- |------|----------|-------------|
- | -300 | UserNotFound | Không tìm thấy người dùng |
- | -304 | InvalidEmail | Email không hợp lệ |
- ### Validation Errors (-800 to -899)
- | errorCode| Constant | Description |
- |------|----------|-------------|
- | -801 | RequiredFieldMissing | Thiếu trường bắt buộc |
- ---
- ## Authentication
- 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:
- ```
- Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
- ```
- ---
- ## Flow Diagram
- ```
- ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
- │ Client │ │ API │ │ Email │
- └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
- │ │ │
- │ POST /request-otp │ │
- │──────────────────>│ │
- │ │ │
- │ │ Generate OTP │
- │ │ Save to DB │
- │ │ Queue Email │
- │ │ │
- │ Response │ │
- │<──────────────────│ │
- │ │ │
- │ │ Send OTP Email │
- │ │──────────────────>│
- │ │ │
- │ │ │ OTP Email
- │<──────────────────────────────────────│
- │ │ │
- │ POST /verify-otp │ │
- │──────────────────>│ │
- │ │ │
- │ │ Verify OTP │
- │ │ Generate JWT │
- │ │ │
- │ Token Response │ │
- │<──────────────────│ │
- │ │ │
- ```
- ---
- ## Example Usage (cURL)
- ### Request OTP
- ```bash
- curl -X POST https://api.esimlao.com/apis/auth/request-otp \
- -H "Content-Type: application/json" \
- -d '{
- "email": "user@example.com",
- "lang": "vi"
- }'
- ```
- ### Verify OTP
- ```bash
- curl -X POST https://api.esimlao.com/apis/auth/verify-otp \
- -H "Content-Type: application/json" \
- -d '{
- "email": "user@example.com",
- "otpCode": "123456"
- }'
- ```
- ### Use Token
- ```bash
- curl -X GET https://api.esimlao.com/apis/user/profile \
- -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
- ```
- ---
- ## 3. Article Category
- Lấy danh sách danh mục bài viết.
- ### Endpoint
- ```
- POST /apis/auth/article-category-load
- ```
- ### Request
- ```json
- {
- "lang": "lo",
- "pageNumber": 0,
- "pageSize": 10,
- "parentId": null
- }
- ```
- | Field | Type | Default | Description |
- |-------|------|---------|-------------|
- | lang | string | "lo" | Ngôn ngữ: "lo", "en" (có thể truyền qua header Accept-Language) |
- | pageNumber | int | 0 | Trang hiện tại |
- | pageSize | int | 10 | Số item mỗi trang |
- | parentId | int? | null | ID danh mục cha (null = root) |
- ### Response Success
- ```json
- {
- "errorCode": 0,
- "message": "Success",
- "data": {
- "items": [
- {
- "id": 1,
- "categoryName": "Cẩm nang du lịch",
- "categorySlug": "cam-nang-du-lich",
- "description": "Mô tả...",
- "iconUrl": "/icons/travel.png",
- "parentId": null,
- "displayOrder": 1
- }
- ],
- "pagination": {
- "pageNumber": 0,
- "pageSize": 10,
- "totalCount": 5,
- "totalPages": 1
- }
- }
- }
- ```
- ---
- ## 4. Article Load
- Lấy danh sách bài viết hoặc chi tiết 1 bài viết.
- ### Endpoint
- ```
- POST /apis/auth/article-load
- ```
- ### Request (danh sách)
- ```json
- {
- "lang": "lo",
- "pageNumber": 0,
- "pageSize": 10,
- "categoryId": 1,
- "isFeatured": false
- }
- ```
- ### Request (chi tiết)
- ```json
- {
- "lang": "lo",
- "slug": "huong-dan-cai-dat-esim"
- }
- ```
- | Field | Type | Default | Description |
- |-------|------|---------|-------------|
- | lang | string | "lo" | Ngôn ngữ (hoặc header Accept-Language) |
- | pageNumber | int | 0 | Trang hiện tại |
- | pageSize | int | 10 | Số item mỗi trang |
- | categoryId | int? | null | Lọc theo danh mục |
- | isFeatured | bool? | null | Lọc bài viết nổi bật |
- | slug | string? | null | Slug để lấy chi tiết bài viết |
- ### Response Success (danh sách)
- ```json
- {
- "errorCode": 0,
- "message": "Success",
- "data": {
- "items": [
- {
- "id": 1,
- "title": "Hướng dẫn cài đặt eSIM",
- "slug": "huong-dan-cai-dat-esim",
- "summary": "Tóm tắt...",
- "thumbnailUrl": "/images/article1.jpg",
- "categoryId": 1,
- "viewCount": 150,
- "isFeatured": true,
- "isPinned": false,
- "publishedDate": "2024-12-25"
- }
- ],
- "pagination": {...}
- }
- }
- ```
- ### Response Success (chi tiết)
- ```json
- {
- "errorCode": 0,
- "message": "Success",
- "data": {
- "article": {
- "id": 1,
- "title": "Hướng dẫn cài đặt eSIM",
- "slug": "huong-dan-cai-dat-esim",
- "summary": "Tóm tắt...",
- "content": "<p>Nội dung HTML...</p>",
- "thumbnailUrl": "/images/article1.jpg",
- "coverImageUrl": "/images/cover1.jpg",
- "metaDescription": "SEO description",
- "metaKeywords": "esim, laos",
- "categoryId": 1,
- "viewCount": 151,
- "isFeatured": true,
- "publishedDate": "2024-12-25",
- "createdDate": "2024-12-20"
- }
- }
- }
- ```
- ---
- ## 5. Banner Load
- Lấy danh sách banner.
- ### Endpoint
- ```
- POST /apis/content/banner
- ```
- ### Request
- ```json
- {
- "lang": "lo",
- "pageNumber": 0,
- "pageSize": 10,
- "position": "home"
- }
- ```
- | Field | Type | Default | Description |
- |-------|------|---------|-------------|
- | lang | string | "lo" | Ngôn ngữ (hoặc header Accept-Language) |
- | pageNumber | int | 0 | Trang hiện tại |
- | pageSize | int | 10 | Số item mỗi trang |
- | position | string? | null | Vị trí: "home", "sidebar"... |
- ### Response
- ```json
- {
- "errorCode": 0,
- "data": {
- "items": [
- {
- "id": 1,
- "title": "Banner Title",
- "subtitle": "Subtitle",
- "imageUrl": "/images/banner1.jpg",
- "imageMobileUrl": "/images/banner1_m.jpg",
- "linkUrl": "/promo",
- "linkTarget": "_blank",
- "position": "home",
- "displayOrder": 1
- }
- ],
- "pagination": {...}
- }
- }
- ```
- ---
- ## 6. Customer Review Load
- Lấy đánh giá của khách hàng.
- ### Endpoint
- ```
- POST /apis/content/review
- ```
- ### Request
- ```json
- {
- "lang": "lo",
- "pageNumber": 0,
- "pageSize": 10,
- "isFeatured": true
- }
- ```
- | Field | Type | Default | Description |
- |-------|------|---------|-------------|
- | lang | string | "lo" | Ngôn ngữ |
- | pageNumber | int | 0 | Trang |
- | pageSize | int | 10 | Số item |
- | isFeatured | bool? | null | Lọc review nổi bật |
- ### Response
- ```json
- {
- "errorCode": 0,
- "data": {
- "items": [
- {
- "id": 1,
- "customerName": "Nguyen Van A",
- "avatarUrl": "/avatars/user1.jpg",
- "rating": true,
- "reviewContent": "Dich vu rat tot...",
- "destination": "Vientiane, Laos",
- "isFeatured": true,
- "createdDate": "2024-12-25"
- }
- ],
- "pagination": {...}
- }
- }
- ```
- ---
- ## 6.1 Customer Review Create
- Khách hàng gửi đánh giá (chờ duyệt).
- ### Endpoint
- ```
- POST /apis/content/review/create
- ```
- ### Request
- ```json
- {
- "lang": "lo",
- "customerName": "Nguyen Van A",
- "reviewContent": "Dich vu rat tot, toi rat hai long!",
- "destination": "Vientiane, Laos",
- "rating": 5
- }
- ```
- | Field | Type | Required | Description |
- |-------|------|----------|-------------|
- | lang | string | No | Ngôn ngữ |
- | customerName | string | Yes | Tên khách hàng |
- | reviewContent | string | Yes | Nội dung đánh giá |
- | destination | string | No | Địa điểm |
- | rating | int | No | Đánh giá (1-5) |
- ### Response Success
- ```json
- {
- "errorCode": 0,
- "message": "Review submitted successfully",
- "data": {
- "reviewId": 123
- }
- }
- ```
- ### Note
- - Review mới sẽ có `Status = false` (chờ admin duyệt)
- ---
- ## 7. FAQ Category Load
- Lấy danh mục FAQ.
- ### Endpoint
- ```
- POST /apis/content/faq-category
- ```
- ### Request
- ```json
- {
- "lang": "lo",
- "pageNumber": 0,
- "pageSize": 10
- }
- ```
- ### Response
- ```json
- {
- "errorCode": 0,
- "data": {
- "items": [
- {
- "id": 1,
- "categoryName": "Cài đặt eSIM",
- "categorySlug": "cai-dat-esim",
- "description": "Hướng dẫn cài đặt",
- "iconUrl": "/icons/setup.png",
- "displayOrder": 1
- }
- ],
- "pagination": {...}
- }
- }
- ```
- ---
- ## 8. FAQ Load
- Lấy danh sách câu hỏi thường gặp.
- ### Endpoint
- ```
- POST /apis/content/faq
- ```
- ### Request
- ```json
- {
- "lang": "lo",
- "pageNumber": 0,
- "pageSize": 10,
- "categoryId": 1,
- "isFeatured": false
- }
- ```
- | Field | Type | Default | Description |
- |-------|------|---------|-------------|
- | lang | string | "lo" | Ngôn ngữ |
- | pageNumber | int | 0 | Trang |
- | pageSize | int | 10 | Số item |
- | categoryId | int? | null | Lọc theo danh mục |
- | isFeatured | bool? | null | Lọc FAQ nổi bật |
- ### Response
- ```json
- {
- "errorCode": 0,
- "data": {
- "items": [
- {
- "id": 1,
- "question": "Làm sao để cài đặt eSIM?",
- "answer": "<p>Hướng dẫn chi tiết...</p>",
- "categoryId": 1,
- "viewCount": 100,
- "isFeatured": true
- }
- ],
- "pagination": {...}
- }
- }
- ```
|