跳转到内容

開發者模式 — Shopify 結帳整合 API

當其他應用程式或自訂結帳腳本與 HK Pickup 自動攔截結帳衝突,或你需要完全控制何時開啟配送對話框及如何繼續結帳時,請使用 開發者模式。

在 Shopify App Store 安裝 HK Pickup →


情況 開發者模式
單一 HK Pickup 安裝,預設結帳 關(建議)
其他應用程式攔截結帳 開——自行串接 hkpickup.open()
自訂結帳/無頭流程 開——監聽 hkpickup:* 事件

開發者模式 開啟時,HK Pickup 不會綁定結帳按鈕。除非你加入自訂 JavaScript,否則按結帳會直接前往 Shopify。

需要以自訂 JavaScript 控制「誰會看到對話框」?請用 開發者模式。從其他自取應用程式遷移時的一般正式結帳,請改用 試用模式——無需自訂程式碼。

有些其他應用程式擁有結帳按鈕,而且一律開啟自己寫死的 /checkout。它們不會使用 HK Pickup 的地址網址。預設模式無法攔截該次點擊。請保持開發者模式開啟,並覆寫它開啟的網址上的地址。


  1. Online Store → Themes → Customize(網上商店 → 佈景主題 → 自訂)
  2. App embeds → HK Pickup
  3. 開啟 Developer mode(開發者模式)
  4. Save(儲存)

職責 負責方
顯示配送對話框 UI HK Pickup(當你呼叫 open() 時)
寫入購物車屬性(_sf_delivery_mode、_sf_pickup_*) HK Pickup——在 home/confirm 事件之前
前往結帳/提交購物車表單 你(整合者)

若 /cart/update.js 失敗,HK Pickup 會在對話框顯示錯誤,且不會觸發 home 或 confirm 事件。


只在開發者模式開啟時可用。

成員 說明
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 步「順豐速運自取」(僅內部)、篩選/搜尋變更。

{
"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。

鍵 送貨上門 自取
_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。


只有 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 → 除非被阻止否則關閉。


加入佈景主題自訂 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,你無法自行把購物者送到該網址。見 覆寫寫死的結帳網址。


預設模式無法運作時使用這段。另一個應用程式已接管結帳按鈕,而且一律以寫死的路徑結束:

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 可以更新備註、屬性與商品數量。它不能設定結帳送貨地址。

地址必須在該寫死導向發生當下,合併回網址。

保留 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 覆寫。

Shopify 香港結帳的區域只接受 香港島、九龍 或 新界,其他值會被換成第一個選項。HK Pickup 會按 store.province_code 送出對應代碼(HK、KL 或 NT),所以新界自取點會顯示 新界。無法對應地區時不會送出省份。澳門自取點照送順豐的地區文字。自行重組網址時請保留這些參數。

Shop Pay 會拒絕沒有收件人姓名的預填地址,所以顧客已登入時會附上 first_name / last_name。


貼到 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)' : '')
)
)

串接結帳後,在 驗證結帳 執行相同檢查。