iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
Modern Web

WebMCP:30 天打造 AI Agent 看得懂、也操作得動的網站系列 第 26 篇

Day 26|「加入兩件」和「改成兩件」不同:WooCommerce 購物車 Tool 實戰

  • 分享至 

  • xImage
  •  

Day 25 已經能找商品,今天讓 Tool 修改真正的 WooCommerce 購物車。

這次從空購物車開始,加入兩件單價 1,290 元的機械鍵盤,再改成一件,最後移除。整條流程的重點是:每次都使用伺服器回傳的購物車,不自行猜測數量與總額。

本篇重點

  • 使用目前瀏覽器的 Cookie 工作階段,搭配 Store API Nonce。
  • 區分商品 ID 與購物車項目 key。
  • 區分「再加入幾件」與「總共改成幾件」。
  • 操作成功後,同步 Tool 回傳與頁面上的購物車。
  • 本篇實作簡單商品的加入;需要規格的商品回傳 needs_input。

一、先準備測試頁與商品

  1. 啟用 WooCommerce,將 WP WebMCP Lab 更新到 0.4.0。
  2. 沿用 Day 25 的「Day25 機械鍵盤」:本機 ID 101、已發佈、簡單虛擬商品、價格 1,290 TWD。
  3. 開啟網站首頁加上 ?webmcp_lab=26。本機網址為 https://wordpress.local/?webmcp_lab=26。
  4. 打開 WebMCP Inspector,確認下列六個工具。
Tool 用途 主要輸入
search_products 搜尋公開商品 keyword、maxPrice、limit
get_product 讀取商品詳情 productId
get_cart 讀取目前購物車 {}
add_to_cart 再加入指定件數 productId、quantity
update_cart_item 將一筆商品改成指定件數 key、quantity
remove_from_cart 移除整筆購物車商品 key

商品搜尋沿用 Day 25。換站操作時,使用該站搜尋結果中的 ID。

本頁操作會改變目前工作階段的購物車。使用獨立測試工作階段,才能從空車核對數量。重新整理頁面或按 Inspector Reset,都不會清空 WooCommerce 購物車。

二、Cookie 與 Nonce 各做什麼?

Cookie 讓伺服器辨認目前的購物車工作階段;Nonce 則用於 Store API 的請求驗證。本篇保留 Cookie,並用 Nonce header 傳送 Store API nonce。

Day 23 的 WordPress REST API 使用 wp_rest 與 X-WP-Nonce。本篇的 Store API 使用:

wp_create_nonce( 'wc_store_api' )

Day 26 的 PHP 將 URL 與 nonce 提供給自己的 JavaScript:

wp_localize_script(
    'wp-webmcp-cart',
    'wpWebMCPCart',
    array(
        'cartUrl' => esc_url_raw( rest_url( 'wc/store/v1/cart' ) ),
        'productsUrl' => esc_url_raw( rest_url( 'wc/store/v1/products' ) ),
        'nonce' => wp_create_nonce( 'wc_store_api' ),
    )
);

不要直接把 wc/store/v1/cart 接在網站網址後方;使用 rest_url() 才能配合目前的永久連結設定。本機使用 index.php?rest_route=...,範例也支援 /wp-json/...。

JavaScript 的請求核心如下:

let nonce = wpWebMCPCart.nonce;

const response = await fetch(url, {
  method: body ? 'POST' : 'GET',
  credentials: 'same-origin',
  cache: 'no-store',
  headers: {
    Accept: 'application/json',
    ...(nonce ? { Nonce: nonce } : {}),
    ...(body ? { 'Content-Type': 'application/json' } : {})
  },
  ...(body ? { body: JSON.stringify(body) } : {})
});

const nextNonce = response.headers.get('Nonce');
if (nextNonce) nonce = nextNonce;

這是請求核心節錄;完整程式另外處理輸入驗證、同源 URL、錯誤與畫面更新。Nonce 保留在 JavaScript 內,Tool 結果與頁面紀錄只顯示 nonceSent: true,不輸出它的值。

每次寫入前,範例先 GET 購物車,取得目前狀態及回應提供的 nonce,再送 POST。寫入完成後,直接使用 POST 回傳的購物車,不需要為了更新畫面再 GET 一次。

三、先讀取購物車

在 Inspector 的 Tool 選 get_cart,Input Arguments 填 {},按 Execute Tool。

空購物車的主要欄位如下:

