Skip to content

運營商 API 參考

下面每個介面都需要有效的運營商簽名(見簽名與身份驗證),並按租戶做速率限制。這個 API 共用的完整狀態碼參考見錯誤與重試——本頁只涵蓋每個介面各自特有的內容。

POST /v1/operator/games/launch

請求體:

ts
type LaunchGameRequestBody = {
  playerRef: string
  gameId: string
  currency: string // 必須是目標遊戲 GameSummary.currencies 裡的其中一項
  mode: 'REAL' | 'DEMO'
  language?: string // 選填的 BCP-47 語言標籤(例如 "en"、"zh-TW");若傳入,必須在該遊戲的 GameSummary.supportedLanguages 之內——不傳則讓遊戲回退到自己的預設語言
  lobbyUrl?: string // 選填的絕對 http(s) 網址;會以 `&lobby=` 附加到 launchUrl 後面——遊戲的「返回大廳」控制項會直接導向最上層視窗到這裡,而不是請求 shell 把它關閉。不傳則維持既有的 shell 關閉行為
}

響應:

ts
type LaunchGameResponse = {
  launchUrl: string     // 把它嵌入 iframe
  sessionToken: string  // 也已包含在 launchUrl 裡;廠商的遊戲
                          // 客戶端會在自己的錢包呼叫裡帶上它
}

錯誤響應(除了錯誤與重試裡的共用集合之外):404(遊戲不存在,或對你的運營商租戶不可見——DEMO 模式的啟動會跳過可見性檢查,所以這一項只適用於 REAL)、400(該遊戲不支援這個貨幣,傳入的 language 不在該遊戲的 supportedLanguages 內,或傳入的 lobbyUrl 不是絕對的 http(s) 網址)、403(啟動被風控攔截——該玩家在此運營商的黑名單上;響應體只帶一個通用訊息,不會給出具體原因——如果你需要知道某個玩家具體為什麼被封鎖,請聯繫平台管理團隊)。

GET /v1/operator/games

無請求體。返回你的運營商租戶可見的遊戲列表。

GameSummary

ts
type GameSummary = {
  gameId: string
  name: string
  provider: string
  currencies: string[] // 此遊戲廠商支援的 ISO-4217 幣別代碼——由該廠商名下所有遊戲共用,不是按遊戲個別設定;LaunchGameRequestBody.currency 就是依此集合做校驗
  supportedLanguages: string[] // 此遊戲廠商支援的 BCP-47 語言標籤(例如 ["en", "zh-TW"])——LaunchGameRequestBody.language 就是依此集合做校驗
  launchBaseUrl: string // 廠商的遊戲客戶端 URL;launch 會在後面附加 session token
  replayBaseUrl: string // 廠商的回放頁面 URL,若該遊戲不支援回合回放則為空字串——見下方 POST /v1/operator/rounds/replay
}

響應:GameSummary[]

POST /v1/operator/players/kick

結束 playerRef 在你的運營商租戶下的所有活躍 session——用於強制把玩家踢下線(例如自我排除、風控凍結、帳戶凍結等場景)。這個操作立即生效且具有權威性:session 會在伺服端被刪除,玩家的遊戲客戶端下一次錢包呼叫就會收到 401。平台還會盡力通知每個被結束 session 所屬的廠商,讓仍在開啟中的遊戲畫面能立刻被關閉,而不必等到下一次呼叫失敗才發現——但如果聯繫不到廠商,並不會改變這個介面本身的結果;而玩家瀏覽器只會透過你上報的 shell 端橋接SESSION_REVOKED 事件得知,而不是平台直接推送到瀏覽器的任何東西。

請求體:

ts
type KickPlayerRequestBody = {
  playerRef: string
}

響應:

ts
type KickPlayerResponse = {
  revokedCount: number // 實際被結束的 session 數量——若玩家原本沒有活躍 session 則為 0,這代表成功,不是錯誤
}

錯誤響應:400(缺少 playerRef)、401(未能解析出運營商身份)、429(超出速率限制)、500(意外失敗)。

POST /v1/operator/rounds/replay

鑄造一個連結,指向廠商託管、用於回放特定一局的頁面——完整說明(「回放」代表什麼、廠商需要實作什麼才能讓它運作)見取得單局回放連結。平台從未看到一局的視覺結果,只看到資金異動——回放支援是按遊戲選配的(未設定時 GameSummary.replayBaseUrl 為空),且只有廠商加入錄製功能之後進行的局才能回放。

請求體:

ts
type RoundReplayRequestBody = {
  roundId: string // 廠商為這一局提交交易時使用的同一個 roundId
  gameId: string
}

響應:

ts
type RoundReplayResponse = {
  replayUrl: string // 在瀏覽器開啟此網址即可觀看這一局的回放
}

replayUrl 內嵌一個短時效、單一用途的 token(與 launchUrl 的 session token 是同一種模式)——連結會在固定時間之後過期(預設 15 分鐘),所以每次都應重新請求一個新的,而不要快取起來重複使用。

錯誤響應:404(在你的運營商租戶下找不到符合這個 roundId + gameId 的局——包含 roundId 屬於其他運營商、或屬於你另一個遊戲的情況,這兩種情況被刻意做成與「不存在」無法區分,避免這個介面被用來探測你不擁有的 round ID)、400roundId/gameId 缺失,或該遊戲不支援回放——其 replayBaseUrl 尚未設定)、401(未能解析出運營商身份)、429(超出速率限制)、500(意外失敗)。

免費旋轉

運營商自助發放免費旋轉走的是自己獨立的一組路由——POST /v1/operator/free-spins/grants 及其相關介面——由於它們有自己獨立的冪等性和狀態模型,因此另外記錄在免費旋轉 API 參考裡。指南見免費旋轉