{"openapi":"3.1.0","info":{"title":"Western Zodiac Provider — Sandbox","version":"0.1.0","description":"Sandbox implementation only. HMAC details: 接入指南.md. HTTP 202 indicates durable acceptance, not debit success. All times are UTC epoch milliseconds except X-Timestamp (seconds)."},"servers":[{"url":"https://sandbox-api.12zodi.com","description":"Test service; test credentials only"},{"url":"https://api.12zodi.com","description":"Production service; separately approved credentials only"}],"paths":{"/v1/games":{"get":{"summary":"Game catalog","operationId":"GET__v1_games","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/game":{"get":{"summary":"Merchant feed with playback URL, current issue, server time, odds and limits","operationId":"GET__v1_game","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/issues/current":{"get":{"summary":"Current authoritative issue and betting status","operationId":"GET__v1_issues_current","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/odds":{"get":{"summary":"Current round zodiac odds snapshot, inclusive of stake","operationId":"GET__v1_odds","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/balance":{"post":{"summary":"Merchant player wallet balance","operationId":"POST__v1_balance","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"playerId":{"type":"string"},"currency":{"type":"string","pattern":"^[A-Z]{3}$"}},"required":["playerId","currency"],"additionalProperties":false}}}}}},"/v1/bets":{"post":{"summary":"Merchant server bet, authenticated with HMAC and source IP","operationId":"POST__v1_bets","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[],"responses":{"202":{"description":"Durably accepted; query order for final wallet state.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Bet"},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantBetRequest"}}}}},"get":{"summary":"List tenant orders, newest first, maximum 100 per page","operationId":"GET__v1_bets","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BetPage"},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/results":{"get":{"summary":"Formal results and cancelled rounds","operationId":"GET__v1_results","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[{"name":"issueNo","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/launches":{"post":{"summary":"Create or replay unconsumed game launch","operationId":"POST__v1_launches","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Launch"},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchRequest"}}}}}},"/v1/bets/{id}":{"get":{"summary":"Tenant order details","operationId":"GET__v1_bets_id_","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Bet"},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/transactions/{id}":{"get":{"summary":"Tenant wallet transaction","operationId":"GET__v1_transactions_id_","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/reconciliation":{"get":{"summary":"Local confirmed and unresolved totals; not external reconciliation","operationId":"GET__v1_reconciliation","security":[{"OperatorId":[],"Timestamp":[],"Nonce":[],"Signature":[]}],"parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":9007199254740991}},{"name":"until","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true},"requestId":{"type":"string"}},"required":["data","requestId"],"additionalProperties":false}}}},"default":{"description":"Failure. Wallet timeouts remain unresolved; do not invent a new transaction ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"OperatorId":{"type":"apiKey","in":"header","name":"X-Operator-Id"},"Timestamp":{"type":"apiKey","in":"header","name":"X-Timestamp"},"Nonce":{"type":"apiKey","in":"header","name":"X-Nonce"},"Signature":{"type":"apiKey","in":"header","name":"X-Signature"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"requestId":{"type":"string"}},"required":["error","requestId"],"additionalProperties":false},"BetItem":{"type":"object","properties":{"signCode":{"type":"string","enum":["aries","taurus","gemini","cancer","leo","virgo","libra","scorpio","sagittarius","capricorn","aquarius","pisces"]},"amount":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Integer minor currency units; decimals are agreed per operator."},"gameAmount":{"type":"string","pattern":"^\\d{1,16}(\\.\\d{1,8})?$","description":"Game units. Converted exactly using merchant denomination and wallet decimals. Do not also send amount."}},"required":["signCode"],"additionalProperties":false,"oneOf":[{"required":["amount"],"not":{"required":["gameAmount"]}},{"required":["gameAmount"],"not":{"required":["amount"]}}]},"BetRequest":{"type":"object","properties":{"requestId":{"type":"string","minLength":1,"maxLength":128},"issueNo":{"type":"string"},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"items":{"type":"array","items":{"$ref":"#/components/schemas/BetItem"},"minItems":1,"maxItems":12}},"required":["requestId","issueNo","currency","items"],"additionalProperties":false},"MerchantBetRequest":{"type":"object","properties":{"playerId":{"type":"string","minLength":1,"maxLength":128},"requestId":{"type":"string","minLength":1,"maxLength":128},"issueNo":{"type":"string"},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"items":{"type":"array","items":{"$ref":"#/components/schemas/BetItem"},"minItems":1,"maxItems":12}},"required":["playerId","requestId","issueNo","currency","items"],"additionalProperties":false},"MerchantRequest":{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"name":{"type":"string"},"contactName":{"type":"string"},"contactEmail":{"type":"string","format":"email"},"website":{"type":"string"},"notes":{"type":"string"},"walletUrl":{"type":"string","format":"uri"},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"decimals":{"type":"integer","minimum":0,"maximum":6},"minBet":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Integer minor currency units; decimals are agreed per operator."},"maxBet":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Integer minor currency units; decimals are agreed per operator."},"maxRoundBet":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Integer minor currency units; decimals are agreed per operator."},"allowedIps":{"type":"array","items":{"type":"string"}},"reason":{"type":"string"},"tokenBaseUnits":{"type":"integer","minimum":1,"maximum":9007199254740991},"tokenUnits":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["id","name","contactName","contactEmail","walletUrl","currency","decimals","minBet","maxBet","maxRoundBet","allowedIps"],"additionalProperties":false},"LaunchRequest":{"type":"object","properties":{"gameCode":{"const":"western_zodiac_live"},"playerId":{"type":"string","minLength":1,"maxLength":128},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"requestId":{"type":"string","minLength":1,"maxLength":128}},"required":["gameCode","playerId","currency","requestId"],"additionalProperties":false},"Launch":{"type":"object","properties":{"launchUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["launchUrl","expiresAt"],"additionalProperties":false},"Session":{"type":"object","properties":{"sessionToken":{"type":"string"},"expiresAt":{"type":"integer","minimum":0,"maximum":9007199254740991},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"decimals":{"type":"integer","minimum":0,"maximum":9007199254740991},"playerId":{"type":"string"}},"required":["sessionToken","expiresAt","currency","decimals","playerId"],"additionalProperties":false},"OperatorRequest":{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"name":{"type":"string"},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"decimals":{"type":"integer","minimum":0,"maximum":6},"minBet":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Integer minor currency units; decimals are agreed per operator."},"maxBet":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Integer minor currency units; decimals are agreed per operator."},"maxRoundBet":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Integer minor currency units; decimals are agreed per operator."},"walletUrl":{"type":"string","format":"uri"},"secret":{"type":"string","minLength":32,"maxLength":256,"writeOnly":true},"allowedIps":{"type":"array","items":{"type":"string"}}},"required":["id","name","currency","decimals","minBet","maxBet","maxRoundBet","walletUrl","secret"],"additionalProperties":false},"IssueRequest":{"type":"object","properties":{"issueNo":{"type":"string"},"opensAt":{"type":"integer","minimum":1,"maximum":9007199254740991},"closesAt":{"type":"integer","minimum":1,"maximum":9007199254740991},"status":{"enum":["betting","closed"]},"playbackUrl":{"type":"string"}},"required":["issueNo","opensAt","closesAt","status"],"additionalProperties":false},"Transaction":{"type":"object","properties":{"id":{"type":"string"},"kind":{"enum":["debit","credit","refund"]},"original_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"amount":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Integer minor currency units; decimals are agreed per operator."},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"status":{"enum":["pending","processing","unknown","succeeded","declined"]},"attempts":{"type":"integer","minimum":0,"maximum":9007199254740991},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}]},"completed_at":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["id","kind","original_id","amount","currency","status","attempts","last_error","completed_at"],"additionalProperties":false},"Bet":{"type":"object","properties":{"id":{"type":"string"},"operatorId":{"type":"string"},"playerId":{"type":"string"},"issueNo":{"type":"string"},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"amount":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Integer minor currency units; decimals are agreed per operator."},"items":{"type":"array","items":{"type":"object","additionalProperties":true}},"status":{"enum":["debit_pending","active","rejected","settlement_pending","settled","refund_pending","refunded","manual"]},"payout":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"mappingVersion":{"type":"string"},"ruleVersion":{"type":"string"},"createdAt":{"type":"integer","minimum":0,"maximum":9007199254740991},"updatedAt":{"type":"integer","minimum":0,"maximum":9007199254740991},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"idempotentReplay":{"type":"boolean"}},"required":["id","operatorId","playerId","issueNo","currency","amount","items","status","payout","mappingVersion","ruleVersion","createdAt","updatedAt","transactions"],"additionalProperties":false},"BetPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Bet"}},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["items","nextCursor"],"additionalProperties":false}}}}