服務市場 商家 API
第一期:商品與入庫

商家 API:把 SKU、採購預報與深圳倉庫存接進你的系統

給在蝦皮、酷澎、momo 開店的公司行號。上架時產生的商品條碼用 API 傳進來,採購時預報快遞單號與內容物,貨到深圳倉就自動開工單、貼碼、逐件掃描上架,庫存與差異即時回傳。

公司行號

開放對象(需 8 碼統編)

200 筆

SKU 單次批量上限

WO-SK

入倉自動開貼碼工單

60 次/分

每把金鑰預設限流

1 服務概覽

第一期提供「商品與入庫」:從建立 SKU 到貨物在深圳倉上架成庫存。

目前可以做的事

  • 批量建立或更新 SKU(以你的 seller_sku 為準),每個顏色、尺碼各自一組商品條碼,並綁定蝦皮/酷澎/momo 的商品規格編號。
  • 依 11 碼稅則號列自動比對輸入規定,標出需要商品檢驗、許可或不能進口的商品。
  • 採購時預報快遞單號與每箱內容物;貨到深圳倉自動開 WO-SK 貼碼工單,倉庫逐件貼碼、掃描上架。
  • 查詢分倉庫存與庫存流水,並用 webhook 即時收到到倉、入庫完成、數量差異與庫存變動。

入庫流程

  1. 建立 SKU:傳入商品條碼、規格、申報品名、稅則號列。
  2. 預報入庫:傳入快遞單號與每個 SKU 的預報數量。
  3. 深圳倉入倉:掃快遞單號後自動開 WO-SK 工單並列印。
  4. 貼碼上架:倉庫列印商品條碼、逐件貼上並掃描計數。
  5. 完成入庫:實收進入深圳倉庫存,破損另計,差異通知你的系統。
關於進口規定:系統依關務署稅則資料的輸入規定代號自動判定,僅供作業參考;商品實際是否需要檢驗、許可或正式報關,以海關及合作報關行審核為準。商家備貨屬於銷售用途,不適用個人自用的免證額度。

規劃中的功能

批量出貨訂單、依申報規定自動歸組的出貨批次,以及桃園倉前置庫存、分揀與平台面單。上線時會在本頁公布。

2 申請與金鑰

商家 API 只開放公司行號,每把金鑰都綁定一個已核准的商家帳號。

開通步驟

  1. 在會員中心新增「公司」申報人,填寫 8 碼統一編號。
  2. 聯繫好運器客服申請開通商家 API,審核通過後會核發金鑰。
  3. 金鑰只會顯示一次,請保存在伺服器端的環境變數,不要放進瀏覽器或 App。
  4. 需要 webhook 時,先到會員中心的 API 頁面設定並驗證網址,再訂閱商家事件。
所有請求都用 Authorization: Bearer <金鑰>。一般會員登入 App 或網頁產生的權杖不能呼叫商家 API。
Authorization: Bearer 12|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

3 共通規範

所有端點共用以下規則。

Base URL

https://0523.tw/api/v1/merchant

格式與語言

請求與回應都是 JSON。錯誤訊息預設為繁體中文,帶 Accept-Language: en 回英文;程式判斷請一律使用固定英文的 error.code

回應結構

成功回 {"success": true, "data": …, "meta": …};失敗回 {"success": false, "error": {"code", "message", "errors", "context"}}errors 是逐欄明細。唯一例外是沒帶或帶了無效金鑰:HTTP 401,body 為 {"message": "Unauthenticated."}

{
  "success": false,
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "…",
    "errors": [
      { "code": "TRACKING_IN_USE", "field": "packages.0.tracking_no", "message": "…" }
    ]
  }
}

限流

每把金鑰每分鐘 60 次、每日 5,000 次(高用量方案每分鐘 300 次、每日 50,000 次),批量端點一次算一次。需要即時資料請訂閱 webhook,不要輪詢。

回應標頭說明
X-RateLimit-Limit每分鐘上限
X-RateLimit-Remaining本分鐘剩餘次數
X-RateLimit-Limit-Day
X-RateLimit-Remaining-Day
每日上限與剩餘次數
Retry-After超過上限時,幾秒後可以重試

