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

建立 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)
modePAYMENTSUBSCRIPTIONSETUP;未指定時依商品類型自動判斷
customer_email預填客戶 Email(未提供時由結帳頁向付款者收集)
customer_name預填客戶姓名
external_customer_id您系統中的用戶 ID。無論 email 是在建立時提供或結帳頁才收集,都會套用到該 Session 建立/連結的客戶,詳見客戶身份綁定
promotion_code預先套用的優惠碼(建立時即驗證與計算折扣)
collect_payment_methodalways(預設)或 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 為準進行開通;此端點適合重新導向頁的即時確認與除錯。

錯誤

HTTPcode情境
400bad_requestJSON 格式錯誤、Publishable Key 帶 metadata
401unauthorizedAPI Key 無效
404not_found商品不存在或未上架(含存取其他組織的商品)
409conflict客戶已有該商品的有效訂閱,詳見錯誤代碼
422validation_error請求本文驗證失敗(含 einvoice 格式錯誤,如統編檢查碼不符、手機條碼格式錯誤)

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

Last updated on