{
  "status": "success",
  "cart": {
    "lineCount": 0,
    "totalQuantity": 0,
    "items": [],
    "totals": {
      "total": { "amount": 0, "currency": "TWD" }
    }
  }
}

這裡節錄主要欄位。完整回傳也包含商品金額、折扣、運費、稅額與是否需要配送。

lineCount 是商品項目筆數;totalQuantity 是所有項目的件數。相同鍵盤兩件通常是一筆商品、兩件,兩個數字用途不同。

圖片 1|get_cart 讀取目前工作階段的購物車,確認加入前的商品數量與總額。
https://ithelp.ithome.com.tw/upload/images/20261005/20121296Dl7qZoEmbf.png

四、加入兩件商品

先用 search_products 搜尋:

{"keyword":"鍵盤","maxPrice":2000,"limit":5}

本機符合條件的是 ID 101、1,290 TWD 的機械鍵盤。接著:

  1. Tool 改成 add_to_cart。
  2. Input Arguments 填入下面內容。
  3. 按 Execute Tool 一次,等待回傳。
{"productId":101,"quantity":2}

加入使用商品 ID。送到 Store API 時,欄位名稱改為 id:

POST /wc/store/v1/cart/add-item
{"id":101,"quantity":2}

範例在 POST 前先讀取商品,確認為簡單商品,再同步目前購物車。此次加入回傳 HTTP 201,JavaScript 用 response.ok 判斷成功,沒有將成功寫死成只接受 200。

圖片 2|add_to_cart 將商品 ID 與加入件數送到 Store API,成功回傳 HTTP 201。
https://ithelp.ithome.com.tw/upload/images/20261005/20121296O7ErVeKkpt.png

成功後,Tool 與左側「目前購物車」共同使用回傳資料,顯示:

  • 1 筆商品、2 件。
  • 機械鍵盤單價 1,290 TWD。
  • 目前購物車總額 2,580 TWD。

add_to_cart 的 quantity 是額外加入件數。再呼叫一次相同輸入,會再加兩件,不能把它當成設定總數。

圖片 3|加入兩件機械鍵盤後,購物車有 1 筆商品、2 件,總額為 2,580 TWD。
https://ithelp.ithome.com.tw/upload/images/20261005/20121296FIWjpo5zwR.png

金額使用 API 的 currency_minor_unit 換算。本機回傳 total_price: "258000"、小數位 2,因此是 2,580 TWD。畫面總額直接取自 totals.total_price,不以「單價 × 數量」取代伺服器計算。

本機商品為虛擬商品,needsShipping: false。實體商品還要查看配送狀態;shipping: null 表示尚未計算運費,不應解讀為免運。

五、修改與移除要用 key

商品 ID 用來找商品,購物車的 key 用來指定某一筆已加入的項目。

先從最新的 get_cart 或剛才操作回傳中取得該筆 key。以下的「目前項目的 key」要換成實際值。

把兩件改成一件

  1. Tool 選 update_cart_item。
  2. 輸入 key 與新的總件數。
  3. 按 Execute Tool,核對回傳數量與總額。
{"key":"目前項目的 key","quantity":1}

Store API 對應 POST /cart/update-item。這次回傳 HTTP 200,數量變成 1 件,總額 1,290 TWD。

範例將數量限制在 1~20;移除商品使用獨立的 remove_from_cart。

圖片 4|update_cart_item 使用購物車項目 key,把數量改為 1 件,總額同步更新為 1,290 TWD。
https://ithelp.ithome.com.tw/upload/images/20261005/20121296UDJ1Ln3W7e.png

移除這筆商品

Tool 改成 remove_from_cart,填入同一筆項目的 key,再按 Execute Tool:

{"key":"目前項目的 key"}

Store API 對應 POST /cart/remove-item,會移除整筆項目。本次回傳 HTTP 200,購物車回到 0 件、0 TWD。

圖片 5|remove_from_cart 移除指定項目後,購物車回到 0 件、0 TWD。
https://ithelp.ithome.com.tw/upload/images/20261005/20121296Sv87CkzyQF.png

「把第二個商品改成兩件」則需要先看目前的購物車清單,取出第二筆 key。第二個是清單位置,不是商品 ID 2,也不是字串 key "2"。

六、工具描述與錯誤處理也要跟上

get_cart 標記 readOnlyHint: true;加入、更新與移除標記為 false。所有 Schema 都設 additionalProperties: false,執行時也檢查整數、數量範圍和 key。