冪等(Idempotency-Key)

寫入請求可帶 Idempotency-Key 標頭(8–128 字元,英數與 _-:.)。網路逾時後用同一把 key、同一份內容重送,會拿到第一次的回應,標頭 Idempotent-Replayed: true;同一把 key 換了內容回 422。紀錄保留 24 小時。

批量回應

批量端點逐筆回報結果:全部成功回 200、部分失敗回 207、全部失敗回 422。每一筆都有 indexstatus(created/updated/failed)與失敗原因。

識別碼字元

seller_sku 只能用英數與 ._-(1–64 字元);商品條碼另可用 /+(3–64 字元)。大小寫視為相同。

4 商品 SKU

SKU 以你的 seller_sku 為唯一鍵:同一個 seller_sku 重送就是更新,只會修改有帶的欄位。

批量建立或更新 SKU

POST/api/v1/merchant/skus/batch

一次最多 200 筆,每一筆獨立處理,一筆失敗不影響其他筆。

欄位型別必填說明
seller_skustring必填你的 SKU 編號,例如蝦皮的商品選項貨號。
product_namestring新建必填商品名稱。同名的 SKU 會歸在同一個商品底下。
barcodestring選填商品條碼,倉庫會照這個碼印標籤並掃描上架。不同顏色、尺碼必須不同;沒有條碼可以不填,系統會產生系統條碼。超過 16 字元時標籤改印系統條碼。
gtinstring選填國際條碼(8/12/13/14 碼,會驗證檢查碼)。蝦皮「商品無國際條碼」傳 00
specobject選填規格,例如 {"color": "黑", "size": "M"},最多 5 項。
declared_name_zh
declared_name_en
string選填申報品名(中文/英文),請寫材質與用途,不要寫「樣品」「禮物」。
declared_unit_valuenumber選填申報單價,是你向供應商的採購單價,不是平台售價。
declared_currencystring選填CNYTWDUSD,填了單價就必填。
hs_codestring選填11 碼貨品分類號列,系統依此比對輸入規定。
origin_countrystring選填原產地 ISO 代碼,預設 CN
weight_ginteger選填單件重量(公克)。
dimensions_cmarray選填長、寬、高(公分),例如 [20, 15, 3]
battery_typestring選填nonecontained(內建)、packed(隨附)、standalone(單獨電池)。
channelsarray選填平台商品對應,最多 20 組:platform(shopee/coupang/momo/other)、shop_iditem_idmodel_idplatform_sku

請求範例 (POST JSON)

curl -X POST https://0523.tw/api/v1/merchant/skus/batch \
  -H "Authorization: Bearer $LUCKY_MERCHANT_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: sku-sync-20260917-001" \
  -d '{
  "items": [
    {
      "seller_sku": "TEE-RED-S",
      "barcode": "4710000000011",
      "product_name": "Cotton T-shirt",
      "spec": { "color": "red", "size": "S" },
      "declared_name_en": "Cotton knitted T-shirt",
      "declared_unit_value": 18.5,
      "declared_currency": "CNY",
      "hs_code": "61091000006",
      "weight_g": 160,
      "channels": [ { "platform": "shopee", "shop_id": "123456", "item_id": "2233", "model_id": "445566" } ]
    }
  ]
}'

回應 200

{
  "success": true,
  "data": [
    {
      "index": 0,
      "seller_sku": "TEE-RED-S",
      "status": "created",
      "sku": {
        "seller_sku": "TEE-RED-S",
        "barcode": "4710000000011",
        "system_barcode": null,
        "pick_code": "131999",
        "hs_code": "61091000006",
        "regulation": { "status": "ok", "import_codes": [], "reasons": [] },
        "channels": [ { "platform": "shopee", "shop_id": "123456", "item_id": "2233", "model_id": "445566", "platform_sku": null } ]
      }
    }
  ],
  "meta": { "summary": { "created": 1, "updated": 0, "failed": 0 } }
}

