WooCommerce Store API 實戰(三)- 建立訂單

前情提要:API 提供了以程式互動為主的操作介面,讓工程師可以開發出更多自動化的流程,業界最流行的 API 瀏覽器 Postman 以清晰的介面讓工程師可以測試 API 的各項功能,而 WooCommerce Store API 可以實現許多結帳行為。

除了取得商品列表、商品規格、加入購物車以外,WooCommerce Store API 的重頭戲當然就是結帳付款囉~雖然這些功能可以自己開發 API 來處理,但牽涉到電子商務,裡面的魔鬼絕對是一大堆,尤其是安全性的部分,因此這 API 是由官方開發的話相對來說會安全的多,畢竟有全世界的工程師在幫忙盯著XD

Store API 使用折價券

前篇文章我們成功將加商品加入購物車了,先打開 Postman 來查看一下購物車裡面的商品,以 GET 的方式請求 /cart,可以看到有兩樣商品總金額為 NT1,650 元:

我有準備好一張折價券「nywjjtsz」可以打 9 折,因此使用折價券後購物車小計應該會變成 1650*0.9=1,485 元,使用折價券的方式為以 POST 請求 /cart/coupons/,並帶入一個參數 code:

加入成功後會回傳折扣的金額,這時候再用 GET /cart 就能在最上面的 coupons 陣列看到目前使用中的折價券:

有個地方需要注意的是假設我要移除折價券,使用的是 DELETE 請求 /cart/coupons/nywjjtsz,成功後是沒有回傳任何訊息的,翻了程式碼發現到 /cart/coupons 請求後回傳的是折價券詳細資料,因此當刪除折價券就不會回傳任何資訊:

這部分在前端實作 Ajax 的時候需要多一個檢查,不然拿不到回傳資料可能會發生預期外的錯誤,比較好的作法可能是在請求完折價券後再去呼叫 /cart,並以購物車裡面回傳的資訊來做畫面的顯示。接下來我們測試結帳流程。

Store API 結帳流程

在 WooCommerce 的結帳流程中通常是以下幾個步驟:

  1. 查看購物車 /cart
  2. 前往結帳頁 /checkout
  3. 在結帳頁輸入帳單地址與運送地址
  4. 在結帳頁選擇運送方式
  5. 在結帳頁選擇付款方式
  6. 在結帳頁送出訂單

但 Store API 的流程有點不太一樣,步驟三跟四是放在請求路徑 /cart 裡面,五跟六才是放在 /checkout 裡面來請求,也就是說 cart 裡面管理所有除了付款方式以外的結帳相關資訊,我一開始在 /checkout 裡面找運送方式的傳送參數卻找不到,原來是躲在 /cart 裡面…

接下來我們先輸入帳單與運送地址,以 POST 的方式請求 /cart/update-customer,要送的參數很多,但不外乎就是你熟悉的 billing_address 或是 shipping_address 那些,每個欄位都是非必填:

成功後會回傳 cart 的內容,就能看到 billing 與 shipping 的資料更新為我們所提供的內容,在實務上這邊會增加自訂欄位,可能是顧客的年紀、性別,或是常見的電子發票欄位,Store API 提供了 woocommerce_store_api_cart_update_customer_from_request 勾點來擴充欄位:

可以用 $request 拿到我們自己傳的參數,像是 {"invoiceType":"company"},然後在勾點裡面用 $request["invoiceType"] 取得發票開立類型為三聯式發票,然後用 set_props() 來更新顧客的資料,第 127 行的 $customer->save() 就會自動幫我們寫入資料庫。

所以如果你有用 Checkout Field Editor 之類的外掛來加入新的結帳欄位也可以用這個勾點來處理,其他還有像是選擇超商的資料回傳,在接下來的實作中我也會試著把這些欄位整合進去。下一步我們來選擇運送方式,以 POST 方式請求 /cart/select-shipping-rate,並且傳 package_id 與 rate_id。

package_id 與 rate_id 該去哪裡找?我們先 GET /cart 來查看 shipping_rates,裡面就有 package_id 以及 rate_id:

找到這兩個資訊後就能設定購物車的運送方式,我們這邊以單一費率為例:

請求成功後就可以看到在該運送方式的 selected 參數變為 true 就代表已經選中,這邊有一個問題是 Store API 目前沒有支援運送類別的回傳,也就是說如果你想要針對運送類別來設定運費只靠 Store API 是無法辦到的,查看原始碼也沒有勾點可以擴充。

