#避坑指南

這幾個月對接 PetaX 單錢包時踩過的坑,按「現象 → 根因 → 應對」整理。全部是我方實測結論,能幫後來者少走彎路。

#1. settled-ticket 靜默跳過陷阱 🔴 最容易誤判

現象:結算通道(HTTP /petax/settled-ticket 或 RabbitMQ settled_win/loss)看起來一切正常,但對賬頁永遠沒有 MATCHED,petax_transactions 裡也查不到 settled_ticket 記錄。

根因:結算處理邏輯裡,若回調攜帶的 username 在我方 petax_user_links 查不到對應用戶,會打一條 warn 日誌、返回成功(HTTP 200 / AMQP ACK)、但完全不寫庫。這是刻意設計(避免 PetaX 因失敗而重發風暴),但代價是:

「PetaX 根本沒推消息」和「消息到了但字段/用戶名對不上、被靜默丟棄」在數據庫里長得一模一樣——都是 0 行。

應對:不要只看 DB 判斷結算通道通不通。要麼掛一個臨時消費者/抓包實測原始消息體(見下),要麼檢查回調日誌(servicelog,integration=petax)確認調用次數與狀態碼。只有拿到原始 payload,才能分清是「沒推」還是「推了但丟了」。

#2. Service API 前綴 520,和白名單無關

現象:出站調用 PetaX 的 Service API(如交易查詢接口)返回 Cloudflare 520,帶 token 不帶 token結果一樣。

根因:520 是「Cloudflare 連上了源站,但源站對這個路徑返回未知錯誤」——即請求根本沒走到鑑權層,是路由層面就失敗了。第一反應容易歸因到「IP 白名單沒配」,但如果同一個域名下別的路徑(比如認證/JWKS)能正常 200,就說明白名單沒問題,是 URL 前綴本身配錯了

應對:排查 520 時先做對照實驗——同主機換一條已知能用的路徑(如 JWKS)。兩者結果不同,才能定位到底是網絡/白名單問題,還是純粹的路徑/前綴問題。別急著去找 PetaX 要「加白名單」,先自證問題範圍。

#3. 隊列訂閱成功 ≠ 有消息投遞

現象:RabbitMQ 隊列存在、消費者在線(能連、能訂閱),但某類通知(如贏單/輸單結算)長期零消息,而另一類(如開獎結果)正常收得到。

根因:隊列「建好了」只代表可以訂閱,是否往裡面投遞消息是發佈方(PetaX)的事。隊列存在不等於該通知已對我方商戶啟用。

應對:用「安全 peek」(basic.get 一條打印後 Nack(requeue=true) 放回,不銷燬)加時間窗觀察;若同一時間段內確定發生了對應業務事件(如真實結算了幾張注單)卻仍零消息,基本可判定是 PetaX 側未啟用該通知,需要主動去問,而不是繼續排查自己的消費代碼。

#4. 出口 IP 白名單:EOF ≠ 證書/配置問題

現象:mTLS 連接 RabbitMQ 時,TCP 能連上,但發出 ClientHello 後立刻 EOF,讀到 0 字節。

根因:這不是證書錯、cipher 不匹配、或 serverName 配錯(那些情況會收到 TLS alert,讀到的字節數 > 0)。read 0 bytes握手包都沒收到回應就被掛斷,是網絡層直接丟棄——出口 IP 未在白名單。

應對:用 openssl s_client 直接測,看 read N bytes 是 0 還是有內容,一眼區分「網絡層拒絕」和「協議層拒絕」,不要憑感覺調整證書配置。

#5. admin 時間選擇器格式 vs 嚴格 RFC3339

現象:後臺某些頁面的時間範圍選擇器,選完提交後端點返回 400。

根因:前端表格組件在特定展示模式下,時間參數序列化成 YYYY-MM-DD HH:mm:ss(不帶時區),而部分早期接口用嚴格 time.Parse(RFC3339) 解析——這個格式解析不出來。這個 bug 平時不容易被發現,因為它常被其他更顯眼的錯誤(如 502)掩蓋。

應對:後端解析時間參數應兼容三種常見形態(RFC3339、空格分隔的 datetime、純日期),缺時區時按 UTC 處理,不要假設前端一定發 RFC3339。

#6. 冪等鍵設計:結算通知不限時間窗匹配

現象:如果對賬邏輯簡單地「時間窗內的投注 x 時間窗內的結算」兩兩比較,會把「投注在窗內、但結算稍晚才到(跨到窗外)」的正常場景誤判成「未結算」。

應對:投注側按時間窗過濾沒問題,但去匹配結算記錄時應該按 ticketId 全局查找(不限時間窗),因為結算總是滯後於投注發生。

#7. 房間(桌臺)是靜態清單,沒有查詢接口

現象:想通過接口動態獲取當前可用房間列表,找不到對應 API。

根因:PetaX 沒有「列房間」的 REST 接口,房間信息也不經 RabbitMQ 推送。房間是靜態維護的清單,由 PetaX 一次性提供。

應對:不要設計成運行時動態拉取房間列表;房間 id 需要向 PetaX 索要,且要確認是哪個環境(staging/production)可用的真實 id——用錯環境的房間 id 會導致玩家進入遊戲後房間不存在。

#8. 首次玩家必須先開戶,否則 launch 直接 502

現象:新用戶第一次點開 PetaX 遊戲,直接失敗。

根因:PetaX 側賬號需要預先創建(開戶/create-agent),不是首次登錄時自動生成。若我方直接拿一個從未開戶的映射賬號去登錄,登錄本身就會失敗,導致整個 launch 鏈路 502。

應對:launch 流程裡,確保「首次玩家 → 先開戶 → 再登錄」的順序被覆蓋到,並且開戶失敗與登錄失敗要能在日誌裡區分開,否則很難判斷是哪一步出的問題。

#9. 金額口徑:兩次換算,別把單位搞混

現象:核對金額時數字對不上,懷疑資金有誤差。

根因:PetaX 側金額是它自己的最小單位(minor units),要經過標度換算(scale)才能變成通用整數金額,再按匯率換算成我方統一餘額的計價單位。兩次換算疊加,如果只按面值直接比較,看起來會"對不上",但其實是單位不同。

應對:核對金額前先確認雙方在比較同一層單位;展示層可以兩個數字並列展示(不強行判等),避免把正常的換算誤差當成資金問題去排查。