輸入規定判定(regulation.status)

ok沒有輸入規定代號。
review_required規定只涵蓋部分商品(例如 C02「本項下部分商品屬應施檢驗」),要依商品實際用途確認。
formal_required涉及輸入規定(檢驗、檢疫、許可等),不能用簡易申報。
blocked大陸物品不准輸入(MW0,原產地為中國大陸),不能預報入庫。
unclassified還沒提供稅則號列,無法判定。

查詢 SKU

GET/api/v1/merchant/skus

可用 seller_skubarcoderegulation_statusupdated_since(ISO 8601)篩選,pageper_page(最多 100)分頁。

單一 SKU

GET/api/v1/merchant/skus/{seller_sku}

更新平台商品對應

PUT/api/v1/merchant/skus/{seller_sku}/channels

以傳入的清單整批取代原本的對應;同一組平台規格不能同時綁兩個 SKU。

下載商品條碼標籤

GET/api/v1/merchant/skus/{seller_sku}/label.pdf?qty=10

回傳 40×30mm 標籤 PDF,qty 為張數(1–1000)。深圳倉貼碼時印的是同一種標籤;這支供你想在出貨前自行貼碼時使用。

5 入庫預報

採購出貨後,把快遞單號與內容物預報進來。一張入庫單可以有多個快遞單號,每個單號底下列 SKU 與數量。

建立入庫單

POST/api/v1/merchant/inbound-orders

整張驗證:任一錯誤都不會建立。同一個快遞單號同時只能屬於一張進行中的入庫單;同一個包裹內重複的 SKU 會合併數量。

欄位型別必填說明
reference_nostring必填你的採購單號或入庫單號,同一商家內唯一(英數與 ._-/)。
supplier_order_nostring選填供應商訂單號,例如 1688 訂單編號。
warehouse_codestring選填入庫倉,目前只收 SZ(深圳倉)。
notesstring選填備註(最多 1,000 字)。
packagesarray必填快遞包裹清單,最多 50 個。
packages[].tracking_nostring必填中國快遞單號。
packages[].carrierstring選填快遞公司代碼,例如 ytosf
packages[].itemsarray必填包裹內容物:seller_skuqty,整張入庫單合計最多 500 行。

請求範例 (POST JSON)

curl -X POST https://0523.tw/api/v1/merchant/inbound-orders \
  -H "Authorization: Bearer $LUCKY_MERCHANT_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: po-20260917-0001" \
  -d '{
  "reference_no": "PO-20260917-0001",
  "supplier_order_no": "1688-3312456789",
  "packages": [
    {
      "tracking_no": "YT1234567890123",
      "carrier": "yto",
      "items": [
        { "seller_sku": "TEE-RED-S", "qty": 40 },
        { "seller_sku": "TEE-RED-M", "qty": 60 }
      ]
    }
  ]
}'
重送保護:同一個 reference_no 再建立一次會回 409 INBOUND_REFERENCE_EXISTSerror.context.inbound_order_id 帶原本的入庫單 id。要安全重試請帶 Idempotency-Key

入庫單狀態

created已預報,包裹都還沒到倉。
partially_arrived部分包裹已到深圳倉。
arrived所有包裹都已到倉,貼碼上架中。
completed全部上架完成,數量與預報相同。
completed_with_discrepancy全部完成,但有短收、超收或破損。
cancelled已取消。

包裹狀態

awaiting_arrival等待到倉。
labeling已入倉,工單已開,貼碼上架中。
received上架完成。
mismatch入倉時的包裹歸屬與你的預報對不上,客服核對中。
cancelled已取消或作廢,快遞單號已釋出。

查詢入庫單

GET/api/v1/merchant/inbound-orders

GET/api/v1/merchant/inbound-orders/{id}

可用 statusreference_noupdated_since 篩選。每個包裹會回傳預報、實收、破損數量與差異。

取消入庫單

POST/api/v1/merchant/inbound-orders/{id}/cancel

只有包裹都還沒到倉時可以取消;取消後快遞單號可以重新預報。