另外免運費的設定條件也是沒有的,說如果你在後台設定單一費率在購物車金額超過 100 元時運費變 0 元,這在目前的 Store API 中也是無法判斷的,解法是只能開自己的 API 來處理,像是用 GET 請求 /cart/rate/instance_id 這樣來取得這些附加資訊,或是只能寫信請官方加入勾點。

Store API 送出訂單

輸入完結帳資料後,最後就是選擇付款方式並送出訂單,我這邊選擇使用綠界信用卡結帳,以 POST 方式請求 /checkout,並帶入傳送參數 payment_method 為金流 ID:

除了 payment_method 參數要傳之外,還需要帶入 billing 與 shipping_address,這讓我不太理解,明明在 cart 的地方都已經處理好了最後 checkout 卻還要再傳一次顯得有些多餘,看程式碼的說明是因為結帳時要寫入顧客資料,所以要再傳入一次以確保這些資料是最新的。

所以在前端處理的時候可能要先把 billing 跟 shipping 的存起來,以便在結帳時再傳送一次。因為綠界是第三方金流,實際的付款是在綠界那邊,Store API 會回傳跳轉網址,這樣就能在前端處理頁面的跳轉:

當請求完成後就可以在後台看到這張訂單了,Store API 有避免重複送出訂單的機制,但當我回去用 GET 查看 /cart 的時候發現到購物車裡面的資訊並未被清空,由於 Store API 是靠著 Cookie 來紀錄購物車的內資料,我們可以在 Postman 的 Cookies 頁面中看到:

當我們把這三個 Cookie 都刪除後就可以看到購物車被清空了,因此在實作結帳完成之後要把 Cookie 刪掉才能清空購物車,但如果你想保留部分資料像是顧客姓名,那麼就能 POST /cart/remove-item 來整理購物車內的商品。

在 /checkout 的部分還有一個特別的參數值得一提,那就是我們可以用 payment_data 來帶入一些付款的附加資訊,這可以用在什麼地方呢?最常見的就是分期付款的分期期數,我以綠界信用卡分期付款來測試這個參數。

首先我們先結帳頁找到綠界信用卡分期付款的欄位名稱以及值,用開發者工具就可以找到:

這個欄位叫做 ecpay_number_of_periods,可選值為期數數字,這時候我們就可以用 payment_data 來帶入這個參數,我一開始帶錯,以為只要用 key:value 也就是 “ecpay_number_of_periods”:”3″ 就能搞定,結果翻了原始碼才知道不是這樣寫,正確寫法如下:

要一組 key 名稱叫做 「key」跟「value」的陣列才能正確接收,value 的部分只支援字串與布林值,因此雖然我們傳送的是數字 3,但還是記得要加引號用字串來送才是正確的,這樣就能跳轉到綠界信用卡分期付款的畫面。

到這邊基本的結帳流程我們都走過一遍了,不知道你有沒有跟我一樣對於 Store API 感到興奮不已,它可以完全釋放 WooCommerce 的威力,不用再被綁在範本檔案裡面,實現各種客製化的結帳頁面,但同時我們也知道了他的限制,包含運送類別以及會員機制的處理,同時他也沒有取得所有付款方式的 API,這些我們可能都要自己來了。

因此接下來我會先開發我們所需要的 API,並且學習 Store API 的程式碼架構來進行設計,搞不好寫完後還能直接貢獻給開發團隊,下一篇來深入研究 Store API 的程式碼!

文章標籤Store API

目錄

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

賴俊吾 / Oberon Lai
賴俊吾 / Oberon Lai

現為全職 WordPress 工程師,網站開發經歷 11 年,專攻前端工程與 WordPress 佈景主題、外掛客製化開發

訂閱電子報

Hi,我是 Oberon,我會固定在每週五早上發送接案心得以及與 WordPress 相關的電子報,同時也會分享一些實用的開發知識,讓你在 WordPress 的接案路上不孤單!

專注於分享 WordPress 開發、接案技巧、專案管理等自由工作者必備知識與心得

© 2024 想點創意科技有限公司

想點創意科技有限公司 | 統一編號 90516823
Designed by Hend Design | 隱私權政策

訂閱電子報

Hi,我是 Oberon,我會固定在每週五早上發送接案心得以及與 WordPress 相關的電子報,同時也會分享一些實用的開發知識,讓你在 WordPress 的接案路上不孤單!