14 KiB
14 KiB
訂閱系統 API
📋 概述
Drama Ling 的訂閱會員系統,支援iOS/Android原生內購,提供對話訓練功能解鎖和進階學習體驗。
💳 訂閱特色
訂閱方案
- 月費會員: NT$600/月 (測試期2折優惠 NT$120)
- 支援平台: iOS App Store、Google Play 原生內購
- 訪客訂閱: 支援透過裝置ID的訪客用戶訂閱
- 權限管理: 基於訂閱狀態的功能權限控制
解鎖功能
- ✅ 對話訓練: 無限制對話練習
- ✅ 進階場景: 專業場景和挑戰模式
- ✅ 詳細分析: 完整學習報告和建議
- ✅ 語言評估: Microsoft API 驅動的專業評估
- ✅ 優先支援: 專屬客服通道
📌 API 端點
1. 獲取訂閱方案
GET /api/v1/subscriptions/plans
Authorization: Bearer <access_token> // 訪客用戶可選
回應範例
Response 200 OK
{
"success": true,
"data": {
"available_plans": [
{
"plan_id": "PLAN_MONTHLY_TWD",
"product_id": "dramaling.subscription.monthly",
"name": "月費會員",
"description": "解鎖對話訓練功能,享受完整學習體驗",
"pricing": {
"regular_price": {
"amount": 600,
"currency": "TWD",
"display": "NT$600"
},
"test_period_discount": {
"percentage": 80,
"discounted_amount": 120,
"currency": "TWD",
"display": "NT$120",
"description": "內部測試期間限時2折優惠",
"valid_until": "2025-03-31T23:59:59Z"
}
},
"billing_cycle": "monthly",
"trial_period": {
"duration_days": 7,
"available": true
},
"features": [
{
"feature_id": "unlimited_dialogue",
"name": "無限制對話練習",
"description": "解鎖所有對話訓練場景,無每日次數限制"
},
{
"feature_id": "advanced_scenarios",
"name": "進階情境練習",
"description": "商務、醫療、學術等專業場景"
},
{
"feature_id": "detailed_analysis",
"name": "詳細學習分析",
"description": "Microsoft AI 驅動的語言評估和建議"
},
{
"feature_id": "priority_support",
"name": "優先客服支援",
"description": "專屬客服通道,優先處理問題"
}
],
"platform_config": {
"ios": {
"product_id": "dramaling.subscription.monthly",
"app_store_id": "6451234567"
},
"android": {
"sku": "dramaling_monthly_subscription",
"billing_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOC..."
}
}
}
],
"current_user_status": {
"is_subscribed": false,
"user_type": "guest", // guest, registered
"device_id": "DEV_iOS_12345",
"eligible_for_trial": true,
"subscription_triggers": [
{
"trigger_id": "first_dialogue_attempt",
"description": "首次嘗試對話訓練時",
"timing": "immediate"
},
{
"trigger_id": "vocabulary_completion",
"description": "完成詞彙練習後",
"timing": "after_completion"
}
]
}
}
}
2. 驗證內購收據
POST /api/v1/subscriptions/verify-receipt
Authorization: Bearer <access_token> // 訪客用戶可選
Content-Type: application/json
{
"platform": "ios", // ios, android
"receipt_data": "base64_encoded_receipt",
"transaction_id": "1000000123456789",
"product_id": "dramaling.subscription.monthly",
"user_context": {
"user_type": "guest", // guest, registered
"device_id": "DEV_iOS_12345",
"subscription_trigger": "dialogue_access_blocked"
}
}
iOS 收據驗證範例
Response 200 OK
{
"success": true,
"data": {
"subscription_created": {
"subscription_id": "SUB_20240907_001",
"plan_id": "PLAN_MONTHLY_TWD",
"user_id": "USR_12345", // null for guest users
"device_id": "DEV_iOS_12345",
"status": "active"
},
"receipt_validation": {
"is_valid": true,
"platform": "ios",
"original_transaction_id": "1000000123456789",
"purchase_date": "2024-09-07T12:00:00Z",
"expires_date": "2024-10-07T12:00:00Z",
"product_id": "dramaling.subscription.monthly",
"auto_renew_status": true
},
"subscription_details": {
"activated_at": "2024-09-07T12:00:00Z",
"expires_at": "2024-10-07T12:00:00Z",
"auto_renewal": true,
"billing_cycle": "monthly",
"is_trial_period": false,
"price_paid": {
"amount": 120,
"currency": "TWD",
"was_discounted": true
}
},
"unlocked_features": [
"unlimited_dialogue",
"advanced_scenarios",
"detailed_analysis",
"priority_support"
]
},
"message": "Subscription activated successfully"
}
3. 檢查訂閱狀態
GET /api/v1/subscriptions/status
Authorization: Bearer <access_token> // 訪客用戶可選
查詢參數
include_features: 是否包含功能權限詳情 (true/false)check_renewal: 是否檢查自動續訂狀態 (true/false)
回應範例
Response 200 OK
{
"success": true,
"data": {
"subscription_status": {
"is_active": true,
"subscription_id": "SUB_20240907_001",
"plan_id": "PLAN_MONTHLY_TWD",
"status": "active", // active, expired, cancelled, pending
"activated_at": "2024-09-07T12:00:00Z",
"expires_at": "2024-10-07T12:00:00Z",
"days_remaining": 30,
"auto_renewal": true,
"billing_cycle": "monthly"
},
"user_context": {
"user_type": "registered", // guest, registered
"device_id": "DEV_iOS_12345",
"platform": "ios"
},
"access_permissions": {
"dialogue_training": {
"has_access": true,
"access_type": "unlimited",
"restrictions": []
},
"advanced_features": {
"detailed_analysis": true,
"progress_reports": true,
"priority_support": true,
"offline_content": false // 未來功能
}
},
"usage_statistics": {
"dialogues_this_month": 45,
"analysis_requests": 23,
"last_activity": "2024-09-07T11:30:00Z"
}
}
}
4. 取消訂閱
POST /api/v1/subscriptions/cancel
Authorization: Bearer <access_token>
Content-Type: application/json
{
"cancellation_reason": "too_expensive", // too_expensive, not_using, technical_issues, other
"feedback": "價格對學生來說太高了",
"immediate_cancellation": false // true: 立即取消, false: 期滿後取消
}
回應範例
Response 200 OK
{
"success": true,
"data": {
"cancellation_processed": {
"subscription_id": "SUB_20240907_001",
"cancellation_effective_date": "2024-10-07T12:00:00Z",
"immediate_cancellation": false,
"remaining_access_days": 30
},
"retention_offer": {
"offer_id": "RETENTION_STUDENT_50",
"discount_percentage": 50,
"offer_description": "學生專屬50%折扣",
"valid_until": "2024-09-14T12:00:00Z",
"reactivation_url": "/subscriptions/reactivate?offer=RETENTION_STUDENT_50"
},
"feature_impact": {
"features_will_be_disabled": [
"unlimited_dialogue",
"detailed_analysis"
],
"features_remain_accessible": [
"basic_vocabulary",
"spaced_repetition"
]
}
},
"message": "Subscription will be cancelled at the end of current billing period"
}
5. 重新啟用訂閱
POST /api/v1/subscriptions/reactivate
Authorization: Bearer <access_token>
Content-Type: application/json
{
"offer_id": "RETENTION_STUDENT_50", // 可選,使用挽留優惠
"payment_method_update": {
"platform": "ios",
"new_receipt_data": "base64_receipt_data"
}
}
6. 訂閱歷史記錄
GET /api/v1/subscriptions/history
Authorization: Bearer <access_token>
查詢參數
start_date: 開始日期end_date: 結束日期status: 訂閱狀態篩選page: 頁碼limit: 每頁筆數
回應範例
Response 200 OK
{
"success": true,
"data": {
"subscription_history": [
{
"subscription_id": "SUB_20240907_001",
"plan_name": "月費會員",
"status": "active",
"activated_at": "2024-09-07T12:00:00Z",
"expires_at": "2024-10-07T12:00:00Z",
"platform": "ios",
"amount_paid": 120,
"currency": "TWD",
"transaction_id": "1000000123456789"
}
],
"summary": {
"total_subscriptions": 1,
"total_amount_paid": 120,
"currency": "TWD",
"average_subscription_length": 30, // days
"most_recent_status": "active"
},
"pagination": {
"current_page": 1,
"total_pages": 1,
"total_items": 1
}
}
}
7. 訂閱優惠和促銷
GET /api/v1/subscriptions/offers
Authorization: Bearer <access_token> // 可選
回應範例
Response 200 OK
{
"success": true,
"data": {
"active_offers": [
{
"offer_id": "NEW_USER_TRIAL",
"name": "新用戶免費試用",
"description": "7天免費試用,隨時可取消",
"discount_type": "free_trial",
"trial_duration_days": 7,
"applicable_plans": ["PLAN_MONTHLY_TWD"],
"eligibility": {
"new_users_only": true,
"device_restriction": false,
"geographic_restriction": ["TW"]
},
"valid_until": "2024-12-31T23:59:59Z"
},
{
"offer_id": "STUDENT_DISCOUNT",
"name": "學生專屬折扣",
"description": "學生身分驗證後享50%折扣",
"discount_type": "percentage",
"discount_percentage": 50,
"verification_required": "student_email",
"valid_until": "2024-12-31T23:59:59Z"
}
],
"user_eligibility": {
"eligible_offers": ["NEW_USER_TRIAL"],
"ineligible_offers": [
{
"offer_id": "STUDENT_DISCOUNT",
"reason": "verification_required"
}
]
}
}
}
🔐 權限控制系統
功能權限矩陣
| 功能 | 免費用戶 | 訂閱用戶 | 備註 |
|---|---|---|---|
| 基礎詞彙練習 | ✅ | ✅ | 完全開放 |
| 間隔複習 | ✅ | ✅ | 完全開放 |
| 對話訓練 | ❌ | ✅ | 需訂閱解鎖 |
| 進階場景 | ❌ | ✅ | 需訂閱解鎖 |
| 詳細分析報告 | ❌ | ✅ | 需訂閱解鎖 |
| 語言程度評估 | ❌ | ✅ | 需訂閱解鎖 |
權限檢查 API
GET /api/v1/subscriptions/check-access/{feature_id}
Authorization: Bearer <access_token>
回應範例
Response 200 OK
{
"success": true,
"data": {
"feature_id": "dialogue_training",
"has_access": false,
"access_reason": "subscription_required",
"subscription_info": {
"required_plan": "PLAN_MONTHLY_TWD",
"upgrade_url": "/subscriptions/plans",
"current_status": "expired"
},
"alternative_actions": [
"subscribe_now",
"start_free_trial",
"use_basic_features"
]
}
}
🔧 錯誤處理
訂閱相關錯誤
| 錯誤碼 | HTTP狀態 | 描述 | 處理建議 |
|---|---|---|---|
SUBSCRIPTION_NOT_FOUND |
404 | 訂閱記錄不存在 | 檢查訂閱狀態或重新訂閱 |
SUBSCRIPTION_EXPIRED |
403 | 訂閱已過期 | 引導用戶續訂 |
SUBSCRIPTION_CANCELLED |
403 | 訂閱已取消 | 提供重新訂閱選項 |
RECEIPT_VERIFICATION_FAILED |
400 | 收據驗證失敗 | 檢查收據格式或重新購買 |
RECEIPT_INVALID |
400 | 收據無效 | 聯繫App Store/Google Play |
SUBSCRIPTION_ALREADY_ACTIVE |
409 | 訂閱已啟用 | 提示用戶當前訂閱狀態 |
PLATFORM_VERIFICATION_ERROR |
502 | 平台驗證服務錯誤 | 稍後重試 |
REFUND_PROCESSING_ERROR |
400 | 退款處理失敗 | 聯繫客服 |
錯誤回應範例
Response 403 Forbidden
{
"success": false,
"error": {
"code": "SUBSCRIPTION_EXPIRED",
"message": "訂閱已過期,無法存取此功能",
"details": {
"expired_at": "2024-09-01T12:00:00Z",
"days_since_expiration": 6,
"grace_period_remaining": 1,
"renewal_options": [
{
"plan_id": "PLAN_MONTHLY_TWD",
"price": 600,
"currency": "TWD"
}
]
}
}
}
🧪 測試範例
檢查訂閱狀態
curl -X GET "https://api.dramaling.com/api/v1/subscriptions/status" \
-H "Authorization: Bearer <access_token>"
驗證iOS收據
curl -X POST "https://api.dramaling.com/api/v1/subscriptions/verify-receipt" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"platform": "ios",
"receipt_data": "base64_receipt_here",
"transaction_id": "1000000123456789",
"product_id": "dramaling.subscription.monthly"
}'
取消訂閱
curl -X POST "https://api.dramaling.com/api/v1/subscriptions/cancel" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"cancellation_reason": "not_using",
"feedback": "暫時不需要進階功能",
"immediate_cancellation": false
}'
📊 收據驗證流程
iOS App Store 驗證
- 客戶端完成內購後取得收據
- 將收據傳送到後端 API
- 後端調用 Apple App Store API 驗證
- 驗證成功後啟用訂閱
Google Play 驗證
- 客戶端完成內購後取得購買token
- 將token傳送到後端 API
- 後端調用 Google Play Developer API 驗證
- 驗證成功後啟用訂閱