6 庫存查詢

庫存按倉別分開:SZ 深圳倉、TY 桃園倉(桃園倉庫存隨出貨功能開放)。

查詢庫存

GET/api/v1/merchant/inventory?warehouse_code=SZ

可用 warehouse_codeseller_sku[](最多 200 個)篩選。

on_hand在庫數量。
reserved已被訂單保留的數量。
available可用數量=在庫-保留。
damaged破損數量,不可出貨。

回應 200

{
  "success": true,
  "data": [
    { "seller_sku": "TEE-RED-S", "barcode": "4710000000011", "warehouse_code": "SZ",
      "on_hand": 38, "reserved": 0, "available": 38, "damaged": 2, "updated_at": "2026-09-17T15:20:11+08:00" }
  ],
  "meta": { "total": 1, "page": 1, "per_page": 100, "last_page": 1 }
}

庫存流水

GET/api/v1/merchant/inventory/movements?after_id=0&limit=200

只增不改的異動紀錄,用 after_id 游標往後翻頁(每次最多 500 筆),記住回應的 meta.next_after_id 即可續抓對帳。

7 Webhook 事件

事件發生時主動推送到你的網址,不必輪詢。

設定方式

  1. 到會員中心 API 頁面設定 webhook 網址(僅接受 https),完成擁有權驗證:你的端點要回 HTTP 200,body 為 {"challenge": "收到的值"}
  2. 呼叫 PUT /api/v1/merchant/webhook/events 訂閱商家事件。之後在會員中心改網址不會清掉商家事件的訂閱。
curl -X PUT https://0523.tw/api/v1/merchant/webhook/events \
  -H "Authorization: Bearer $LUCKY_MERCHANT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"events": ["inbound.arrived", "inbound.received", "inbound.discrepancy", "inventory.changed"]}'

事件清單

sku.regulation_flaggedSKU 的輸入規定判定變成需要確認、需要正式報關或不准輸入。
inbound.arrived包裹到深圳倉,工單已開。
inbound.mismatch包裹入倉時的歸屬與預報對不上,客服核對中。
inbound.received包裹上架完成,附每個 SKU 的預報、實收、破損數量。
inbound.discrepancy上架數量與預報不同或有破損(會與 inbound.received 同時送出)。
inventory.changed庫存有異動,附異動 SKU 的最新庫存。

inbound.received

{
  "event": "inbound.received",
  "delivery_id": "5b0f1c2e-8f3a-4d7e-9c21-0a6b2d4e8f10",
  "created_at": "2026-09-17T15:20:11+08:00",
  "data": {
    "inbound_order_id": 128,
    "reference_no": "PO-20260917-0001",
    "order_status": "completed_with_discrepancy",
    "tracking_no": "YT1234567890123",
    "work_order": "WO-SK-315",
    "warehouse_code": "SZ",
    "items": [
      { "seller_sku": "TEE-RED-S", "expected_qty": 40, "received_qty": 38, "damaged_qty": 2, "difference": 0 },
      { "seller_sku": "TEE-RED-M", "expected_qty": 60, "received_qty": 59, "damaged_qty": 0, "difference": -1 }
    ],
    "received_at": "2026-09-17T15:20:10+08:00"
  }
}

驗證簽章

每次推送都帶 X-Lucky-EventX-Lucky-Delivery-IdX-Lucky-Signature: t=時間戳,v1=簽章。以你的 webhook secret 對「時間戳 + . + 原始 body」做 HMAC-SHA256,比對 v1,並拒絕超過 5 分鐘的時間戳。同一事件重試時 delivery_id 不變,可用來去重。

回應非 2xx 會在 1 分鐘、5 分鐘、30 分鐘、2 小時、6 小時後重試;連續失敗 20 次會自動停用,需到會員中心重新設定。

// PHP
$body   = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_LUCKY_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $header), $sig);   // ['t' => '1789…', 'v1' => 'ab12…']

$expected = hash_hmac('sha256', ($sig['t'] ?? '') . '.' . $body, getenv('LUCKY_WEBHOOK_SECRET'));

