Yuruicamp

Payment API Contract(v0.1)

欄位 內容
狀態 Locked(線 D 待實作)
日期 2026-07-20
版本 0.1
共用 common-api-conventions.md
DB payment_methodpayment_status ENUM、payment_notificationsordersbookings
ENUM schema-enums.md

0. 一句話

線上付款只走 ECPayNotifyURL 是付款真相;COD 僅商城且履約後才 paid;預約禁止 COD


1. payment_method(寫死)

用途
ecpay-credit 綠界信用卡
ecpay-atm 綠界 ATM
ecpay-cvs 綠界超商
ecpay-other 其他綠界通道
cod 貨到付款(僅 orders;bookings CHECK 禁止)

2. 端點

方法 路徑 認證 說明
POST /api/checkout/sessions/{orderId}/ecpay 會員 商城:取得綠界表單欄位
POST /api/booking/checkout/sessions/{bookingId}/ecpay 會員 預約:同上
POST /api/payments/ecpay/notify Bearer;驗簽 綠界背景通知(真相)
GETPOST /api/payments/ecpay/return 無/弱 導回前端成功/失敗頁(不當付款真相)
POST /api/checkout/sessions/{orderId}/confirm-cod 會員 商城 COD 確認(見 Checkout)

3. POST …/ecpay 回應 — EcpayLaunch

JSON 型別 說明
orderIdbookingId string 業務單號
merchantTradeNo string 送綠界的商店訂單編號(需可對回 DB)
actionUrl string 綠界表單 POST URL(沙箱/正式)
fields object key→value,前端組 hidden form 提交
expiresAt string 與結帳截止對齊

在此回應宣告 paymentStatus=paid

本機未接綠界時可用 stub:actionUrl 指測試頁或回傳固定 fields,並在文件標 yuruicamp.ecpay.stub=true


4. Notify — POST /api/payments/ecpay/notify

4.1 行為(寫死)

  1. 驗綠界簽章;失敗 → 非 200/依綠界要求回應
  2. merchantTradeNo(等)對應 ordersbookings
  3. 寫入 payment_notifications(冪等):
    • 首次成功:result=success → 更新 payment_status=paidpaid_at
    • 重複:result=ignored_duplicate改狀態兩次
    • 失敗:result=failed
  4. 商城:相關 product_stock_reservationsfulfilled(規則在 Service)
  5. 回給綠界的 body/狀態碼依綠界文件(實作時鎖死一種)

4.2 payment_notifications 對照(內部,可不直接曝 API)

DB 說明
provider 固定 ecpay
merchant_trade_no 商店訂單號
provider_trade_no 綠界交易號
order_id XOR booking_id 二擇一
raw_payload jsonb 原文
result success | ignored_duplicate | failed

5. Return URL


6. COD(僅商城)

步驟 payment_status 說明
confirm-cod unpaid 已成立訂單,未收款
後台履約完成(規則實作時定:出貨或 completed) paid Service 更新;paid_at

預約任何嘗試設 cod → 400/409(DB 亦有 ck_bookings_no_cod)。


7. v0.1 不做

項目 原因
LINE Pay/舊 credit-card 字串 ENUM 已移除
部分退款細 API 後續;DB 有 refund_status 可先保留欄位
信用卡號經自家 API 全部在綠界

Changelog

版本 日期 說明
0.1 2026-07-20 ECPay 真相在 Notify;COD 僅商城