161 lines
5.4 KiB
Markdown
161 lines
5.4 KiB
Markdown
|
|
# 第三方系統 API 對接手冊
|
|||
|
|
|
|||
|
|
Star ERP 系統提供外部整合 API (Integration API) 供電商前台、POS 機或其他第三方系統串接。
|
|||
|
|
所有的整合 API 均受到 Laravel Sanctum Token 與多租戶 (Multi-tenant) Middleware 保護。
|
|||
|
|
|
|||
|
|
## 基礎連線資訊
|
|||
|
|
|
|||
|
|
- **API Base URL**: `https://[租戶網域]/api/v1/integration` (依實際部署網址為準,單機開發為 `http://localhost/api/v1/integration`)
|
|||
|
|
- **Headers 要求**:
|
|||
|
|
- `Accept: application/json`
|
|||
|
|
- `Content-Type: application/json`
|
|||
|
|
- `Authorization: Bearer {YOUR_API_TOKEN}` (由 ERP 系統管理員核發的 Sanctum Token)
|
|||
|
|
- **速率限制**:每位使用者每分鐘最多 60 次請求。超過時會回傳 `429 Too Many Requests`。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 產品資料同步 (Upsert Product)
|
|||
|
|
|
|||
|
|
此 API 用於將第三方系統(如 POS)的產品資料單向同步至 ERP。採用 Upsert 邏輯:若 `external_pos_id` 存在則更新資料,不存在則新增產品。
|
|||
|
|
|
|||
|
|
- **Endpoint**: `/products/upsert`
|
|||
|
|
- **Method**: `POST`
|
|||
|
|
|
|||
|
|
### Request Body (JSON)
|
|||
|
|
|
|||
|
|
| 欄位名稱 | 型態 | 必填 | 說明 |
|
|||
|
|
| :--- | :--- | :---: | :--- |
|
|||
|
|
| `external_pos_id` | String | **是** | 第三方系統中的唯一產品 ID,ERP 會依此 ID 判斷是否為同一商品 |
|
|||
|
|
| `name` | String | **是** | 產品名稱 |
|
|||
|
|
| `price` | Number | 否 | 產品售價 |
|
|||
|
|
| `barcode` | String | 否 | 產品條碼 |
|
|||
|
|
| `category` | String | 否 | 產品分類名稱 |
|
|||
|
|
| `unit` | String | 否 | 單位 (例如: 個, 瓶, 箱) |
|
|||
|
|
| `updated_at` | String(Date) | 否 | 第三方系統的最後更新時間 (格式: YYYY-MM-DD HH:mm:ss) |
|
|||
|
|
|
|||
|
|
**請求範例:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"external_pos_id": "POS-ITEM-001",
|
|||
|
|
"name": "特級冷壓初榨橄欖油",
|
|||
|
|
"price": 450,
|
|||
|
|
"barcode": "4711234567890",
|
|||
|
|
"category": "調味料",
|
|||
|
|
"unit": "瓶"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Response
|
|||
|
|
|
|||
|
|
**Success (HTTP 200)**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"message": "Product synced successfully",
|
|||
|
|
"data": {
|
|||
|
|
"id": 15,
|
|||
|
|
"external_pos_id": "POS-ITEM-001"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 訂單資料寫入與扣庫 (Create Order)
|
|||
|
|
|
|||
|
|
此 API 用於讓第三方系統(如 POS 結帳後)將「已成交」的訂單推送到 ERP。
|
|||
|
|
**重要提醒**:寫入訂單的同時,ERP 會自動且**強制**扣除對應倉庫的庫存(允許扣至負數,以利後續盤點或補單)。
|
|||
|
|
|
|||
|
|
- **Endpoint**: `/orders`
|
|||
|
|
- **Method**: `POST`
|
|||
|
|
|
|||
|
|
### Request Body (JSON)
|
|||
|
|
|
|||
|
|
| 欄位名稱 | 型態 | 必填 | 說明 |
|
|||
|
|
| :--- | :--- | :---: | :--- |
|
|||
|
|
| `external_order_id` | String | **是** | 第三方系統中的唯一訂單編號,不可重複 (Unique) |
|
|||
|
|
| `warehouse_id` | Integer | 否 | 指定出貨倉庫的系統 ID (若已知) |
|
|||
|
|
| `warehouse` | String | 否 | 指定出貨倉庫名稱。若 `warehouse_id` 與此欄皆未傳,系統將預設寫入並建立「銷售倉庫」 |
|
|||
|
|
| `payment_method` | String | 否 | 付款方式,僅接受:`cash`, `credit_card`, `line_pay`, `ecpay`, `transfer`, `other`。預設為 `cash` |
|
|||
|
|
| `sold_at` | String(Date) | 否 | 交易發生時間,預設為當下時間 (格式: YYYY-MM-DD HH:mm:ss) |
|
|||
|
|
| `items` | Array | **是** | 訂單明細陣列,至少需包含一筆商品 |
|
|||
|
|
|
|||
|
|
#### `items` 陣列欄位說明:
|
|||
|
|
|
|||
|
|
| 欄位名稱 | 型態 | 必填 | 說明 |
|
|||
|
|
| :--- | :--- | :---: | :--- |
|
|||
|
|
| `pos_product_id` | String | **是** | 對應產品的 `external_pos_id`。**注意:商品必須先透過產品同步 API 建立至 ERP 中。** |
|
|||
|
|
| `qty` | Number | **是** | 銷售數量 (必須 > 0) |
|
|||
|
|
| `price` | Number | **是** | 銷售單價 |
|
|||
|
|
|
|||
|
|
**請求範例:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"external_order_id": "ORD-20231026-0001",
|
|||
|
|
"warehouse": "台北大安門市",
|
|||
|
|
"payment_method": "credit_card",
|
|||
|
|
"sold_at": "2023-10-26 14:30:00",
|
|||
|
|
"items": [
|
|||
|
|
{
|
|||
|
|
"pos_product_id": "POS-ITEM-001",
|
|||
|
|
"qty": 2,
|
|||
|
|
"price": 450
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"pos_product_id": "POS-ITEM-005",
|
|||
|
|
"qty": 1,
|
|||
|
|
"price": 120
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Response
|
|||
|
|
|
|||
|
|
**Success (HTTP 201)**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"message": "Order synced and stock deducted successfully",
|
|||
|
|
"order_id": 42
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Error: Product Not Found (HTTP 400)**
|
|||
|
|
若 `items` 內傳入了未曾同步過的 `pos_product_id`,會導致寫入失敗。
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"message": "Sync failed: Product not found for POS ID: POS-ITEM-999. Please sync product first."
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 幂等性說明 (Idempotency)
|
|||
|
|
|
|||
|
|
訂單 API 支援幂等性處理:若傳入已存在的 `external_order_id`,系統不會報錯,而是回傳該訂單的資訊:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"message": "Order already exists",
|
|||
|
|
"order_id": 42
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
這讓第三方系統在網路問題導致重送時,不會產生重複訂單或重複扣庫。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 常見問題與除錯 (FAQ)
|
|||
|
|
|
|||
|
|
1. **收到 `401 Unauthorized` 錯誤?**
|
|||
|
|
- 請檢查請求標頭 (Header) 是否有正確攜帶 `Authorization: Bearer {Token}`。
|
|||
|
|
- 確認該 Token 尚未過期或被撤銷。
|
|||
|
|
|
|||
|
|
2. **收到 `422 Unprocessable Entity` 錯誤?**
|
|||
|
|
- 代表傳送的 JSON 欄位不符合格式要求,例如必填欄位遺漏、數量為負數、或 `payment_method` 不在允許的值中。Laravel 會在回應的 `errors` 物件中詳細說明哪個欄位驗證失敗。
|
|||
|
|
|
|||
|
|
3. **收到 `429 Too Many Requests` 錯誤?**
|
|||
|
|
- 代表已超過速率限制(每分鐘 60 次),請稍後再試。
|
|||
|
|
|
|||
|
|
4. **庫存扣除邏輯**
|
|||
|
|
- POS 訂單寫入視為「已發生之事實」,系統會無條件扣除庫存。若該產品在指定倉庫原先庫存為 0,訂單寫入後庫存將變為負數,提醒門市人員需進行調撥補貨。
|