if (! hash_equals($expected, $sig['v1'] ?? '') || abs(time() - (int) ($sig['t'] ?? 0)) > 300) {
    http_response_code(400);
    exit;
}
$event = json_decode($body, true);   // de-duplicate by $event['delivery_id']
http_response_code(200);

8 錯誤碼

error.code 固定為英文,下列是常見錯誤。

HTTPerror.code說明
401沒有帶金鑰、金鑰無效或已過期(body 為 {"message": "Unauthenticated."})。
403MERCHANT_TOKEN_REQUIRED這把權杖沒有商家 API 權限(例如一般會員登入產生的權杖)。
403MERCHANT_NOT_APPROVED
MERCHANT_SUSPENDED
帳號尚未核准為商家,或商家已暫停。
403APP_SUSPENDED
APP_REVOKED
APP_NOT_FOUND
金鑰對應的 API 應用已停權或撤銷。
422VALIDATION_FAILED
PRODUCT_NAME_REQUIRED
資料格式錯誤,請看 error.errors 的逐欄明細。
422BATCH_TOO_LARGE批量筆數超過上限。
207 / 409SKU_BARCODE_DUPLICATE
SKU_BARCODE_CONFLICT
商品條碼已被另一個 SKU 使用,或與另一個 SKU 的系統條碼、揀貨碼相同。
207 / 422GTIN_INVALID
HS_CODE_NOT_FOUND
國際條碼檢查碼錯誤,或稅則號列不存在。
404 / 422SKU_NOT_FOUND
SKU_IMPORT_BLOCKED
找不到 SKU,或 SKU 屬不准輸入商品不能預報。
409INBOUND_REFERENCE_EXISTS入庫單參考編號已存在。
422TRACKING_IN_USE
TRACKING_FORECASTED_BY_OTHER
TRACKING_ALREADY_WAREHOUSED
TRACKING_NOT_AVAILABLE
快遞單號已在進行中的入庫單、已被其他會員預報或已入倉在其他會員名下。
409INBOUND_NOT_CANCELLABLE已有包裹到倉,入庫單不能取消。
400 / 409 / 422IDEMPOTENCY_KEY_INVALID
IDEMPOTENCY_IN_PROGRESS
IDEMPOTENCY_KEY_REUSED
Idempotency-Key 格式錯誤、被用於不同內容,或上一個請求還在處理中。
409CONFLICT_RETRY同一筆資料正被另一個請求修改,請稍後重送。
429RATE_LIMIT_EXCEEDED超過限流,依 Retry-After 等待後重試。

9 程式範例

以下範例請在伺服器端執行,不要把金鑰放進前端程式。

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

$api = Http::withToken(config('services.lucky.merchant_key'))
    ->acceptJson()
    ->baseUrl('https://0523.tw/api/v1/merchant')
    ->timeout(20);

// 1) Sync SKUs (up to 200 per request)
$res = $api->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
    ->post('/skus/batch', ['items' => $items]);

foreach ($res->json('data') as $row) {
    if ($row['status'] === 'failed') {
        logger()->warning('SKU failed', $row['errors']);
    }
}

// 2) Forecast an inbound order
$order = $api->withHeaders(['Idempotency-Key' => 'po-' . $po->id])
    ->post('/inbound-orders', [
        'reference_no' => $po->number,
        'packages'     => [[
            'tracking_no' => $po->tracking_no,
            'items'       => [['seller_sku' => 'TEE-RED-S', 'qty' => 40]],
        ]],
    ])->throw()->json('data');

// 3) Read Shenzhen stock
$stock = $api->get('/inventory', ['warehouse_code' => 'SZ'])->json('data');

10 技術支援

串接過程有任何問題,請提供請求時間、端點與 error.code,方便我們協助排查。

LINE 官方帳號 @0523tw

技術信箱 howyunqisoftware@gmail.com

版本 v1 第一期(2026-09-17):商品 SKU、入庫預報、深圳倉貼碼上架、庫存查詢、webhook。

聯繫客服開通