開發者模式 — Shopify 結帳整合 API
當其他應用程式或自訂結帳腳本與 HK Pickup 自動攔截結帳衝突,或你需要完全控制何時開啟配送對話框及如何繼續結帳時,請使用 開發者模式。
在 Shopify App Store 安裝 HK Pickup →
| 情況 | 開發者模式 |
|---|---|
| 單一 HK Pickup 安裝,預設結帳 | 關(建議) |
| 其他應用程式攔截結帳 | 開——自行串接 hkpickup.open() |
| 自訂結帳/無頭流程 | 開——監聽 hkpickup:* 事件 |
開發者模式 開啟時,HK Pickup 不會綁定結帳按鈕。除非你加入自訂 JavaScript,否則按結帳會直接前往 Shopify。
需要以自訂 JavaScript 控制「誰會看到對話框」?請用 開發者模式。從其他自取應用程式遷移時的一般正式結帳,請改用 試用模式——無需自訂程式碼。
有些其他應用程式擁有結帳按鈕,而且一律開啟自己寫死的 /checkout。它們不會使用 HK Pickup 的地址網址。預設模式無法攔截該次點擊。請保持開發者模式開啟,並覆寫它開啟的網址上的地址。
在佈景主題編輯器啟用
Section titled “在佈景主題編輯器啟用”- Online Store → Themes → Customize(網上商店 → 佈景主題 → 自訂)
- App embeds → HK Pickup
- 開啟 Developer mode(開發者模式)
- Save(儲存)
HK Pickup 仍負責什麼
Section titled “HK Pickup 仍負責什麼”| 職責 | 負責方 |
|---|---|
| 顯示配送對話框 UI | HK Pickup(當你呼叫 open() 時) |
寫入購物車屬性(_sf_delivery_mode、_sf_pickup_*) |
HK Pickup——在 home/confirm 事件之前 |
| 前往結帳/提交購物車表單 | 你(整合者) |
若 /cart/update.js 失敗,HK Pickup 會在對話框顯示錯誤,且不會觸發 home 或 confirm 事件。
命令式 API(window.hkpickup)
Section titled “命令式 API(window.hkpickup)”只在開發者模式開啟時可用。
| 成員 | 說明 |
|---|---|
isReady |
初始化及店面設定載入後為 true |
open() |
重設至第 1 步、顯示對話框、觸發 hkpickup:open |
close(options?) |
{ force?: boolean }——關閉對話框;觸發不可取消的 hkpickup:close,reason: 'api'。若先前阻止了 home/confirm 關閉,非同步工作完成後使用 force: true |
所有事件均為 document 的 CustomEvents,前綴為 hkpickup:。
在 hkpickup:ready 之後註冊監聽器(或檢查 window.hkpickup?.isReady)。
| 事件 | 時機 | detail |
|---|---|---|
hkpickup:ready |
初始化完成 | { developerMode: true, locale } |
hkpickup:open |
透過 open() 開啟對話框 |
{ source: 'api' } |
hkpickup:close |
對話框關閉前(開發者模式) | { reason }——見下方可取消規則 |
hkpickup:home |
選擇送貨上門(屬性已清除) | { cartAttributes } |
hkpickup:back |
從順豐列表返回 → 第 1 步 | {} |
hkpickup:location-select |
選中順豐列 | { store } |
hkpickup:confirm |
順豐確認(屬性已儲存) | { store, checkoutUrl, cartAttributes } |
不會觸發: 第 1 步「順豐速運自取」(僅內部)、篩選/搜尋變更。
store 物件
Section titled “store 物件”{ "code": "H852K067P", "type": "store", "category": "store", "name": "SF Station …", "address": "…", "area": "HK", "region": "Hong Kong Island", "city": "Central", "district": "Central", "province_code": "HK"}area 為 HK 或 MO。province_code 是 Shopify 的香港區域代碼(HK、KL 或 NT);澳門或無法對應地區時為 null。
cartAttributes 鍵
Section titled “cartAttributes 鍵”| 鍵 | 送貨上門 | 自取 |
|---|---|---|
_sf_delivery_mode |
home |
pickup |
_sf_pickup_code |
"" |
順豐編號 |
_sf_pickup_type |
"" |
服務類型 |
_sf_pickup_address |
"" |
地址 |
_sf_pickup_region |
"" |
區域 |
_sf_pickup_district |
"" |
地區 |
_sf_pickup_locale |
"" |
zh-HK / zh-CN / en-US |
若商戶在管理設定取消勾選 Save SF Express details on the order,送貨上門及自取時以上所有鍵均為 "",HK Pickup 亦會把這些空值寫入購物車。如需自取點資料,請改用 detail.store。
可取消關閉(hkpickup:close)
Section titled “可取消關閉(hkpickup:close)”只有 home 及 confirm 關閉原因可取消。監聽器可同步呼叫 event.preventDefault() 以保持對話框開啟(例如另一個外掛正在執行時)。
detail.reason |
可取消? | 行為 |
|---|---|---|
home |
是 | 在 hkpickup:home 之後 |
confirm |
是 | 在 hkpickup:confirm 之後 |
dismiss |
否 | X 按鈕或背景——一律關閉 |
api |
否 | hkpickup.close()——一律關閉 |
非同步模式:
document.addEventListener('hkpickup:close', (e) => { if (e.detail.reason !== 'confirm') return e.preventDefault() runOtherPlugin().finally(() => window.hkpickup.close({ force: true }))})事件順序(home/confirm): 購物車屬性儲存 → hkpickup:home 或 hkpickup:confirm → 可取消的 hkpickup:close → 除非被阻止否則關閉。
Dawn 範例——自行攔截結帳
Section titled “Dawn 範例——自行攔截結帳”加入佈景主題自訂 JavaScript(或你的應用程式資源):
document.addEventListener('hkpickup:ready', () => { document.querySelectorAll('button[name="checkout"]').forEach((btn) => { btn.addEventListener('click', (e) => { e.preventDefault() window.hkpickup.open() }) })})
document.addEventListener('hkpickup:home', () => { window.location.href = '/checkout'})
document.addEventListener('hkpickup:confirm', (e) => { window.location.href = e.detail.checkoutUrl})若結帳按鈕不同,請為你的佈景主題調整選擇器。
當你的腳本負責開啟結帳時,才用上面的確認處理。detail.checkoutUrl 已包含自取地址。若另一個應用程式擁有結帳按鈕並寫死 /checkout,你無法自行把購物者送到該網址。見 覆寫寫死的結帳網址。
覆寫寫死的結帳網址
Section titled “覆寫寫死的結帳網址”預設模式無法運作時使用這段。另一個應用程式已接管結帳按鈕,而且一律以寫死的路徑結束:
window.location.href = '/checkout'// 或window.location.replace('/checkout')該指定常常包在閉包函式裡,你無法改變該應用程式把購物者送到哪裡。保留它的導向,並覆寫它開啟的網址上的地址。
自取對話框仍會完成,購物者仍會進入結帳,但送貨地址欄位是空的。自取選擇本身已儲存。_sf_pickup_code、_sf_pickup_address 等購物車屬性會留在購物車,之後也會留在訂單上。這些屬性不會填入結帳表單。Shopify 是用結帳網址上的查詢參數預填該表單:
checkout[shipping_address][first_name]、checkout[shipping_address][last_name](只限已登入顧客)checkout[shipping_address][address1]checkout[shipping_address][address2]checkout[shipping_address][city]checkout[shipping_address][province]checkout[shipping_address][country]
HK Pickup 會組出該網址,並在確認事件上以 event.detail.checkoutUrl 提供。開發者模式下它不會自行導向。它會更新購物車、派發 hkpickup:confirm 或 hkpickup:home,然後關閉。
寫死的 /checkout 沒有這些參數,所以 HK Pickup 已經組好的網址被忽略。直接指定 location.href 也不會提交購物車表單,而那是帶上隱藏欄位 checkout[shipping_address][...] 的另一個方式。POST /cart/update.js 可以更新備註、屬性與商品數量。它不能設定結帳送貨地址。
地址必須在該寫死導向發生當下,合併回網址。
把地址放回網址
Section titled “把地址放回網址”保留 detail.checkoutUrl 的查詢字串。在 hkpickup:confirm 時存下來。送貨上門時,若 detail.checkoutUrl 不存在就清掉,避免較早的自取地址漏進送貨上門的結帳。
監聽 Navigation API。若導向是同源、路徑為 /checkout 或 /checkout/、可以取消,且尚未包含 checkout[shipping_address][address1],就取消它,再把 location.href 指定到同一個網址並加上已儲存的地址參數。原有的查詢參數保留。
let address = null
document.addEventListener('hkpickup:confirm', (event) => { const checkoutUrl = event.detail.checkoutUrl address = checkoutUrl ? new URL(checkoutUrl, location.origin).searchParams : null})
document.addEventListener('hkpickup:home', (event) => { if (!event.detail.checkoutUrl) address = null})
if (window.navigation) { navigation.addEventListener('navigate', (event) => { if (!address || !event.cancelable) return const url = new URL(event.destination.url) if (url.origin !== location.origin || !/\/checkout\/?$/.test(url.pathname)) return if (url.searchParams.has('checkout[shipping_address][address1]')) return address.forEach((value, name) => { url.searchParams.set(name, value) }) event.preventDefault() location.href = url.toString() })}用 if (window.navigation) 包住監聽器。沒有這個 API 時,對話框與結帳重新導向仍會執行。只是略過地址預填。
| 瀏覽器 | 版本 | 發布日期 |
|---|---|---|
| Chrome、Edge | 102 | 2022 年 5 月 24 日 |
| Safari、iOS | 26.2 | 2025 年 12 月 12 日 |
| Firefox | 147 | 2026 年 1 月 13 日 |
26.2 之前的 Safari 與 147 之前的 Firefox 無法攔截 location.href。一個可能的後備做法,是在純 /checkout 指定之後,再把 location.href 指定到帶地址的網址。最後一次指定會生效,但必須發生在第一次之後。太早指定會被 /checkout 覆寫。
香港結帳表單的區域
Section titled “香港結帳表單的區域”Shopify 香港結帳的區域只接受 香港島、九龍 或 新界,其他值會被換成第一個選項。HK Pickup 會按 store.province_code 送出對應代碼(HK、KL 或 NT),所以新界自取點會顯示 新界。無法對應地區時不會送出省份。澳門自取點照送順豐的地區文字。自行重組網址時請保留這些參數。
Shop Pay 會拒絕沒有收件人姓名的預填地址,所以顧客已登入時會附上 first_name / last_name。
除錯——記錄所有事件
Section titled “除錯——記錄所有事件”貼到 DevTools 主控台,然後重新載入:
;['ready','open','close','home','back','location-select','confirm'].forEach((n) => document.addEventListener(`hkpickup:${n}`, (e) => console.log(`hkpickup:${n}`, e.detail, e.cancelable ? '(cancelable)' : '') ))串接結帳後,在 驗證結帳 執行相同檢查。