Files
star-erp/resources/markdown/manual/api-integration.md
sky121113 a05acd96dc feat(integration): 完善外部 API 對接邏輯與安全性
1. 新增 API Rate Limiting (每分鐘 60 次)
2. 實作 ProductServiceInterface 與 findOrCreateWarehouseByName 解決跨模組耦合問題
3. 強化 OrderSync API 驗證 (price 欄位限制最小 0、payment_method 加上允許白名單)
4. 實作 OrderSync API 冪等性處理,重複訂單直接回傳現有資訊
5. 修正 ProductSync API 同步邏輯,每次同步皆會更新產品分類與單位
6. 完善 integration API 對接手冊內容與 UI 排版
2026-02-23 10:10:03 +08:00

5.4 KiB
Raw Blame History

第三方系統 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 第三方系統中的唯一產品 IDERP 會依此 ID 判斷是否為同一商品
name String 產品名稱
price Number 產品售價
barcode String 產品條碼
category String 產品分類名稱
unit String 單位 (例如: 個, 瓶, 箱)
updated_at String(Date) 第三方系統的最後更新時間 (格式: YYYY-MM-DD HH:mm:ss)

請求範例:

{
    "external_pos_id": "POS-ITEM-001",
    "name": "特級冷壓初榨橄欖油",
    "price": 450,
    "barcode": "4711234567890",
    "category": "調味料",
    "unit": "瓶"
}

Response

Success (HTTP 200)

{
    "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 銷售單價

請求範例:

{
    "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)

{
    "message": "Order synced and stock deducted successfully",
    "order_id": 42
}

Error: Product Not Found (HTTP 400)items 內傳入了未曾同步過的 pos_product_id,會導致寫入失敗。

{
    "message": "Sync failed: Product not found for POS ID: POS-ITEM-999. Please sync product first."
}

幂等性說明 (Idempotency)

訂單 API 支援幂等性處理:若傳入已存在的 external_order_id,系統不會報錯,而是回傳該訂單的資訊:

{
    "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訂單寫入後庫存將變為負數提醒門市人員需進行調撥補貨。