錢包回調介面參考
這裡的方向和運營商 API相反:那邊是你呼叫平台,這裡是平台呼叫你。下面各類型的欄位級語義記錄在資料模型與列舉裡;本頁只涵蓋這兩個介面本身。完整的敘述式說明見實現錢包回調。
Moose 遊戲平台從不持有玩家資金——它是一個無縫錢包(seamless wallet)聚合平台,你的錢包才是玩家餘額的唯一真相來源。每一筆 BET、WIN、ROLLBACK 都會即時透過你實現的兩個介面,向你的錢包結算:
POST /v1/wallet/transaction—— 提交一筆交易GET /v1/wallet/balance—— 查詢玩家目前餘額
這兩個介面的位址都由你透過租戶的自助入口網站自行註冊——見註冊你的錢包回調 URL。
POST /v1/wallet/transaction
請求體:TransactionRequest。
響應體:
type TransactionResponse = {
status: 'OK' | 'DECLINED' // DECLINED 只在 BET 上才合法——見
// 資料模型與列舉
balance: number // 套用這筆交易後的餘額,最小貨幣單位
}任何非 200 的響應都會被視為失敗。平台可能會用完全相同的 transactionId 重試——見下方的冪等性。
GET /v1/wallet/balance
查詢參數:playerRef(必填)。
// GET /v1/wallet/balance?playerRef=<ref>
// 響應
{ "balance": number } // 最小貨幣單位這個介面有兩類呼叫方,因此需要實現它並保持其可靠性:
- 廠商餘額查詢。 遊戲廠商可以呼叫平台的
POST /v1/wallet/balance,在不提交交易的情況下按需讀取玩家目前的餘額。平台會即時把這個請求轉發到你這裡,並原樣返回你的響應。你這邊的失敗或逾時會直接以錯誤的形式暴露給廠商——這是一個廠商可直接觸達的必需介面,而不僅僅是一個背景檢查。 - 停滯回合補償。 平台也會在補償處理「停滯回合」(例如遊戲客戶端在回合中途斷線)時,把這個介面當作一次盡力而為的核對來呼叫。在那條路徑上,失敗、逾時或不支援的響應都在預期之內,永遠不會阻塞平台自己的回滾流程——但廠商發起的餘額查詢沒有這種容錯兜底,所以不要指望這個介面是「可選的」。
冪等性(硬性要求)
針對你處理過的每一個 transactionId(按玩家區分),快取其響應,重複請求時原樣回放——不要重複套用餘額變動。平台依賴這一點:逾時或網路錯誤之後,它可能重新發送完全相同的請求,並預期拿到相同的答案,而不是被重複扣款/加款。
Rollback 語義
ROLLBACK 透過 originalTransactionId 指向它要沖正的那筆 BET——查出該筆下注的金額並退款。
平台還有一個兜底的補償機制,會強制關閉長時間沒有活動的回合(客戶端在最後一次 roundComplete 之前就斷線了)。它會針對每一筆未結清的下注發送一筆合成回滾:
transactionId:stale-rollback:+ 原始下注的transactionIdsessionToken:哨兵值system:stale-round-reconciler
按普通回滾一樣處理即可——同樣的冪等規則適用,而且因為 transactionId 是確定性的,重複執行的補償掃描只會回放你快取的響應,不會重複退款。
逾時
平台呼叫你時會設定一個有界的逾時時間(按運營商配置,你第一次註冊回調 URL 時預設為 5000ms——見環境與基礎 URL)。在這個時間窗口內沒有響應會被視為 TIMED_OUT——平台可能會重試(同樣的 transactionId)或之後透過核對機制解決。請儘快回應;只要你遵守上面的冪等規則,逾時之後的重試永遠可以安全地給出相同的答案。
校驗平台的簽名
平台對每個出站呼叫的簽名,使用的是和你簽名呼叫平台請求完全相同的 HMAC 構造,只有一點不同:這裡的兩個介面都對完整的請求 URI——路徑和查詢字串簽名,而不只是路徑。這正是為了覆蓋 GET /v1/wallet/balance 的 playerRef 查詢參數,讓它無法在傳輸途中被篡改而不使簽名失效。完整構造和 verifyPlatformSignature 參考實現見簽名與身份驗證。
取得你的共用密鑰
雙向共用同一把密鑰簽名——見簽名參考裡的取得你的共用密鑰一節。