525 lines
14 KiB
Markdown
525 lines
14 KiB
Markdown
# 訂閱系統 API
|
||
|
||
## 📋 概述
|
||
Drama Ling 的訂閱會員系統,支援iOS/Android原生內購,提供對話訓練功能解鎖和進階學習體驗。
|
||
|
||
## 💳 訂閱特色
|
||
|
||
### 訂閱方案
|
||
- **月費會員**: NT$600/月 (測試期2折優惠 NT$120)
|
||
- **支援平台**: iOS App Store、Google Play 原生內購
|
||
- **訪客訂閱**: 支援透過裝置ID的訪客用戶訂閱
|
||
- **權限管理**: 基於訂閱狀態的功能權限控制
|
||
|
||
### 解鎖功能
|
||
- ✅ **對話訓練**: 無限制對話練習
|
||
- ✅ **進階場景**: 專業場景和挑戰模式
|
||
- ✅ **詳細分析**: 完整學習報告和建議
|
||
- ✅ **語言評估**: Microsoft API 驅動的專業評估
|
||
- ✅ **優先支援**: 專屬客服通道
|
||
|
||
## 📌 API 端點
|
||
|
||
### 1. 獲取訂閱方案
|
||
```http
|
||
GET /api/v1/subscriptions/plans
|
||
Authorization: Bearer <access_token> // 訪客用戶可選
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
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. 驗證內購收據
|
||
```http
|
||
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 收據驗證範例
|
||
```http
|
||
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. 檢查訂閱狀態
|
||
```http
|
||
GET /api/v1/subscriptions/status
|
||
Authorization: Bearer <access_token> // 訪客用戶可選
|
||
```
|
||
|
||
#### 查詢參數
|
||
- `include_features`: 是否包含功能權限詳情 (`true`/`false`)
|
||
- `check_renewal`: 是否檢查自動續訂狀態 (`true`/`false`)
|
||
|
||
#### 回應範例
|
||
```http
|
||
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. 取消訂閱
|
||
```http
|
||
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: 期滿後取消
|
||
}
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
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. 重新啟用訂閱
|
||
```http
|
||
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. 訂閱歷史記錄
|
||
```http
|
||
GET /api/v1/subscriptions/history
|
||
Authorization: Bearer <access_token>
|
||
```
|
||
|
||
#### 查詢參數
|
||
- `start_date`: 開始日期
|
||
- `end_date`: 結束日期
|
||
- `status`: 訂閱狀態篩選
|
||
- `page`: 頁碼
|
||
- `limit`: 每頁筆數
|
||
|
||
#### 回應範例
|
||
```http
|
||
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. 訂閱優惠和促銷
|
||
```http
|
||
GET /api/v1/subscriptions/offers
|
||
Authorization: Bearer <access_token> // 可選
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
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
|
||
```http
|
||
GET /api/v1/subscriptions/check-access/{feature_id}
|
||
Authorization: Bearer <access_token>
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
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 | 退款處理失敗 | 聯繫客服 |
|
||
|
||
### 錯誤回應範例
|
||
```http
|
||
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"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 🧪 測試範例
|
||
|
||
### 檢查訂閱狀態
|
||
```bash
|
||
curl -X GET "https://api.dramaling.com/api/v1/subscriptions/status" \
|
||
-H "Authorization: Bearer <access_token>"
|
||
```
|
||
|
||
### 驗證iOS收據
|
||
```bash
|
||
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"
|
||
}'
|
||
```
|
||
|
||
### 取消訂閱
|
||
```bash
|
||
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 驗證
|
||
1. 客戶端完成內購後取得收據
|
||
2. 將收據傳送到後端 API
|
||
3. 後端調用 Apple App Store API 驗證
|
||
4. 驗證成功後啟用訂閱
|
||
|
||
### Google Play 驗證
|
||
1. 客戶端完成內購後取得購買token
|
||
2. 將token傳送到後端 API
|
||
3. 後端調用 Google Play Developer API 驗證
|
||
4. 驗證成功後啟用訂閱
|
||
|
||
---
|
||
|
||
**模組負責人**: 後端團隊 + 金流團隊
|
||
**最後更新**: 2024年9月7日
|
||
**相關文檔**: [用戶管理API](./user-management.md), [錯誤處理](./errors.md) |