Skip to Content
概念訂單

訂單

如果 CheckoutSession 是買家看到的, Order 就是在意的。它是以下事項的永久紀錄:

  • 買的是什麼(商品項目)
  • 該付多少、實際付了多少
  • 待處理與已套用的退款
  • 你的外部參考(external_ref)— 通常是你自己的訂單 ID,儲存在 Order 上並透過 GET /b2b/v1/orders/{id} 回傳(不會在 webhook 酬載中回顯 — 見下文)

CheckoutSession 在其某個 PaymentIntent 結算或 TTL 過期後就會死亡。 Order 永遠存在。

Order 何時被建立

當你呼叫 POST /b2b/v1/checkout-sessions/quick 時,payment-service 會在一個 transaction 中同時建立一個新 Order 一個新的 CheckoutSession。如果你已經有 Order 且想重試結帳(例如買家放棄 之後),請改用 POST /b2b/v1/checkout-sessions 將新 session 附到 既有訂單 — 保留稽核軌跡。

生命週期

狀態意義
DRAFT保留給未來的草稿流程。目前沒有任何程式碼路徑會建立 DRAFT 訂單 — 每個訂單都是以 PENDING 建立,所以你不會觀察到此狀態。
PENDING一個 CheckoutSession 仍有效且未結算。
PAID全額已結算。webhook payment.settled 在這裡觸發。 可以安全履約。
PARTIAL_PAID資金已到但少於總額。請看下方「短付」。
CANCELEDSession 過期或商家取消。metadata.canceled_reason 說明原因(payment_timeoutmerchant_canceled 等)。
REFUNDED所有已付金額都已退款。
PARTIALLY_REFUNDED部分退款已執行,但仍有已付餘額。

你應該以 PAID 作為履約邏輯的切換點 — 而非 CheckoutSession 的 COMPLETEDpayment.settled webhook 是規範訊號。

external_ref 欄位

建立 session 時可以帶 external_ref(任意字串,最多 255 字 — 通常 是你自己的訂單 ID)。它會貫穿整個管線:

  • 儲存於 Order 上
  • 在商家儀表板可見,方便 support 查詢
  • GET /b2b/v1/orders/{id} 上回傳,讓 webhook handler 在收到 payment.settled 後可以查到它

Webhook 酬載目前不會直接回顯 external_ref — 本文件先前的草稿 曾聲稱 data.external_ref 會貫穿到每個事件,那是錯誤的。要把 payment.* webhook 對應回你的 DB 列,請從 payload 中取 order_id 再去查詢訂單。在 webhook payload 中原生帶 external_ref 在路線圖上。

短付

若買家的鏈上轉帳結算金額少於訂單總額,Order 會進入 PARTIAL_PAID。 你有三個選項:

  1. 接受並解析。 把訂單翻為 PAID 並發出 order.resolved。這不是 公開 REST endpoint — resolve 目前是內部 / 維運動作,所以對於自助 流程請優先採用選項 2(收集差額)。
  2. 等待差額。 對同一個 Order 建立新的 CheckoutSession,amount_due 為剩餘額。買家補上差額;結算後 Order 移到 PAID
  3. 取消並退款。 退還已付的部分並取消 Order。買家需自行負擔鏈上 手續費。

產品端沒有特別推薦哪一個 — 不同商家想要不同政策。請選擇一個並落實 在你的 admin 工具中。

退款

退款是獨立的 API 介面與獨立的概念頁面。請見概念 → 退款

API endpoints

MethodPath備註
POST/b2b/v1/orders不建立 session 直接建立 Order(罕見)
GET/b2b/v1/orders/:order_id讀取完整訂單,含商品項目 + 付款歷史
PATCH/b2b/v1/orders/:order_id/cancel取消未付款訂單
PATCH/b2b/v1/orders/:order_id/reopen重新開啟自動取消(payment_timeout)的訂單

下一步