dramaling-app/docs/04_technical/api/subscription.md

525 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 訂閱系統 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)