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) |
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
}
| 欄位 | 說明 |
|---|---|
id | Session ID |
url | 導向用戶的結帳頁 URL |
expires_at | Session 到期時間(建立後 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
}
| 欄位 | 說明 |
|---|---|
status | OPEN(等待付款)、COMPLETE(付款完成)、EXPIRED(已過期) |
customer_email | 建立時預填或結帳頁收集到的 Email |
external_customer_id | 建立 Session 時帶入的外部客戶 ID(可用於稽核綁定值) |
subscription_id | 訂閱建立後回填(SUBSCRIPTION mode) |
付款完成後,建議以 checkout.completed webhook 為準進行開通;此端點適合重新導向頁的即時確認與除錯。
錯誤
| HTTP | code | 情境 |
|---|---|---|
| 400 | bad_request | JSON 格式錯誤、Publishable Key 帶 metadata |
| 401 | unauthorized | API Key 無效 |
| 404 | not_found | 商品不存在或未上架(含存取其他組織的商品) |
| 409 | conflict | 客戶已有該商品的有效訂閱,詳見錯誤代碼 |
| 422 | validation_error | 請求本文驗證失敗(含 einvoice 格式錯誤,如統編檢查碼不符、手機條碼格式錯誤) |
完整錯誤格式請見錯誤代碼。