接入你的 App
Xsolla 訂閱
適合透過 Xsolla 賣訂閱、自己沒有伺服器的 App。App 用一個 API 金鑰把 Xsolla 使用者 ID 傳給閘道;閘道用你的 Xsolla API 金鑰去問 Xsolla,回答該使用者有沒有生效中的訂閱。驗證免費。
#開始之前
- 一個 Xsolla Publisher Account,其中有販售訂閱的專案(Subscriptions → Subscription plans)。
- App 寫進付款權杖的使用者 ID(user.id)。同一個使用者每次都要一樣,例如 App 首次產生後儲存下來的 ID。
#1. 取得 ID 和 API 金鑰
- 1
開啟 Publisher Account
publisher.xsolla.com用有權限管理 API 金鑰的帳號登入。
- 2
記下商戶 ID 和專案 ID
開啟專案,網址是 publisher.xsolla.com/<商戶 ID>/projects/<專案 ID>,例如 746076 和 273204。
- 3
建立 API 金鑰
Company settings → API keys → Create API key,或專案的 Settings → API keys馬上複製:Xsolla 只顯示一次。拿到它的人能讀取你的訂閱,所以不要放進 App。
#2. 填到 API 金鑰上
- 1
開啟 App 用的那個金鑰
控制台 → API 金鑰 → 編輯為 App 單獨建立一個金鑰,只開放它用到的模型,並設定額度上限。
- 2
填寫 Xsolla 訂閱驗證
設定 Xsolla 驗證填寫商戶 ID、專案 ID 和 API 金鑰後儲存。閘道會先用這個金鑰問一次 Xsolla 再儲存;金鑰加密儲存,之後不再顯示。
#3. 在 App 裡驗證
付款視窗關閉後查一次,App 開啟時再查一次。傳入 App 寫進付款權杖的同一個使用者 ID。不要等結果才啟動 App:先顯示上次儲存的結果,查完再更新。每個金鑰預設每分鐘可查 120 次。
xsolla.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
const apiKey = 'sk-YOUR_KEY';
Future<Map<String, dynamic>?> checkXsolla(String userId) async {
final res = await http.post(
Uri.parse('https://www.aisplice.store/v1/xsolla/verify'),
headers: {
'Authorization': 'Bearer $apiKey',
'Content-Type': 'application/json',
// Request signing on for this key? Then this call must be signed too:
// ...signedHeaders('POST', '/v1/xsolla/verify'),
},
body: jsonEncode({'user_id': userId}),
);
if (res.statusCode != 200) return null; // keep the last saved answer
return jsonDecode(res.body) as Map<String, dynamic>;
}
Future<void> refreshEntitlement(String userId) async {
final status = await checkXsolla(userId);
if (status == null) return;
await saveEntitlement(status); // your local storage
if (status['active'] == true) unlockPaidFeatures();
}#4. 決定解鎖什麼
| 驗證結果 | App 怎麼做 | 常見原因 |
|---|---|---|
| active: true, in_trial: true | 解鎖,並按 expiry_time 顯示「試用到期時間」。 | 免費試用,還沒扣款 |
| active: true | 解鎖,有效到 expiry_time。 | 已付費,包括關閉了自動續訂但還沒到期的訂閱 |
| subscribed: true, active: false | 不解鎖,顯示續訂頁面。 | 已取消或已凍結 |
| subscribed: false | 不解鎖,顯示訂閱頁面。 | 該使用者還沒有訂閱,或付款還沒完成 |
| HTTP 502 / 503 | 沿用上次儲存的結果,稍後重試。 | Xsolla 或 API 金鑰沒有回應 |
把 expiry_time 和結果一起儲存。兩次驗證之間,到這個時間之前都當作可用,這樣手機離線也能正常用。
#5. 保護 App 裡的金鑰
放在 App 裡的 key 只要攔截流量就能看到。給這個 key 開啟請求簽名,這樣別人複製走 key 也無法單獨使用;建置時做混淆,並給 key 設額度上限。
#6. 查看發生了什麼
每次驗證(包括快取結果和失敗)都會列在主控台 → 請求紀錄裡,是金鑰上的一筆免費 xsolla-verify 紀錄。
- 儲存時提示 Xsolla 不接受金鑰:金鑰沒複製完整、已被刪除,或屬於別的公司。請新建一個。
- xsolla_credentials_invalid:儲存後金鑰在 Publisher Account 裡被刪除了。請新建金鑰並填到 API 金鑰上。
- 每次都回傳 subscribed: false:使用者 ID 和付款權杖裡的不一致,或金鑰上的專案 ID 是另一個專案。
還是沒解決?
把請求 ID 或錯誤訊息傳給我們,我們來查。