Skip to content

伺服端接入

@moosehq/provider-sdkProviderClient 是你後端需要的一切入口:session 校驗、餘額查詢和錢包交易提交。簽名、nonce、冪等重試都已經幫你處理好了。

安裝

由 Moose 遊戲平台直接以 npm 套件形式分發——你的對接窗口會提供存取方式。

建立客戶端

ts
import { ProviderClient } from '@moosehq/provider-sdk'

const client = new ProviderClient({
  baseUrl: 'https://platform.example.com',
  tenantId: 'acme-studio',
  secret: process.env.PLATFORM_SECRET!,
  // retry: { maxAttempts: 5, baseDelayMs: 200 }, // 以上為預設值
})

secret 是你租戶的 HMAC 簽名金鑰——見下方安全性

典型的接入順序是:遊戲載入時呼叫一次 verifySession,需要展示或同步餘額時呼叫 getBalance,每局裡的每筆下注/派彩/回滾則用 submitTransaction

校驗 session

在你的遊戲啟動時,校驗啟動 token 並讀取針對這個 (game, operator) 組合解析出的 Central Config(RTP 標籤 + 下注限額)。這裡的 sessionToken 就是你的瀏覽器客戶端從啟動 URL 讀出、再發給你後端的那個值——它如何到達,見取得 session token

ts
const session = await client.verifySession(sessionToken)
// {
//   playerRef, gameId, operatorId, currency,
//   config: { rtpProfile, minBetMinor, maxBetMinor } // maxBetMinor === 0 表示無上限
// }

拿到 session 之後,你就可以用它查詢餘額,也可以直接提交交易。

查詢餘額

ts
const { balance } = await client.getBalance(sessionToken)
// balance 為最小貨幣單位(分),和交易回應裡的 `balance` 結構一致

只需要 session token 即可——playerRef 會在伺服端從 session 解析出來,因此這個介面永遠無法用來讀取其他廠商的玩家餘額。它不會移動任何資金:運營商的錢包仍是唯一的權威來源,這只是一次透傳查詢。

每筆 submitTransaction 回應本身就會返回交易後的餘額,所以對局進行中通常不需要另外查——適合在玩家第一次下注前展示餘額,或斷線重連後重新同步。DEMO session 返回的是記憶體中的試玩餘額,而不是查詢真實運營商。和 submitTransaction 不同,這個呼叫在平台側不做冪等追蹤——這是一次讀取操作,失敗了直接重試即可。完整狀態碼對照見錯誤碼與重試

提交交易

ts
const bet = await client.submitTransaction({
  transactionId: crypto.randomUUID(),
  sessionToken,
  type: 'BET',            // 'BET' | 'WIN' | 'ROLLBACK'
  roundId,
  roundComplete: false,    // 該局最後一筆交易時為 true(僅對 BET/WIN 有意義)
  playerRef: session.playerRef,
  amount: 300,             // 最小貨幣單位(分)—— 絕不用浮點數
  currency: session.currency,
  gameId: session.gameId,
})

if (bet.status === 'DECLINED') {
  // 正常的業務結果(餘額不足,或超出配置的下注限額)—— 不是錯誤,不會重試。
}
  • transactionId —— 由你自己生成(例如 crypto.randomUUID())。對同一次邏輯嘗試的重試要原樣複用它;SDK 內部的自動重試已經會幫你複用了。
  • ROLLBACK —— 把 originalTransactionId 設為要撤銷的那筆 BETtransactionId
  • WIN —— 作為獨立於 BET 的另一筆交易提交,在兩者中結束該局的那筆上標記 roundComplete: true

什麼會重試,什麼不會

結果行為
網路錯誤(DNS、連線被拒等)帶退避重試
HTTP 409(同一個 transactionId 已有請求在處理中)帶退避重試
HTTP 5xx(包括平台側判定為 TIMED_OUT 的情況)帶退避重試
HTTP 400/401/403/404立即以 PlatformApiError 丟擲,不重試——請求本身無效或未通過鑑權,重試沒有意義
HTTP 429(超出限流)立即以 PlatformApiError 丟擲,SDK 不會重試。若平台有回傳 Retry-After 響應頭,會放在 PlatformApiError.retryAfter——請遵循這個值再自行重試,沒有的話再退回固定延遲
200 響應且 status: "DECLINED"正常返回,不是錯誤,不重試——BET 的一種業務結果

重試始終複用同一個 transactionId,匹配平台的冪等契約——你完全不需要自己實現這套邏輯。完整狀態碼參考見錯誤碼與重試

入站回呼

有三件事是平台呼叫的伺服端——session 撤銷和兩條免費旋轉路由——完全在這個 SDK 之外,因為這時候是你的伺服端接收呼叫,而不是發出呼叫。共用契約見平台 → 廠商回呼,各路由的完整細節見Session 撤銷回呼免費旋轉回呼

撤銷請求送達時,平台側的 session 其實已經被刪除了——這只是盡力而為的「立即通知」,不是權威來源。無論這個回呼有沒有送達,你自己下一次針對該 sessionTokenverifySession/submitTransaction 呼叫都已經會收到 401。若是瀏覽器端遊戲,請透過 @moosehq/game-client-sdknotifySessionRevoked 把這個事件上報給 shell——見 game-client-sdk 參考

單局回放

運營商可以請求一個連結來回放你遊戲的某一局。平台會把這個連結指向你的回放頁面——但只有當你完成兩件事之後這才會運作:與平台團隊為你的遊戲設定好回放頁面基礎網址,以及在 spin 時就把這一局的回放紀錄錄製下來(平台從頭到尾只看得到資金異動,從未看過你遊戲的視覺結果,如果你沒有自己錄製,平台也沒有東西可以拿來回放)。完整契約、verifyReplay 用法與範例見單局回放

簽名

每個請求都用 HMAC-SHA256 對一段由方法、路徑、時間戳、nonce、主體組成的 canonical string 簽名,放入四個請求頭:X-Tenant-IDX-TimestampX-NonceX-SignatureProviderClient 會自動生成並發送這些頭——只有當你要實現 SDK 沒覆蓋的廠商端呼叫時才需要用到底層的 signRequest/generateNonce 匯出,若是實作上面提到的入站回呼則需要 verifyPlatformSignature。完整契約(含時鐘偏差、nonce 重複使用、金鑰輪替)見簽名與鑑權

安全性

secret 是你租戶的 HMAC 簽名金鑰。必須只儲存在伺服端——絕不能發到瀏覽器。這個 SDK 是給你的後端(RGS)用的,不是給面向玩家的遊戲客戶端用的——那部分見取得 session token生命週期上報

除錯

遇到無法解釋的 401、呼叫在背後靜默重試——見除錯指南,內容涵蓋 onDebugexplainSignature,以及 PlatformApiErrorhint/requestId;想在沒有完整平台環境的情況下跑整合測試,見用 createMockPlatform 測試

完整參考

每個匯出型別和方法簽名詳見 @moosehq/provider-sdk 參考文件