@moosehq/provider-sdk 參考
完整講解見伺服端接入指南。
ProviderClient
new ProviderClient(options: ProviderClientOptions)| 選項 | 型別 | 說明 |
|---|---|---|
baseUrl | string | 平台基礎 URL,不帶結尾斜槓 |
tenantId | string | 你的廠商租戶 ID |
secret | string | HMAC 金鑰——只存在於伺服端 |
retry | Partial<RetryOptions> | 預設為 { maxAttempts: 5, baseDelayMs: 200 } |
timeoutMs | number | 單次嘗試的請求逾時時間。逾時的嘗試會被中止,並像其他網路錯誤一樣被重試。預設為 15000 |
now | () => Date | 可注入的時鐘,用於測試 |
onDebug | (event: DebugEvent) => void | 選用診斷鉤子,預設關閉——見除錯指南 |
fetch | typeof fetch | 可注入的 fetch 實作——搭配 createMockPlatform 可做離線測試。預設為全域 fetch |
type RetryOptions = {
maxAttempts: number // 總嘗試次數,包含第一次——不是重試次數
baseDelayMs: number // 第一次重試前的延遲;之後每次重試翻倍
sleep?: (ms: number) => Promise<void> // 可注入,用於測試;預設是基於 setTimeout 的真實等待
}退避演算法是指數退避:baseDelayMs * 2^(attempt-1)。
方法
verifySession(sessionToken: string): Promise<VerifySessionResponse>submitTransaction(req: TransactionRequest): Promise<TransactionResponse>getBalance(sessionToken: string): Promise<BalanceResponse>—— 按需查詢玩家目前餘額,不會移動任何資金。見POST /v1/wallet/balance。verifyReplay(replayToken: string): Promise<VerifyReplayResponse>—— 將運營商的回放連結(網址中的?replay=token)解析回它所指向的那一局。見單局回放。
注意這裡沒有 submitBehavior——機器人偵測遙測是由瀏覽器透過 @moosehq/game-client-sdk/behavior-reporter 的 BehaviorReporter 直接送出的,完全不經過這個 SDK。見機器人偵測訊號。
型別
欄位層級語義(限制條件、校驗規則、metadata 的用途)見資料模型與列舉;這一節是確切的 TypeScript 型別宣告。
type TransactionType = 'BET' | 'WIN' | 'ROLLBACK'
type ResponseStatus = 'OK' | 'DECLINED'
type TransactionRequest = {
transactionId: string
sessionToken: string
type: TransactionType
roundId: string
roundComplete: boolean
originalTransactionId?: string // type === 'ROLLBACK' 時必填
playerRef: string
amount: number // 最小貨幣單位
currency: string // ISO-4217,大寫,3 個字母(例如 "USD")
gameId: string
}
type TransactionResponse = { status: ResponseStatus; balance: number }
type VerifySessionConfig = {
rtpProfile: string
minBetMinor: number
maxBetMinor: number
language: string // BCP-47 語言標籤(例如 "en"、"zh-TW")——運營商在啟動時要求的語言,若未要求則為 "",此時請回退到你自己的預設語言(例如 "en")
}
type VerifySessionResponse = {
playerRef: string
gameId: string
operatorId: string
currency: string
config: VerifySessionConfig
}
type BalanceResponse = { balance: number } // 最小貨幣單位
type VerifyReplayResponse = {
roundId: string // 用這個去查你自己的 ReplayStore —— 見單局回放
gameId: string
playerRef: string
currency: string
language: string // 這一局原本進行時使用的 BCP-47 語言標籤,若未設定則為 ""——回退規則與 VerifySessionConfig.language 相同
}錯誤
PlatformApiError —— 對不可重試的 HTTP 響應(400/401/403/404/429)丟擲;有 status: number 和 body: string(原始響應體),另外還有 requestId?: string(平台的 X-Request-Id 響應頭,若存在——把這個交給平台支援用於伺服端日誌關聯)、retryAfter?: string(Retry-After 響應頭,若存在——特別是在 429 時,SDK 不會自動重試這個狀態)、以及 hint?: string(一句話指出該狀態最可能的原因,例如 401 的 hint 會列出常見的簽名錯誤)。不會暴露其他響應頭。 isRetryableStatus(status) —— SDK 自身判斷"是否值得重試"的方法(只有 409 和任何 >= 500 才是 true——429 不會被自動重試),匯出給需要自定義重試邏輯的呼叫方使用。 RequestTimeoutError —— 當一次請求嘗試超過 timeoutMs 時丟擲;有 timeoutMs: number 和 hint: string。它被當作網路層級的錯誤處理,會像其他網路錯誤一樣被重試,所以只有當所有嘗試(含全部重試)都逾時後,呼叫方才會收到這個錯誤。
完整狀態碼參考,包含以上這些類別所依據的主表,見錯誤碼與重試。
底層簽名原語
signRequest / generateNonce —— ProviderClient 內部使用,同時也匯出給需要簽名 SDK 未覆蓋的廠商端請求的呼叫方。explainSignature 計算方式與 signRequest 相同,但同時返回它所雜湊的原始 canonical string,用於診斷無法解釋的 401——見除錯指南。完整 canonical string 契約見簽名與鑑權。
type SignRequestInput = {
method: string
path: string // 僅 URL 路徑——不含協定/主機/查詢字串
tenantId: string
secret: string
body: string // 實際將傳送的請求主體位元組
now: Date
nonce: string // 來自 generateNonce()——每次簽名請求必須唯一
}
type SignedHeaders = {
'X-Tenant-ID': string
'X-Timestamp': string
'X-Nonce': string
'X-Signature': string
}
type SignatureExplanation = {
canonicalString: string // 被雜湊的原始位元組
timestamp: string
signature: string
headers: SignedHeaders
}
function signRequest(input: SignRequestInput): SignedHeaders
function explainSignature(input: SignRequestInput): SignatureExplanation
function generateNonce(): string // 16 個隨機位元組,轉十六進位制除錯
DebugEvent —— onDebug 收到的內容;一個以 phase 區分的聯合型別:
type DebugEvent =
| { phase: 'request'; method: string; path: string; tenantId: string; transactionId?: string; attempt: number }
| { phase: 'response'; method: string; path: string; status: number; attempt: number; latencyMs: number; requestId?: string; clockSkewMs?: number }
| { phase: 'retry'; method: string; path: string; attempt: number; reason: 'network' | 'timeout' | 'conflict-409' | 'server-5xx'; delayMs: number }onDebug、explainSignature、PlatformApiError 的 hint/requestId 的完整走查,見除錯指南。
離線模擬平台
createMockPlatform(options: MockPlatformOptions): MockPlatform —— 平台錢包/RGS 端點的可簽名記憶體模擬實作,用於不需要網路的整合測試。完整範例見用 createMockPlatform 測試。
type MockPlatformOptions = { secret: string; tenantId: string; now?: () => Date }
type MockSession = {
sessionToken: string
playerRef: string
gameId: string
operatorId: string
currency: string
config: VerifySessionConfig
balanceMinor: number
}
type MockPlatform = {
fetch: typeof fetch // 作為 ProviderClientOptions.fetch 傳入
registerSession(session: MockSession): void
registerReplay(replayToken: string, resolved: VerifyReplayResponse): void
getBalance(sessionToken: string): number | undefined
}