1. 移除非必要之 Log 備註:從來店禮使用記錄 (Logs) 的電腦版與行動版畫面中,徹底移除了無業務參考價值的技術備註 (Remark) 欄位,優化排版空間以符合極簡奢華風 UI 設計。 2. 補齊與對齊三語系檔案:補齊來店禮、通行碼與商品領取所缺少的多語系 Key,三個語系 JSON 檔 (zh_TW, en, ja) 的 Key 與行數已 100% 完美對齊 (共 2,255 行) 且完成升冪字母排序 (ksort)。 3. 簡化 Guest 票券大標題:簡化 Guest 端三種票券頁面 (通行碼、取貨碼、來店禮) 的大標題多語系拼接結構,改為單一乾淨的翻譯 Key 呼叫。 4. 口語化翻譯微調:將 Pickup Code 在語系檔中的中文翻譯由「領取碼」微調為更口語、直覺的「取貨碼」。 5. 優化 Guest 頁面欄位:將取貨碼頁面的「機台序號」替換為更具溫度的「機台名稱」;通行碼與來店禮頁面則徹底隱藏機台序號,優化用戶體驗。
795 lines
44 KiB
PHP
795 lines
44 KiB
PHP
<?php
|
||
|
||
return [
|
||
'title' => 'Star Cloud IoT 通訊協議',
|
||
'version' => 'v1.0.0',
|
||
'description' => '此文件提供 Star Cloud 智能販賣機 IoT 端點通訊協議說明,包含主動拉取 (HTTP REST) 與被動接收 (MQTT) 雙軌通訊機制,供硬體端與前端開發者調研與串接使用。',
|
||
|
||
'http_apis' => [
|
||
[
|
||
'name' => '機台核心通訊 (IoT Core)',
|
||
'apis' => [
|
||
[
|
||
'name' => 'B000: 維運人員登入認證 (Technician Login)',
|
||
'slug' => 'b000-tech-login',
|
||
'method' => 'POST',
|
||
'path' => '/api/v1/app/admin/login/B000',
|
||
'description' => '維運人員輸入個人帳密進行認證。此 API 需帶入機台 API Token。驗證成功後核發臨時 User Token 供後續擴充使用。',
|
||
'headers' => [
|
||
'Content-Type' => 'application/json',
|
||
'Authorization' => 'Bearer <machine_api_token>',
|
||
],
|
||
'parameters' => [
|
||
'Su_Account' => [
|
||
'type' => 'string',
|
||
'required' => true,
|
||
'description' => '維運人員帳號 (username/email)',
|
||
'example' => 'admin_test'
|
||
],
|
||
'Su_Password' => [
|
||
'type' => 'string',
|
||
'required' => true,
|
||
'description' => '維運人員密碼',
|
||
'example' => 'password123'
|
||
],
|
||
'ip' => [
|
||
'type' => 'string',
|
||
'required' => false,
|
||
'description' => '機台本地 IP',
|
||
'example' => '192.168.1.100'
|
||
],
|
||
],
|
||
'response_parameters' => [
|
||
'success' => [
|
||
'type' => 'boolean',
|
||
'description' => '請求是否成功',
|
||
'example' => true
|
||
],
|
||
'code' => [
|
||
'type' => 'integer',
|
||
'description' => '業務狀態碼',
|
||
'example' => 200
|
||
],
|
||
'message' => [
|
||
'type' => 'string',
|
||
'description' => '回應訊息',
|
||
'example' => 'Success'
|
||
],
|
||
'token' => [
|
||
'type' => 'string',
|
||
'description' => '臨時身份認證 Token',
|
||
'example' => '1|abcdefg...'
|
||
],
|
||
],
|
||
'request' => [
|
||
'Su_Account' => 'admin_test',
|
||
'Su_Password' => 'password123',
|
||
'ip' => '192.168.1.100'
|
||
],
|
||
'response' => [
|
||
'success' => true,
|
||
'code' => 200,
|
||
'message' => 'Success',
|
||
'token' => '1|abcdefg...'
|
||
],
|
||
],
|
||
[
|
||
'name' => 'B014: 機台參數與金鑰下載 (Config Download)',
|
||
'slug' => 'b014-config-download',
|
||
'method' => 'GET',
|
||
'path' => '/api/v1/app/machine/setting/B014',
|
||
'description' => '透過此介面下載金流金鑰、電子發票設定與機台專屬通訊 Token。',
|
||
'headers' => [
|
||
'Content-Type' => 'application/json',
|
||
],
|
||
'parameters' => [
|
||
'machine' => [
|
||
'type' => 'string',
|
||
'required' => true,
|
||
'description' => '機台序號',
|
||
'example' => 'SN202604130001'
|
||
],
|
||
],
|
||
'response_parameters' => [
|
||
'success' => [
|
||
'type' => 'boolean',
|
||
'description' => '是否成功',
|
||
'example' => true
|
||
],
|
||
'data' => [
|
||
'type' => 'object',
|
||
'description' => '配置物件。包含:t050v01 (序號), api_token (通訊 Token), t050v41~43 (玉山設定), t050v34~38 (發票設定), TP_... (趨勢/手機支付設定)',
|
||
'example' => [
|
||
't050v01' => 'SN202604130001',
|
||
'api_token' => 'mac_token_...',
|
||
't050v41' => '80812345',
|
||
't050v34' => '2000132',
|
||
'TP_APP_ID' => 'GP_001'
|
||
]
|
||
],
|
||
],
|
||
'request' => [],
|
||
'response' => [
|
||
'success' => true,
|
||
'code' => 200,
|
||
'data' => [
|
||
't050v01' => 'SN202604130001',
|
||
'api_token' => 'mac_token_...',
|
||
't050v41' => '80812345',
|
||
't050v42' => '9001',
|
||
't050v43' => 'hash_key',
|
||
't050v34' => '2000132',
|
||
'TP_APP_ID' => 'GP_001'
|
||
]
|
||
],
|
||
'notes' => '此 API 為機台初始化引導用,目前不強制驗證 User Token。'
|
||
],
|
||
[
|
||
'name' => 'B005: 廣告清單同步 (Ad Sync)',
|
||
'slug' => 'b005-ad-sync',
|
||
'method' => 'GET',
|
||
'path' => '/api/v1/app/machine/ad/B005',
|
||
'description' => '用於機台端獲取目前應播放的廣告檔案 URL 清單。此介面無需 Request Body。',
|
||
'headers' => [
|
||
'Authorization' => 'Bearer <api_token>',
|
||
'Content-Type' => 'application/json',
|
||
],
|
||
'parameters' => [],
|
||
'response_parameters' => [
|
||
'success' => [
|
||
'type' => 'boolean',
|
||
'description' => '請求是否成功',
|
||
'example' => true
|
||
],
|
||
'code' => [
|
||
'type' => 'integer',
|
||
'description' => '內部業務狀態碼',
|
||
'example' => 200
|
||
],
|
||
'data' => [
|
||
'type' => 'array',
|
||
'description' => '廣告物件陣列。內部欄位包含:t070v01 (名稱), t070v02 (秒數), t070v03 (位置:1:販賣頁, 2:來店禮, 3:待機廣告), t070v04 (URL), t070v05 (順位)',
|
||
'example' => [
|
||
[
|
||
't070v01' => '測試機台廣告',
|
||
't070v02' => 15,
|
||
't070v03' => 3,
|
||
't070v04' => 'https://example.com/ad1.mp4',
|
||
't070v05' => 1
|
||
]
|
||
]
|
||
],
|
||
],
|
||
'request' => [],
|
||
'response' => [
|
||
'success' => true,
|
||
'code' => 200,
|
||
'data' => [
|
||
[
|
||
't070v01' => '測試機台廣告',
|
||
't070v02' => 15,
|
||
't070v03' => 3,
|
||
't070v04' => 'https://example.com/ad1.mp4',
|
||
't070v05' => 1
|
||
]
|
||
]
|
||
],
|
||
],
|
||
[
|
||
'name' => 'B009: 貨道庫存即時回報 (Inventory Report)',
|
||
'slug' => 'b009-inventory-report',
|
||
'method' => 'PUT',
|
||
'path' => '/api/v1/app/products/supplementary/B009',
|
||
'description' => '當人員在機台端完成操作後,將目前的貨道實體狀態同步回雲端。需進行 RBAC 權限核查。',
|
||
'headers' => [
|
||
'Authorization' => 'Bearer <api_token>',
|
||
'Content-Type' => 'application/json',
|
||
],
|
||
'parameters' => [
|
||
'account' => [
|
||
'type' => 'string',
|
||
'required' => true,
|
||
'description' => '操作人員帳號',
|
||
'example' => '0999123456'
|
||
],
|
||
'data' => [
|
||
'type' => 'array',
|
||
'required' => true,
|
||
'description' => '貨道數據陣列。tid: 貨道號, t060v00: 商品 ID, num: 庫存量, type: 貨道類型(1:履帶, 2:彈簧)',
|
||
'example' => [
|
||
['tid' => '1', 't060v00' => '1', 'num' => 10, 'type' => 1]
|
||
]
|
||
],
|
||
],
|
||
'response_parameters' => [
|
||
'success' => [
|
||
'type' => 'boolean',
|
||
'description' => '同步是否成功',
|
||
'example' => true
|
||
],
|
||
'code' => [
|
||
'type' => 'integer',
|
||
'description' => '內部業務狀態碼',
|
||
'example' => 200
|
||
],
|
||
'message' => [
|
||
'type' => 'string',
|
||
'description' => '回應訊息',
|
||
'example' => 'Slot report synchronized success'
|
||
],
|
||
],
|
||
'request' => [
|
||
'account' => '0999123456',
|
||
'data' => [
|
||
['tid' => '1', 't060v00' => '1', 'num' => 10, 'type' => 1]
|
||
]
|
||
],
|
||
'response' => [
|
||
'success' => true,
|
||
'code' => 200,
|
||
'message' => 'Slot report synchronized success',
|
||
],
|
||
],
|
||
[
|
||
'name' => 'B012: 商品配置與商品主檔同步 (Unified Sync)',
|
||
'slug' => 'b012-unified-sync',
|
||
'method' => 'GET',
|
||
'path' => '/api/v1/app/machine/products/B012',
|
||
'description' => '用於機台端獲取目前所有可販售商品的詳細配置 (全量同步)。',
|
||
'headers' => [
|
||
'Authorization' => 'Bearer <api_token>',
|
||
'Content-Type' => 'application/json',
|
||
],
|
||
'parameters' => [],
|
||
'response_parameters' => [
|
||
'success' => [
|
||
'type' => 'boolean',
|
||
'description' => '請求是否處理成功',
|
||
'example' => true
|
||
],
|
||
'code' => [
|
||
'type' => 'integer',
|
||
'description' => '內部業務狀態碼',
|
||
'example' => 200
|
||
],
|
||
'data' => [
|
||
'type' => 'array',
|
||
'description' => '商品明細物件陣列。欄位包含:t060v00(ID), t060v01(名稱), t060v03(規格), t060v06(圖片), t060v09(售價), t060v11(預設上限), spring_limit(彈簧上限), track_limit(履帶上限)',
|
||
'example' => [
|
||
[
|
||
't060v00' => '1',
|
||
't060v01' => '可口可樂 330ml',
|
||
't060v01_en' => 'Coca Cola',
|
||
't060v01_jp' => 'コカコーラ',
|
||
't060v03' => 'Cold Drink',
|
||
't060v06' => 'https://.../coke.png',
|
||
't060v09' => 25.0,
|
||
't060v11' => 10,
|
||
't060v30' => 20.0,
|
||
't063v03' => 25.0,
|
||
't060v40' => 'Buy 1 Get 1',
|
||
't060v41' => 'SKU-COKE-001',
|
||
'spring_limit' => 10,
|
||
'track_limit' => 15
|
||
]
|
||
]
|
||
]
|
||
],
|
||
'request' => [],
|
||
'response' => [
|
||
'success' => true,
|
||
'code' => 200,
|
||
'data' => [
|
||
[
|
||
't060v00' => '1',
|
||
't060v01' => '可口可樂 330ml',
|
||
't060v01_en' => 'Coca Cola 330ml',
|
||
't060v01_jp' => 'コカコーラ 330ml',
|
||
't060v03' => '經典原味,冰涼好滋味',
|
||
't060v06' => 'https://cloud.star.com/storage/products/coke.png',
|
||
't060v09' => 25.0,
|
||
't060v11' => 10,
|
||
't060v30' => 20.0,
|
||
't063v03' => 25.0,
|
||
't060v40' => '買一送一活動中',
|
||
't060v41' => 'SKU-COKE-001',
|
||
'spring_limit' => 10,
|
||
'track_limit' => 15
|
||
]
|
||
]
|
||
],
|
||
],
|
||
[
|
||
'name' => 'B650: 會員身分驗證 (Member Verification)',
|
||
'slug' => 'b650-member-verify',
|
||
'method' => 'POST',
|
||
'path' => '/api/v1/app/machine/member/verify/B650',
|
||
'description' => '機台端掃碼後驗證會員身分。',
|
||
'headers' => [
|
||
'Authorization' => 'Bearer <api_token>',
|
||
'Content-Type' => 'application/json',
|
||
],
|
||
'parameters' => [
|
||
'code' => [
|
||
'type' => 'string',
|
||
'required' => true,
|
||
'description' => '會員代碼',
|
||
'example' => 'MEMBER12345'
|
||
]
|
||
],
|
||
'response' => [
|
||
'success' => true,
|
||
'data' => [
|
||
'member_id' => 123,
|
||
'name' => '王小明',
|
||
'points' => 500
|
||
]
|
||
],
|
||
],
|
||
[
|
||
'name' => 'B660: 取貨碼驗證 (Pickup Code)',
|
||
'slug' => 'b660-pickup-code',
|
||
'method' => 'POST',
|
||
'path' => '/api/v1/app/machine/pickup/verify/B660',
|
||
'description' => '處理代碼取貨驗證。成功後回傳對應資訊,正式消耗改由 MQTT finalize 處理。',
|
||
'headers' => [
|
||
'Authorization' => 'Bearer <api_token>',
|
||
'Content-Type' => 'application/json',
|
||
],
|
||
'parameters' => [
|
||
'code' => [
|
||
'type' => 'string',
|
||
'description' => '8 位數取貨碼',
|
||
'example' => '12345678'
|
||
],
|
||
],
|
||
'response' => [
|
||
'success' => true,
|
||
'data' => [
|
||
'slot_no' => '1',
|
||
'pickup_code_id' => 45,
|
||
'status' => 'active'
|
||
]
|
||
],
|
||
'notes' => '安全性:連續錯誤 5 次將鎖定該機台驗證功能 1 分鐘。消耗流程已遷移至 MQTT。'
|
||
],
|
||
[
|
||
'name' => 'B670: 通行碼驗證 (Pass Code)',
|
||
'slug' => 'b670-pass-code',
|
||
'method' => 'POST',
|
||
'path' => '/api/v1/app/machine/passcode/verify/B670',
|
||
'description' => '專供維修/工程人員使用的通行碼驗證。僅做身份確認,不涉及商品消耗。',
|
||
'headers' => [
|
||
'Authorization' => 'Bearer <api_token>',
|
||
'Content-Type' => 'application/json',
|
||
],
|
||
'parameters' => [
|
||
'code' => [
|
||
'type' => 'string',
|
||
'required' => true,
|
||
'description' => '8 位數通行碼',
|
||
'example' => '88888888'
|
||
]
|
||
],
|
||
'response' => [
|
||
'success' => true,
|
||
'data' => [
|
||
'name' => '工程師 A',
|
||
'status' => 'active'
|
||
]
|
||
],
|
||
'notes' => '僅供現場測試使用,錯誤過多同樣會觸發鎖定。'
|
||
],
|
||
[
|
||
'name' => 'B680: 員工卡身分驗證 (Staff Card Verification)',
|
||
'slug' => 'b680-staff-card-verify',
|
||
'method' => 'POST',
|
||
'path' => '/api/v1/app/machine/staff/verify/B680',
|
||
'description' => '機台端感應員工卡 (RFID/NFC) 後驗證卡片 UID。',
|
||
'headers' => [
|
||
'Authorization' => 'Bearer <api_token>',
|
||
'Content-Type' => 'application/json',
|
||
],
|
||
'parameters' => [
|
||
'code' => [
|
||
'type' => 'string',
|
||
'required' => true,
|
||
'description' => '卡片 UID 碼',
|
||
'example' => 'A1B2C3D4'
|
||
]
|
||
],
|
||
'response' => [
|
||
'success' => true,
|
||
'data' => [
|
||
'name' => '員工姓名',
|
||
'code_id' => 12,
|
||
'status' => 'active'
|
||
]
|
||
],
|
||
'notes' => '驗證成功後會建立刷卡日誌。連續錯誤同樣會觸發鎖定。'
|
||
],
|
||
[
|
||
'name' => 'B690: 來店禮驗證 (Welcome Gift Verify)',
|
||
'slug' => 'b690-welcome-gift-verify',
|
||
'method' => 'POST',
|
||
'path' => '/api/v1/app/machine/welcome-gift/verify/B690',
|
||
'description' => '處理機台端的 8 位數來店禮代碼驗證。成功後回傳折扣資訊(含台灣中文折數標籤),供機台端套用折扣。正式消耗改由 MQTT finalize 處理 (payment_type=7)。',
|
||
'headers' => [
|
||
'Authorization' => 'Bearer <api_token>',
|
||
'Content-Type' => 'application/json',
|
||
],
|
||
'parameters' => [
|
||
'code' => [
|
||
'type' => 'string',
|
||
'required' => true,
|
||
'description' => '8 位數來店禮代碼',
|
||
'example' => '12345678'
|
||
]
|
||
],
|
||
'response_parameters' => [
|
||
'success' => [
|
||
'type' => 'boolean',
|
||
'description' => '請求是否成功',
|
||
'example' => true
|
||
],
|
||
'code' => [
|
||
'type' => 'integer',
|
||
'description' => '業務狀態碼',
|
||
'example' => 200
|
||
],
|
||
'data.name' => [
|
||
'type' => 'string',
|
||
'description' => '來店禮名稱',
|
||
'example' => '新客八五折'
|
||
],
|
||
'data.code_id' => [
|
||
'type' => 'integer',
|
||
'description' => '來店禮 ID (用於 MQTT 交易關聯,payment_type=7 時帶入)',
|
||
'example' => 12
|
||
],
|
||
'data.discount_type' => [
|
||
'type' => 'string',
|
||
'description' => '折扣類型:percentage (趴數折扣) 或 amount (金額折扣)',
|
||
'example' => 'percentage'
|
||
],
|
||
'data.discount_value' => [
|
||
'type' => 'integer',
|
||
'description' => '折扣數值。percentage 時為趴數 (如 15 代表 15% off);amount 時為折扣金額 (如 50)',
|
||
'example' => 15
|
||
],
|
||
'data.discount_label' => [
|
||
'type' => 'string',
|
||
'description' => '台灣中文折數標籤 (如「八五折」、「折 50 元」),供 UI 直接顯示',
|
||
'example' => '八五折'
|
||
],
|
||
'data.usage_type' => [
|
||
'type' => 'string',
|
||
'description' => '使用類型:once (單次) 或 unlimited (無限制)',
|
||
'example' => 'once'
|
||
],
|
||
'data.status' => [
|
||
'type' => 'string',
|
||
'description' => '來店禮狀態',
|
||
'example' => 'active'
|
||
],
|
||
],
|
||
'request' => [
|
||
'code' => '12345678'
|
||
],
|
||
'response' => [
|
||
'success' => true,
|
||
'code' => 200,
|
||
'data' => [
|
||
'name' => '新客八五折',
|
||
'code_id' => 12,
|
||
'discount_type' => 'percentage',
|
||
'discount_value' => 15,
|
||
'discount_label' => '八五折',
|
||
'usage_type' => 'once',
|
||
'status' => 'active'
|
||
]
|
||
],
|
||
'notes' => '安全性:連續錯誤 5 次將鎖定該機台驗證功能 1 分鐘。消耗流程已遷移至 MQTT (payment_type=7)。'
|
||
],
|
||
],
|
||
],
|
||
],
|
||
|
||
'mqtt_connection_specs' => [
|
||
'description' => '機台連線 MQTT Broker 時的必要憑據。',
|
||
'specs' => [
|
||
'Host' => 'mqtt.setdomains.work',
|
||
'Port' => '443 (WSS / 公網) 或 1883 (TCP / 內部)',
|
||
'Username' => '機台序號 (serial_no)',
|
||
'Password' => 'API Token 的 SHA256 雜湊值 (由 B014 取得)',
|
||
'ClientID' => 'SC_{serial_no} (固定格式,確保單機唯一連線)',
|
||
]
|
||
],
|
||
|
||
'mqtt_topics' => [
|
||
[
|
||
'name' => '指令與通訊 (Commands & Flow)',
|
||
'topics' => [
|
||
[
|
||
'name' => '機台心跳上報 (Heartbeat)',
|
||
'slug' => 'mqtt-heartbeat',
|
||
'action' => 'PUB',
|
||
'topic' => 'machine/{serial_no}/heartbeat',
|
||
'qos' => 0,
|
||
'description' => '機台每分鐘固定上報的狀態大包裝。整合了溫度與韌體版本。雲端記錄規則:溫度只要有變動 (current !== last) 即記錄日誌。',
|
||
'payload_parameters' => [
|
||
'temperature' => ['type' => 'integer', 'description' => '目前機台溫度'],
|
||
'firmware_version' => ['type' => 'string', 'description' => 'APP 韌體版本'],
|
||
],
|
||
'payload_example' => [
|
||
'temperature' => 20,
|
||
'firmware_version' => '2.1.6'
|
||
],
|
||
],
|
||
[
|
||
'name' => '機台連線狀態上報 (Status/LWT)',
|
||
'slug' => 'mqtt-status',
|
||
'action' => 'PUB',
|
||
'topic' => 'machine/{serial_no}/status',
|
||
'qos' => 0,
|
||
'description' => '用於機台連線與斷線的即時狀態同步。通常用於 MQTT 的遺囑訊息 (LWT) 設定,或由 Broker 連線事件觸發。',
|
||
'payload_parameters' => [
|
||
'status' => ['type' => 'string', 'description' => '連線狀態。接受值:online, offline'],
|
||
],
|
||
'payload_example' => [
|
||
'status' => 'online'
|
||
],
|
||
],
|
||
[
|
||
'name' => '機台異常上報 (Error)',
|
||
'slug' => 'mqtt-error',
|
||
'action' => 'PUB',
|
||
'topic' => 'machine/{serial_no}/error',
|
||
'qos' => 1,
|
||
'description' => '當機台發生硬體故障(如卡貨、通訊中斷)時即時上報。',
|
||
'payload_parameters' => [
|
||
'tid' => ['type' => 'integer', 'description' => '貨道編號或任務 ID'],
|
||
'error_code' => ['type' => 'string', 'description' => '硬體錯誤代碼 (如 0403 代表卡貨)'],
|
||
],
|
||
'payload_example' => [
|
||
'tid' => 12,
|
||
'error_code' => '0403'
|
||
],
|
||
],
|
||
[
|
||
'name' => '交易階段性上報 (Transaction Steps)',
|
||
'slug' => 'mqtt-transaction-steps',
|
||
'action' => 'PUB',
|
||
'topic' => 'machine/{serial_no}/transaction',
|
||
'qos' => 1,
|
||
'description' => '用於傳統的分段式上報:交易建立 (create)、發票紀錄 (invoice) 或單次出貨結果 (dispense)。',
|
||
'payload_parameters' => [
|
||
'action' => ['type' => 'string', 'description' => '動作:create, invoice, dispense'],
|
||
'flow_id' => ['type' => 'string', 'description' => '唯一流水號'],
|
||
],
|
||
'payload_example' => [
|
||
'action' => 'create',
|
||
'flow_id' => 'FLOW123',
|
||
'total_amount' => 25.0,
|
||
'payment_type' => 1,
|
||
'items' => [['product_id' => 5, 'price' => 25.0, 'quantity' => 1]]
|
||
],
|
||
],
|
||
[
|
||
'name' => '交易完成統整上報 (Transaction Finalized - 推薦)',
|
||
'slug' => 'mqtt-transaction-finalize',
|
||
'action' => 'PUB',
|
||
'topic' => 'machine/{serial_no}/transaction',
|
||
'qos' => 1,
|
||
'description' => '【推薦使用】將交易、發票與出貨結果統整為單一動作上報,確保資料庫寫入的原子性與一致性。',
|
||
'payload_parameters' => [
|
||
'action' => ['type' => 'string', 'description' => '(必填) 固定為 "finalize"'],
|
||
'order' => ['type' => 'object', 'description' => '(必填) 訂單主檔資訊'],
|
||
'order.order_no' => ['type' => 'string', 'description' => '(必填) 訂單編號'],
|
||
'order.flow_id' => ['type' => 'string', 'description' => '(必填) 機台端交易流水號'],
|
||
'order.total_amount' => ['type' => 'numeric', 'description' => '(必填) 應付總金額'],
|
||
'order.pay_amount' => ['type' => 'numeric', 'description' => '(必填) 實際支付金額'],
|
||
'order.change_amount' => ['type' => 'numeric', 'description' => '(選填) 找零金額,預設 0', 'required' => false],
|
||
'order.original_amount' => ['type' => 'numeric', 'description' => '(選填) 原始標價金額', 'required' => false],
|
||
'order.discount_amount' => ['type' => 'numeric', 'description' => '(選填) 折扣金額,預設 0', 'required' => false],
|
||
'order.points_used' => ['type' => 'integer', 'description' => '(選填) 使用點數,預設 0', 'required' => false],
|
||
'order.payment_type' => ['type' => 'integer', 'description' => "(必填) 支付類型代碼:\n1:信用卡, 2:悠遊卡/一卡通, 3:掃碼支付, 4:紙鈔機, 5:通行碼, 6:取貨碼, 7:來店禮, 8:問卷, 9:零錢, 41:員工卡。\n21~25:線下付款+X (21:線下+1, 22:線下+2, 23:線下+3, 24:線下+4, 25:線下+9)。\n30:LINE Pay, 31:街口, 32:悠遊付, 33:Pi, 34:全盈+。\n40:會員驗證取貨商品。\n50~54:線下付款+TapPay (50:線下+30, 51:線下+31, 52:線下+32, 53:線下+33, 54:線下+34)。\n60:點數/優惠卷全額折抵。61~69:會員+X (61:會員+1...69:會員+9)。\n90~94:會員+TapPay (90:會員+30...94:會員+34)。\n100:遠端出貨。"],
|
||
'order.payment_status' => ['type' => 'integer', 'description' => '(必填) 支付狀態 (1:成功)'],
|
||
'order.code_id' => ['type' => 'string', 'description' => '(選填) 閉環勾稽用的代碼 ID (payment_type 為 5, 6, 41 時必填)', 'required' => false],
|
||
'order.payment_request' => ['type' => 'string', 'description' => '(選填) 金流請求原始字串', 'required' => false],
|
||
'order.payment_response' => ['type' => 'string', 'description' => '(選填) 金流回應原始字串', 'required' => false],
|
||
'order.member_barcode' => ['type' => 'string', 'description' => '(選填) 會員條碼', 'required' => false],
|
||
'order.invoice_info' => ['type' => 'string', 'description' => '(選填) 預設發票歸戶字串 (如 統編-電話)', 'required' => false],
|
||
'order.machine_time' => ['type' => 'datetime', 'description' => '(必填) 機台交易時間 (Y-m-d H:i:s)'],
|
||
'order.items' => ['type' => 'array', 'description' => '(必填) 訂單明細陣列'],
|
||
'order.items[].product_id' => ['type' => 'integer', 'description' => '(必填) 商品 ID'],
|
||
'order.items[].price' => ['type' => 'numeric', 'description' => '(必填) 商品單價'],
|
||
'order.items[].quantity' => ['type' => 'integer', 'description' => '(必填) 數量'],
|
||
|
||
'invoice' => ['type' => 'object', 'description' => '(選填) 發票開立資訊 (若無發票可省略)', 'required' => false],
|
||
'invoice.invoice_no' => ['type' => 'string', 'description' => '(必填,若有invoice) 發票號碼', 'required' => false],
|
||
'invoice.invoice_date' => ['type' => 'string', 'description' => '(必填,若有invoice) 發票日期 (Y-m-d)', 'required' => false],
|
||
'invoice.machine_time' => ['type' => 'datetime', 'description' => '(必填,若有invoice) 機台開立發票時間 (Y-m-d H:i:s)', 'required' => false],
|
||
'invoice.amount' => ['type' => 'numeric', 'description' => '(必填,若有invoice) 發票金額', 'required' => false],
|
||
'invoice.random_number' => ['type' => 'string', 'description' => '(必填,若有invoice) 發票隨機碼 (4位)', 'required' => false],
|
||
'invoice.love_code' => ['type' => 'string', 'description' => '(選填) 捐贈碼', 'required' => false],
|
||
'invoice.carrier_id' => ['type' => 'string', 'description' => '(選填) 載具編號', 'required' => false],
|
||
'invoice.carrier_type' => ['type' => 'string', 'description' => '(選填) 載具類型 (如 3J0002)', 'required' => false],
|
||
'invoice.business_tax_id' => ['type' => 'string', 'description' => '(選填) 買受人統編', 'required' => false],
|
||
'invoice.rtn_code' => ['type' => 'string', 'description' => '(選填) 電子發票回傳代碼', 'required' => false],
|
||
'invoice.rtn_msg' => ['type' => 'string', 'description' => '(選填) 電子發票回傳訊息', 'required' => false],
|
||
|
||
'dispense' => ['type' => 'array', 'description' => '(必填) 出貨結果清單'],
|
||
'dispense[].slot_no' => ['type' => 'string', 'description' => '(必填) 貨道編號'],
|
||
'dispense[].product_id' => ['type' => 'integer', 'description' => '(必填) 商品 ID'],
|
||
'dispense[].amount' => ['type' => 'numeric', 'description' => '(必填) 實際扣款額 (單項)'],
|
||
'dispense[].points_used' => ['type' => 'integer', 'description' => '(選填) 該商品花費點數,預設 0', 'required' => false],
|
||
'dispense[].dispense_status' => ['type' => 'integer', 'description' => '(必填) 出貨狀態 (1:成功, 0:失敗)'],
|
||
'dispense[].remaining_stock' => ['type' => 'integer', 'description' => '(必填) 出貨後剩餘庫存'],
|
||
'dispense[].member_barcode' => ['type' => 'string', 'description' => '(選填) 會員條碼', 'required' => false],
|
||
'dispense[].machine_time' => ['type' => 'datetime', 'description' => '(選填) 機台出貨時間 (Y-m-d H:i:s)', 'required' => false],
|
||
],
|
||
'payload_example' => [
|
||
'action' => 'finalize',
|
||
'order' => [
|
||
'order_no' => 'T202508080001',
|
||
'flow_id' => 'FLOW123',
|
||
'total_amount' => 100.0,
|
||
'original_amount' => 100.0,
|
||
'discount_amount' => 0.0,
|
||
'pay_amount' => 100.0,
|
||
'change_amount' => 0.0,
|
||
'points_used' => 0,
|
||
'payment_type' => 1,
|
||
'payment_status' => 1,
|
||
'code_id' => '對應指令的ID或取貨碼(如適用)',
|
||
'payment_request' => '{"req": "data"}',
|
||
'payment_response' => '{"res": "ok"}',
|
||
'member_barcode' => 'MBR999',
|
||
'invoice_info' => '12345678-0912345678',
|
||
'machine_time' => '2025-08-08 10:00:00',
|
||
'items' => [
|
||
['product_id' => 5, 'price' => 100.0, 'quantity' => 1]
|
||
]
|
||
],
|
||
'invoice' => [
|
||
'invoice_no' => 'AB12345678',
|
||
'invoice_date' => '2025-08-08',
|
||
'amount' => 100.0,
|
||
'random_number' => '1234',
|
||
'love_code' => '',
|
||
'carrier_id' => '/ABC1234',
|
||
'carrier_type' => '3J0002',
|
||
'business_tax_id' => '12345678',
|
||
'rtn_code' => '1',
|
||
'rtn_msg' => '成功'
|
||
],
|
||
'dispense' => [
|
||
[
|
||
'slot_no' => '3',
|
||
'product_id' => 5,
|
||
'amount' => 100.0,
|
||
'points_used' => 0,
|
||
'dispense_status' => 1,
|
||
'remaining_stock' => 9,
|
||
'member_barcode' => 'MBR999',
|
||
'machine_time' => '2025-08-08 10:01:00'
|
||
]
|
||
]
|
||
],
|
||
],
|
||
[
|
||
'name' => '指令下發:遠端出貨 (Dispense)',
|
||
'slug' => 'mqtt-command-dispense',
|
||
'action' => 'SUB',
|
||
'topic' => 'machine/{serial_no}/command',
|
||
'qos' => 1,
|
||
'description' => '雲端主動下發「遠端出貨」指令。機台收到後應立即驅動馬達進行出貨,出貨完成或失敗後回報 ACK。',
|
||
'payload_parameters' => [
|
||
'command' => ['type' => 'string', 'description' => '固定為 "dispense"'],
|
||
'command_id' => ['type' => 'string', 'description' => '指令唯一 ID'],
|
||
'payload' => ['type' => 'object', 'description' => '出貨參數'],
|
||
'payload.slot_no' => ['type' => 'string', 'description' => '欲出貨的貨道號碼'],
|
||
'payload.old_stock' => ['type' => 'integer', 'description' => '出貨前的庫存量'],
|
||
'payload.new_stock' => ['type' => 'integer', 'description' => '出貨後應剩餘的庫存量 (樂觀扣減結果)'],
|
||
],
|
||
'payload_example' => [
|
||
'command' => 'dispense',
|
||
'command_id' => '9988776655',
|
||
'payload' => [
|
||
'slot_no' => '1',
|
||
'old_stock' => 10,
|
||
'new_stock' => 9
|
||
]
|
||
],
|
||
],
|
||
[
|
||
'name' => '指令下發:庫存同步 (Update Inventory)',
|
||
'slug' => 'mqtt-command-update-inventory',
|
||
'action' => 'SUB',
|
||
'topic' => 'machine/{serial_no}/command',
|
||
'qos' => 1,
|
||
'description' => '雲端主動下發「庫存更新」指令 (如從後台修改庫存、效期時觸發)。',
|
||
'payload_parameters' => [
|
||
'command' => ['type' => 'string', 'description' => '固定為 "update_inventory"'],
|
||
'command_id' => ['type' => 'string', 'description' => '指令唯一 ID'],
|
||
'payload' => ['type' => 'object', 'description' => '更新參數'],
|
||
'payload.slot_no' => ['type' => 'string', 'description' => '貨道號碼'],
|
||
'payload.stock' => ['type' => 'integer', 'description' => '最新庫存量'],
|
||
'payload.expiry_date' => ['type' => 'string', 'description' => '最新效期 (YYYY-MM-DD)'],
|
||
'payload.batch_no' => ['type' => 'string', 'description' => '批號 (可為 null)'],
|
||
],
|
||
'payload_example' => [
|
||
'command' => 'update_inventory',
|
||
'command_id' => '5566778899',
|
||
'payload' => [
|
||
'slot_no' => '1',
|
||
'stock' => 10,
|
||
'expiry_date' => '2026-12-31',
|
||
'batch_no' => null
|
||
]
|
||
],
|
||
],
|
||
[
|
||
'name' => '指令下發:遠端找零 (Change)',
|
||
'slug' => 'mqtt-command-change',
|
||
'action' => 'SUB',
|
||
'topic' => 'machine/{serial_no}/command',
|
||
'qos' => 1,
|
||
'description' => '雲端主動下發「找零」指令。指示機台退還指定金額的現金。',
|
||
'payload_parameters' => [
|
||
'command' => ['type' => 'string', 'description' => '固定為 "change"'],
|
||
'command_id' => ['type' => 'string', 'description' => '指令唯一 ID'],
|
||
'payload' => ['type' => 'object', 'description' => '找零參數'],
|
||
'payload.amount' => ['type' => 'integer', 'description' => '欲找零/退款的金額'],
|
||
],
|
||
'payload_example' => [
|
||
'command' => 'change',
|
||
'command_id' => '1122334455',
|
||
'payload' => [
|
||
'amount' => 50
|
||
]
|
||
],
|
||
],
|
||
[
|
||
'name' => '指令下發:系統控制 (System Control)',
|
||
'slug' => 'mqtt-command-system',
|
||
'action' => 'SUB',
|
||
'topic' => 'machine/{serial_no}/command',
|
||
'qos' => 1,
|
||
'description' => '雲端主動下發的系統級別控制指令。包含重啟、設備鎖定解鎖、購物車結帳等無額外參數的指令。',
|
||
'payload_parameters' => [
|
||
'command' => ['type' => 'string', 'description' => '系統指令類型。支援:reboot (重啟機台), reboot_card (重啟刷卡機), checkout (購物車結帳), lock (設備鎖定), unlock (設備解鎖), update_ads (廣告同步), update_products (商品資料同步)'],
|
||
'command_id' => ['type' => 'string', 'description' => '指令唯一 ID'],
|
||
'payload' => ['type' => 'object', 'description' => '空物件 (無額外參數)'],
|
||
],
|
||
'payload_example' => [
|
||
'command' => 'reboot',
|
||
'command_id' => '9999999999',
|
||
'payload' => new \stdClass()
|
||
],
|
||
],
|
||
|
||
[
|
||
'name' => '指令執行回報 (Machine to Cloud)',
|
||
'slug' => 'mqtt-command-ack',
|
||
'action' => 'PUB',
|
||
'topic' => 'machine/{serial_no}/command/ack',
|
||
'qos' => 1,
|
||
'description' => '機台執行完雲端指令後的主動回報。此回報極為重要,雲端將依此決定交易是否完成或需進行庫存回滾。',
|
||
'payload_parameters' => [
|
||
'command_id' => ['type' => 'string', 'description' => '對應下發時的指令 ID'],
|
||
'result' => ['type' => 'string', 'description' => '執行結果,僅接受: success 或 failed'],
|
||
'stock' => ['type' => 'integer', 'description' => '執行指令後的最終剩餘庫存 (選填,通常出貨指令需帶上)'],
|
||
'message' => ['type' => 'string', 'description' => '額外的錯誤訊息 (選填)'],
|
||
],
|
||
'payload_example' => [
|
||
'command_id' => '12345',
|
||
'result' => 'success',
|
||
'stock' => 9
|
||
],
|
||
]
|
||
]
|
||
]
|
||
]
|
||
]; |