加入工具的描述明確說明三件事:

Use productId from search_products/get_product, never a list position.
Quantity is additional units.
Does not checkout or place an order.

更新工具則寫明 quantity 是新的總數。這些描述幫助 Agent 選擇工具;實際商品狀態、庫存與操作結果仍以 Store API 為準。

範例的回傳狀態如下:

status 情境 下一步
success 成功取得最新購物車 使用 cart 回答並更新畫面
invalid_input ID、key 或數量格式不合 修正參數
needs_input 商品需要規格或非簡單商品 到商品頁確認規格與加入方式
busy 同頁另一筆購物車操作尚未完成 等待前一筆結果
error API 回傳失敗 依 httpStatus、code 與 message 處理
unknown_outcome 已送出寫入,但未取得完整結果 先 get_cart 核對,不直接重送
internal_error 讀取、網路或資料格式問題 檢查後重新讀取

本機重複移除已不存在的 key,API 回傳 409 與目前購物車。程式會同步錯誤回應中的 cart,保留錯誤狀態;不把它改寫成移除成功。

規格商品的範圍

本篇的 add_to_cart 只接受簡單商品,不接受 variation 參數。檢查到需要規格的商品時,回傳 needs_input,不會選第一個尺寸或顏色。

後續擴充規格商品時,要取得 WooCommerce 實際的 variation ID 或 attribute/value,再按 Store API 的格式送出。Day 25 的屬性名稱與選項展示,不能直接當成完整的規格選擇器。

Cart-Token 的位置

Store API 也提供 Cart-Token 作為購物車識別方式,使用它時不需另外提供 Nonce。本篇固定使用 Cookie 工作階段加 Nonce;不將 Cart-Token 提供給 Agent 或放進操作紀錄。

七、本機實測結果

頁面按鈕與 Tool 共用相同的操作函式。本次透過頁面按鈕核對購物車畫面,並用獨立 Cookie 工作階段直接呼叫 Store API,測試下列結果:

操作 HTTP 結果
讀取空購物車 200 0 件、0 TWD
不帶 Nonce 加入商品 401 woocommerce_rest_missing_nonce
加入 ID 101、2 件 201 1 筆商品、2 件、2,580 TWD
同工作階段再次讀取 200 保留 2 件與 2,580 TWD
將該筆改成 1 件 200 1 件、1,290 TWD
移除該筆商品 200 0 件、0 TWD
再次移除相同 key 409 woocommerce_rest_cart_invalid_key

程式測試共 15 項通過,包含 Day 23~26 的回歸測試。Day 26 覆蓋數量語意、nonce 更新、兩種 REST URL、參數驗證、規格商品阻擋、409 同步、並行操作與寫入中斷後不重送。

八、Agent 操作測試清單

在 Inspector 的 User Prompt 輸入下列題目,按 Send,觀察工具呼叫。獨立案例先按 Reset;接續題目則保留前文,並核對目前購物車。

  1. 「找 2000 元以下的鍵盤,把搜尋到的機械鍵盤加入兩件,再告訴我目前購物車總額。」
  2. 接續:「把剛才的機械鍵盤改成一件。」
  3. 接續:「移除剛才的機械鍵盤,再查看購物車。」
  4. 「找 2000 元以下的鍵盤,把第二個加入兩件。」
  5. 「搜尋鍵盤,不限價格,列出結果。」再接續:「把第二個加入兩件。」

第 4 題是邊界測試:本機只有一筆符合預算,Agent 應說明沒有第二筆,不能改加第一筆。第 5 題則依前一次展示的商品清單,對應第二筆的實際 ID。

成功加入後若再呼叫一次 get_cart,可視為重新核對工作階段狀態,不直接判定為錯誤或多餘。

結論

購物車 Tool 的關鍵是讓「使用者說的數量」、「送出的操作」與「伺服器回傳的狀態」一致。

本次完成的流程是:空車 → 加入兩件 → 改成一件 → 移除。加入使用 productId,修改與移除使用 key;總額取自 API 回傳。這樣 Agent 才能清楚回答目前購物車,而不是只說一句「已加入」。

參考資料


上一篇
Day 25|「找 2000 元以下的鍵盤」怎麼接?用 WooCommerce Store API 做商品 Tool
系列文
WebMCP:30 天打造 AI Agent 看得懂、也操作得動的網站 共 26 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言