接入你的 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. 1

    開啟 Publisher Account

    publisher.xsolla.com

    用有權限管理 API 金鑰的帳號登入。

  2. 2

    記下商戶 ID 和專案 ID

    開啟專案,網址是 publisher.xsolla.com/<商戶 ID>/projects/<專案 ID>,例如 746076 和 273204。

  3. 3

    建立 API 金鑰

    Company settings → API keys → Create API key,或專案的 Settings → API keys

    馬上複製:Xsolla 只顯示一次。拿到它的人能讀取你的訂閱,所以不要放進 App。

#2. 填到 API 金鑰上

  1. 1

    開啟 App 用的那個金鑰

    控制台 → API 金鑰 → 編輯

    為 App 單獨建立一個金鑰,只開放它用到的模型,並設定額度上限。

  2. 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 設額度上限。

App 請求簽名 →

#6. 查看發生了什麼

每次驗證(包括快取結果和失敗)都會列在主控台 → 請求紀錄裡,是金鑰上的一筆免費 xsolla-verify 紀錄。

  • 儲存時提示 Xsolla 不接受金鑰:金鑰沒複製完整、已被刪除,或屬於別的公司。請新建一個。
  • xsolla_credentials_invalid:儲存後金鑰在 Publisher Account 裡被刪除了。請新建金鑰並填到 API 金鑰上。
  • 每次都回傳 subscribed: false:使用者 ID 和付款權杖裡的不一致,或金鑰上的專案 ID 是另一個專案。

全部欄位和錯誤碼 →

還是沒解決?

把請求 ID 或錯誤訊息傳給我們,我們來查。