Recur Docs

Checkout Session 是 Hosted Checkout 的核心資源。在後端建立 Session 後,將用戶導向回傳的 url,即可在 Recur 託管的結帳頁面完成付款。

欄位命名:回應一律使用 snake_case(如 external_customer_id)。請求本文接受 snake_case(建議)與 legacy camelCase 兩種寫法。

認證

建立與查詢端點都支援 Secret Key(Authorization: Bearer sk_xxx)與 Publishable Key(X-Recur-Publishable-Key: pk_xxx)。差異:

  • Publishable Key 不可設定 metadata(server-only 欄位)
  • 建議在後端以 Secret Key 建立 Session

作廢端點只接受 Secret Key。

建立 Checkout Session

POST https://api.recur.tw/v1/checkout/sessions

請求參數

參數必填說明
product_id✅*商品 ID(與 product_slug 二擇一)
product_slug✅*商品 Slug(與 product_id 二擇一)
success_url✅成功後的重新導向 URL(HTTPS,支援 {CHECKOUT_SESSION_ID} 佔位符)
cancel_url✅取消時的重新導向 URL(HTTPS)
mode❌PAYMENT、SUBSCRIPTION、SETUP;未指定時依商品類型自動判斷
customer_email❌預填客戶 Email(未提供時由結帳頁向付款者收集)
customer_name❌預填客戶姓名
external_customer_id❌您系統中的用戶 ID。無論 email 是在建立時提供或結帳頁才收集,都會套用到該 Session 建立/連結的客戶,詳見客戶身份綁定
promotion_code❌預先套用的優惠碼(建立時即驗證與計算折扣)
collect_payment_method❌always(預設)或 if_required(零元結帳免綁卡)
metadata❌自訂 metadata(僅 Secret Key 可用)
einvoice❌買家電子發票選擇(Publishable Key 也可用),用於預填結帳頁的發票資訊區塊。格式錯誤(如統編檢查碼不符)回 422,詳見電子發票

範例

curl -X POST https://api.recur.tw/v1/checkout/sessions \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": "prod_abc123",
    "mode": "SUBSCRIPTION",
    "success_url": "https://example.com/success?session_id={CHECKOUT_SESSION_ID}",
    "cancel_url": "https://example.com/pricing",
    "external_customer_id": "user_123"
  }'

回應(201):

{
  "id": "cs_abc123xyz",
  "url": "https://checkout.recur.tw/cs_abc123xyz",
  "expires_at": "2025-01-01T00:30:00Z",
  "amount": 29900,
  "requires_payment_method": true,
  "livemode": true
}
欄位說明
idSession ID
url導向用戶的結帳頁 URL
expires_atSession 到期時間(建立後 30 分鐘)
amount折扣後實際金額
requires_payment_method是否需要收集信用卡(零元結帳時可能為 false)
client_secret(選)PaymentIntent client secret,供前端 SDK 輪詢狀態
discount(選)套用優惠碼時的折扣明細
einvoice_enabled組織是否已啟用電子發票自動開立(可據此決定是否收集發票資訊)
livemode是否為正式環境

查詢 Checkout Session

GET https://api.recur.tw/v1/checkout/sessions/{id}

用於付款完成重新導向後確認 Session 狀態,或稽核 Session 上儲存的值。

回應(200):

{
  "id": "cs_abc123xyz",
  "status": "COMPLETE",
  "mode": "SUBSCRIPTION",
  "customer_email": "user@example.com",
  "external_customer_id": "user_123",
  "order_id": "ord_xyz789",
  "subscription_id": "sub_def456",
  "payment_intent_id": "pi_ghi012",
  "setup_intent_id": null,
  "amount_total": 29900,
  "currency": "TWD",
  "product": { "id": "prod_monthly", "name": "Monthly Plan" },
  "expires_at": "2025-01-01T00:30:00Z",
  "created_at": "2025-01-01T00:00:00Z",
  "completed_at": "2025-01-01T00:05:00Z",
  "livemode": true
}
欄位說明
statusOPEN(等待付款)、COMPLETE(付款完成)、EXPIRED(已過期)
customer_email建立時預填或結帳頁收集到的 Email
external_customer_id建立 Session 時帶入的外部客戶 ID(可用於稽核綁定值)
subscription_id訂閱建立後回填(SUBSCRIPTION mode)

付款完成後,建議以 checkout.completed webhook 為準進行開通;此端點適合重新導向頁的即時確認與除錯。

作廢 Checkout Session

POST https://api.recur.tw/v1/checkout/sessions/{id}/expire

讓尚未付款的 Session 立即失效,顧客無法再透過它付款。適用情境:顧客改選了另一個方案、你為他建立了新的 Session,要避免舊的那個也被付款。

  • 不需要請求本文,只接受 Secret Key。
  • 成功時回傳與查詢相同格式的 Session,status 為 EXPIRED,expires_at 為作廢的時間。
  • Session 的付款(Payment Intent)與待付款的訂單會一併取消。
  • 對已經是 EXPIRED 的 Session(包含超過 30 分鐘自然過期的)再呼叫一次,同樣回傳 200。
curl -X POST https://api.recur.tw/v1/checkout/sessions/cs_abc123xyz/expire \
  -H "Authorization: Bearer sk_test_xxx"

付款已開始時無法作廢:Session 已完成付款(COMPLETE),或顧客的付款正在處理中、正在進行 3D 驗證時,回傳 409 conflict,Session 維持原狀。這時顧客仍可能付款成功,請以 checkout.completed webhook 為準。

作廢不會發送 webhook,回傳的 Session 即為結果。

錯誤

HTTPcode情境
400bad_requestJSON 格式錯誤、Publishable Key 帶 metadata
401unauthorizedAPI Key 無效
404not_found商品不存在或未上架(含存取其他組織的商品)
401unauthorized作廢時使用 Publishable Key
404not_found查詢或作廢的 Session 不存在,或屬於其他組織。作廢時另含金鑰環境不符(如以測試金鑰作廢正式環境的 Session)
409conflict建立時:客戶已有該商品的有效訂閱,詳見錯誤代碼。作廢時:Session 已完成,或付款已開始
422validation_error請求本文驗證失敗(含 einvoice 格式錯誤,如統編檢查碼不符、手機條碼格式錯誤)

完整錯誤格式請見錯誤代碼。

Last updated on