店家 API 文件
把「開口就買單」接進你自己的品牌。本頁是 Chui Hub 公開 API 的完整參考—— 與 協議規格 PROTOCOL.md 同步。
兩條接入路徑
A. 沒有自己的網站 → 公版開店(零程式碼)
到 chuiprotocol.com「我要開店」:填店名、菜單、客製化選項, 用 Slush 錢包(Chrome 擴充功能/iOS App)簽一個名就上線。收款直達你的錢包,平台不代管任何私鑰。
B. 已有自己的品牌網站 → 串 Hub API
先走 A 完成開店拿到 merchant_id,再讓你的網站直接呼叫本頁 API
(語音解析、下單、結帳)。建議直接用
AI Agent 串接導引——把現成 prompt 貼給
Claude Code/Codex,5 分鐘產出串接程式碼。
通用約定
- Base URL:
https://hub.chuiprotocol.com(免金鑰;瀏覽器可直接呼叫,CORS 全開) - 金額一律整數:菜單價格單位=新台幣元;鏈上金額單位=USDC 最小單位(6 位小數)。
- 錯誤格式:
{"detail": {"code", "message"}},搭配對應的 HTTP 狀態碼。 - 誠實失敗:語音信心不足回
422 CLARIFICATION_NEEDED(必須反問,絕不猜); 鏈上查不到就是pending,不偽造成功。 - 隱私:鏈上只出現
order_digest = SHA-256(canonical_json(明細) ‖ 32B salt), 看不到品項明細。
Hub API 端點
POST /v1/merchants/register — 開店/更新菜單
用錢包簽名證明收款地址所有權。同一錢包+同一店名重複註冊=更新菜單;換店名=開第二家店。
{
"name": "豆花大王", // 必填,最長 20 字
"ticket_prefix": "TF", // 必填,2 個大寫英文字母(取餐叫號用)
"payout_address": "0x…", // 必填,Sui 收款地址(64 hex)
"menu": { "items": [ … ] }, // 必填,最多 30 品項(格式見下方「菜單格式」)
"signature": "…" // 必填,錢包對訊息
// "chui-open-shop:v1:{address}:{name}" 的簽名
}
成功 200 回 {"merchant_id": "m_xxxxxxxxxx", …};
簽名者與收款地址不符回 401 SIGNATURE_INVALID。
GET /v1/merchants — 商家列表
{"merchants": [{"merchant_id", "name", "integration": "native|adapter", "web_url"}]}
GET /v1/merchants/{merchant_id}/menu — 商家菜單
回協議菜單格式(見下方「菜單格式」)。
GET /v1/merchants/{merchant_id}/orders — 店家看板資料
該店訂單流(新到舊;已排除未確認的報價單)。店家後台輪詢或搭配 SSE 用。
POST /v1/orders/parse — 語音/文字解析+報價
multipart/form-data:text(或 audio 音檔)+
merchant_id(省略時 Hub 對所有商家解析、取信心最高者路由)。
// 200 成功
{
"order_id": "ord_xxx",
"merchant_id": "happy-chicken", "merchant_name": "快樂鹽酥雞",
"intent": {"items": […], "confidence": 0.93, "stt_text": "我要一份鹽酥雞加辣"},
"quote": {"lines": […], "total": 65, "currency": "TWD"},
"readback": {"text": "加辣鹽酥雞,總共 65 元,確認嗎?"}
}
// 422 信心不足(協議規定:不確定就必須問,絕不猜)
{"detail": {"code": "CLARIFICATION_NEEDED", "question": "…", "candidates": […]}}
POST /v1/orders/confirm — 確認下單+取結帳參數
Body:{"order_id": "ord_xxx"}。Hub 把訂單交給商家後回鏈上結帳參數:
{
"order_id": "ord_xxx", "merchant_ref": "TF-0906-0003",
"checkout": {
"network": "testnet",
"package_id": "0x…", "module": "pay", "function": "settle",
"coin_type": "0x…::usdc::USDC",
"amount_units": 2080000, // USDC 最小單位(此例=2.08 USDC)
"merchant_address": "0x…",
"order_digest_hex": "…64 hex…"
}
}
錢包端組 PTB:settle<coin_type>(coinWithBalance(amount_units),
merchant_address, digest_bytes)——coin 面額即金額,合約不信任額外參數。
POST /v1/orders/{order_id}/settlement — 回報鏈上交易
Body:{"tx_digest": "…"}。Hub 向 fullnode 驗證
SettlementEvent(digest/金額/店家三者皆符才標記已付款)。
POST /v1/orders/{order_id}/verify — 重新驗證
fullnode 暫時查不到時(狀態 pending)可重試驗證。
GET /v1/orders/{order_id} — 查單一訂單
GET /v1/logs?owner=0x… — 用戶訂單史
依付款錢包地址(鏈上 SettlementEvent.owner)歸戶。
已知限制(誠實揭露):demo 版無存取控制,任何人知道地址即可查詢;
內容僅含訂單摘要,對話明細另以 Seal 端對端加密(平台無鑰)。
GET /v1/events — SSE 即時事件流
Server-Sent Events:訂單建立、付款驗證、封包流向即時推播。 店家看板、封包面板都吃這條。
GET /healthz — 服務狀態
回運行環境、STT 供應商鏈、LLM 備援、匯率來源——所有外部依賴的即時真實狀態。
菜單格式
{
"menu_version": "2026-09-06",
"currency": "TWD",
"items": [{
"id": "boba-tea", "name": "珍珠奶茶", "base_price": 65,
"synonyms": ["珍奶", "波霸奶茶"], // 口語同義詞:辨識救回的關鍵
"options": [{
"id": "sugar", "name": "糖度", "required": false, "default": "FULL",
"choices": [
{"id": "NONE", "name": "無糖", "synonyms": ["不要糖"], "price_delta": 0},
{"id": "HALF", "name": "半糖", "synonyms": [], "price_delta": 0},
{"id": "FULL", "name": "正常糖", "synonyms": [], "price_delta": 0}
]
}]
}]
}
synonyms 救回。商家端介面(進階:adapter 模式)
已有 POS/訂單系統的店家可以反向操作——不改舊系統一行程式碼,寫一個 adapter 實作三個端點,Hub 會主動呼叫你:
| 端點 | 時機 | 格式 |
|---|---|---|
GET /chui/menu | Hub 快取你的菜單 | 上方菜單格式 |
POST /chui/orders | 用戶確認後收單 | 回 {"accepted": true, "merchant_ref": "你的單號"} |
POST /chui/orders/{id}/paid | 鏈上驗證通過,通知出餐 | 回 {"ok": true} |
完整示範:快樂鹽酥雞 adapter 原始碼(legacy 系統原樣不動)。
端到端流程
用戶說「珍奶無糖少冰」
→ POST /v1/orders/parse (封閉詞彙重排序+報價)
→ 覆誦、口頭確認、5 秒防呆倒數
→ POST /v1/orders/confirm (取鏈上結帳參數)
→ 錢包簽 settle()/Vault 自動扣款 (USDC 直達店家地址)
→ POST /v1/orders/{id}/settlement (Hub 鏈上驗證三符)
→ 店家看板即時跳單(SSE),取餐單號叫號