{
  "openapi": "3.0.3",
  "info": {
    "title": "Hash 场馆开放 API",
    "version": "1.1.0",
    "description": "商户服务端开放接口。所有请求均为POST JSON，无URL查询参数，最大请求体64KiB。金额、对外资金ID、注单ID和版本使用字符串；时间为Unix毫秒整数。浏览器仅使用签发的gameUrl进入游戏，不能持有商户密钥。"
  },
  "servers": [
    {
      "url": "/openapi/v1",
      "description": "当前部署环境；使用相同域名和端口。"
    }
  ],
  "tags": [
    {
      "name": "游戏"
    },
    {
      "name": "资金"
    },
    {
      "name": "注单"
    }
  ],
  "security": [
    {
      "MerchantId": [],
      "Timestamp": [],
      "Nonce": [],
      "Signature": []
    }
  ],
  "paths": {
    "/games/list": {
      "post": {
        "operationId": "games-list",
        "summary": "查询授权游戏",
        "description": "返回已授权游戏及当前状态、支持币种、语言和设备。先从这里取得实际gameId，示例ID不可直接使用。",
        "tags": ["游戏"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GameListRequest"
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "请求已处理；业务错误也可能返回HTTP 200。必须同时判断code与业务状态。",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/GameListResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorEnvelope"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "示例成功响应",
                    "value": {
                      "code": "OK",
                      "message": "请求已处理",
                      "requestId": "req_example",
                      "data": {
                        "games": [
                          {
                            "gameId": "HASH_game_from_list",
                            "gameName": "示例哈希游戏",
                            "category": "HASH",
                            "status": "AVAILABLE",
                            "currencies": ["USDT", "TRX", "CNY"],
                            "languages": ["zh-CN", "en-US"],
                            "devices": ["H5", "PC"],
                            "iconUrl": ""
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "请求方法、媒体类型或JSON格式错误",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "签名、时间戳或nonce认证失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "商户停用、来源地址或传输协议不允许",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "请求体超过64KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "超过商户配置的每分钟频率，返回Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "example": 60
                },
                "description": "建议等待秒数。"
              }
            }
          },
          "500": {
            "description": "系统异常或链接生成失败，资金结果须用原单号确认",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/games/launch": {
      "post": {
        "operationId": "games-launch",
        "summary": "获取游戏链接",
        "description": "自动建立独立场馆玩家并签发单次票据。可合并上分；链接仅300秒有效且只能兑换一次。玩家进入后只能访问当前游戏及其投注记录/详情。",
        "tags": ["游戏"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LaunchRequest"
              },
              "example": {
                "username": "player_001",
                "gameId": "HASH_game_from_list",
                "currency": "USDT",
                "language": "zh-CN",
                "device": "H5"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "请求已处理；业务错误也可能返回HTTP 200。必须同时判断code与业务状态。",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/LaunchResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorEnvelope"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "示例成功响应",
                    "value": {
                      "code": "OK",
                      "message": "请求已处理",
                      "requestId": "req_example",
                      "data": {
                        "username": "player_001",
                        "gameId": "HASH_game_from_list",
                        "currency": "USDT",
                        "launchStatus": "READY",
                        "gameUrl": "https://venue.example.test/play/?ticket=EXAMPLE_ONE_TIME_TICKET",
                        "expiresIn": 300,
                        "transfer": null
                      }
                    }
                  },
                  "fundedButUnavailable": {
                    "summary": "原上分已成功，但重新获取链接时游戏不可用",
                    "value": {
                      "code": "GAME_UNAVAILABLE",
                      "message": "游戏当前不可进入或投注",
                      "requestId": "req_example",
                      "data": {
                        "username": "player_001",
                        "gameId": "HASH_game_from_list",
                        "currency": "USDT",
                        "launchStatus": "FAILED",
                        "gameUrl": null,
                        "expiresIn": 0,
                        "transfer": {
                          "transferNo": "deposit_demo_001",
                          "orderNo": "VT_example_order",
                          "username": "player_001",
                          "direction": "IN",
                          "currency": "USDT",
                          "amount": "100",
                          "status": "SUCCESS",
                          "balanceBefore": "0",
                          "balanceAfter": "100",
                          "createdTime": 1792627200000,
                          "completedTime": 1792627200025,
                          "failureCode": null,
                          "failureReason": null
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "请求方法、媒体类型或JSON格式错误",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "签名、时间戳或nonce认证失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "商户停用、来源地址或传输协议不允许",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "请求体超过64KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "超过商户配置的每分钟频率，返回Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "example": 60
                },
                "description": "建议等待秒数。"
              }
            }
          },
          "500": {
            "description": "系统异常或链接生成失败，资金结果须用原单号确认",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "x-combined-request": {
          "username": "player_001",
          "gameId": "HASH_game_from_list",
          "currency": "USDT",
          "language": "zh-CN",
          "device": "H5",
          "amount": "100.00",
          "transferNo": "deposit_demo_001"
        }
      }
    },
    "/wallet/balance": {
      "post": {
        "operationId": "wallet-balance",
        "summary": "查询玩家余额",
        "description": "查询玩家在指定币种下的唯一可用余额。未建立玩家返回PLAYER_NOT_FOUND，不会自动创建玩家。",
        "tags": ["资金"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BalanceRequest"
              },
              "example": {
                "username": "player_001",
                "currency": "USDT"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "请求已处理；业务错误也可能返回HTTP 200。必须同时判断code与业务状态。",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/BalanceResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorEnvelope"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "示例成功响应",
                    "value": {
                      "code": "OK",
                      "message": "请求已处理",
                      "requestId": "req_example",
                      "data": {
                        "username": "player_001",
                        "currency": "USDT",
                        "balance": "100",
                        "queryTime": 1792627200000
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "请求方法、媒体类型或JSON格式错误",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "签名、时间戳或nonce认证失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "商户停用、来源地址或传输协议不允许",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "请求体超过64KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "超过商户配置的每分钟频率，返回Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "example": 60
                },
                "description": "建议等待秒数。"
              }
            }
          },
          "500": {
            "description": "系统异常或链接生成失败，资金结果须用原单号确认",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/wallet/deposit": {
      "post": {
        "operationId": "wallet-deposit",
        "summary": "玩家上分",
        "description": "原子增加玩家场馆余额并记录上下分订单和玩家流水；不校验商户预存或授信额度，不处理真实收付款。首次上分可自动创建玩家。相同transferNo和相同参数可安全重试。",
        "tags": ["资金"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransferRequest"
              },
              "example": {
                "username": "player_001",
                "transferNo": "deposit_demo_001",
                "amount": "100.00",
                "currency": "USDT"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "请求已处理；业务错误也可能返回HTTP 200。必须同时判断code与业务状态。",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/TransferResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorEnvelope"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "示例成功响应",
                    "value": {
                      "code": "OK",
                      "message": "请求已处理",
                      "requestId": "req_example",
                      "data": {
                        "transferNo": "deposit_demo_001",
                        "orderNo": "VT_example_order",
                        "username": "player_001",
                        "direction": "IN",
                        "currency": "USDT",
                        "amount": "100",
                        "status": "SUCCESS",
                        "balanceBefore": "0",
                        "balanceAfter": "100",
                        "createdTime": 1792627200000,
                        "completedTime": 1792627200025,
                        "failureCode": null,
                        "failureReason": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "请求方法、媒体类型或JSON格式错误",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "签名、时间戳或nonce认证失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "商户停用、来源地址或传输协议不允许",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "请求体超过64KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "超过商户配置的每分钟频率，返回Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "example": 60
                },
                "description": "建议等待秒数。"
              }
            }
          },
          "500": {
            "description": "系统异常或链接生成失败，资金结果须用原单号确认",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/wallet/withdraw": {
      "post": {
        "operationId": "wallet-withdraw",
        "summary": "玩家下分",
        "description": "原子扣减玩家场馆余额并记录上下分订单和玩家流水；仅校验玩家余额，不变更商户额度，不处理真实收付款。amount必须为明确的正数金额，不提供自动全额下分参数。",
        "tags": ["资金"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransferRequest"
              },
              "example": {
                "username": "player_001",
                "transferNo": "withdraw_demo_001",
                "amount": "50.00",
                "currency": "USDT"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "请求已处理；业务错误也可能返回HTTP 200。必须同时判断code与业务状态。",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/TransferResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorEnvelope"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "示例成功响应",
                    "value": {
                      "code": "OK",
                      "message": "请求已处理",
                      "requestId": "req_example",
                      "data": {
                        "transferNo": "withdraw_demo_001",
                        "orderNo": "VT_example_order",
                        "username": "player_001",
                        "direction": "OUT",
                        "currency": "USDT",
                        "amount": "50",
                        "status": "SUCCESS",
                        "balanceBefore": "100",
                        "balanceAfter": "50",
                        "createdTime": 1792627200000,
                        "completedTime": 1792627200025,
                        "failureCode": null,
                        "failureReason": null
                      }
                    }
                  },
                  "insufficientBalance": {
                    "summary": "玩家下分余额不足：code仍为OK，资金状态为FAILED",
                    "value": {
                      "code": "OK",
                      "message": "请求已处理",
                      "requestId": "req_example",
                      "data": {
                        "transferNo": "withdraw_demo_001",
                        "orderNo": "VT_example_order",
                        "username": "player_001",
                        "direction": "OUT",
                        "currency": "USDT",
                        "amount": "100",
                        "status": "FAILED",
                        "balanceBefore": null,
                        "balanceAfter": null,
                        "createdTime": 1792627200000,
                        "completedTime": 1792627200025,
                        "failureCode": "INSUFFICIENT_BALANCE",
                        "failureReason": "场馆余额不足"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "请求方法、媒体类型或JSON格式错误",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "签名、时间戳或nonce认证失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "商户停用、来源地址或传输协议不允许",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "请求体超过64KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "超过商户配置的每分钟频率，返回Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "example": 60
                },
                "description": "建议等待秒数。"
              }
            }
          },
          "500": {
            "description": "系统异常或链接生成失败，资金结果须用原单号确认",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/wallet/transfers/query": {
      "post": {
        "operationId": "wallet-transfers-query",
        "summary": "查询资金订单",
        "description": "按商户原资金单号查询持久化结果。TRANSFER_NOT_FOUND仅表示查询时暂未找到；若原请求仍在途中，不能据此换单号补发。",
        "tags": ["资金"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransferQueryRequest"
              },
              "example": {
                "transferNo": "deposit_demo_001"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "请求已处理；业务错误也可能返回HTTP 200。必须同时判断code与业务状态。",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/TransferResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorEnvelope"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "示例成功响应",
                    "value": {
                      "code": "OK",
                      "message": "请求已处理",
                      "requestId": "req_example",
                      "data": {
                        "transferNo": "deposit_demo_001",
                        "orderNo": "VT_example_order",
                        "username": "player_001",
                        "direction": "IN",
                        "currency": "USDT",
                        "amount": "100",
                        "status": "SUCCESS",
                        "balanceBefore": "0",
                        "balanceAfter": "100",
                        "createdTime": 1792627200000,
                        "completedTime": 1792627200025,
                        "failureCode": null,
                        "failureReason": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "请求方法、媒体类型或JSON格式错误",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "签名、时间戳或nonce认证失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "商户停用、来源地址或传输协议不允许",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "请求体超过64KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "超过商户配置的每分钟频率，返回Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "example": 60
                },
                "description": "建议等待秒数。"
              }
            }
          },
          "500": {
            "description": "系统异常或链接生成失败，资金结果须用原单号确认",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/bets/query": {
      "post": {
        "operationId": "bets-query",
        "summary": "分页查询投注记录",
        "description": "按当前商户隔离查询。时间窗口左闭右开且最长24小时；默认按updatedTime、betId升序。游标绑定商户、所有筛选条件和pageSize，有效30分钟。无total和page/pageNo参数。",
        "tags": ["注单"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BetQueryRequest"
              },
              "example": {
                "startTime": 1792627200000,
                "endTime": 1792630800000,
                "timeType": "UPDATE_TIME",
                "pageSize": 100
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "请求已处理；业务错误也可能返回HTTP 200。必须同时判断code与业务状态。",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/BetQueryResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorEnvelope"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "示例成功响应",
                    "value": {
                      "code": "OK",
                      "message": "请求已处理",
                      "requestId": "req_example",
                      "data": {
                        "records": [
                          {
                            "betId": "VB_example_bet",
                            "version": "2",
                            "username": "player_001",
                            "gameId": "HASH_game_from_list",
                            "gameName": "示例哈希游戏",
                            "currency": "USDT",
                            "betAmount": "10",
                            "validBetAmount": "10",
                            "payoutAmount": "19.38",
                            "netProfitAmount": "9.38",
                            "status": "SETTLED",
                            "betTime": 1792627200000,
                            "settledTime": 1792627230000,
                            "updatedTime": 1792627230000,
                            "gameDetail": {
                              "roundNo": "example_round",
                              "blockNo": "72000000",
                              "playName": "尾数单双 · 单",
                              "ruleId": "example_rule",
                              "betContent": "单",
                              "odds": ["1.938"],
                              "amountUnit": "10",
                              "multiple": 1,
                              "betCount": 1,
                              "result": {
                                "blockNo": "72000000",
                                "blockHash": "example_block_hash"
                              }
                            }
                          }
                        ],
                        "hasMore": false,
                        "nextCursor": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "请求方法、媒体类型或JSON格式错误",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "签名、时间戳或nonce认证失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "商户停用、来源地址或传输协议不允许",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "请求体超过64KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "超过商户配置的每分钟频率，返回Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "example": 60
                },
                "description": "建议等待秒数。"
              }
            }
          },
          "500": {
            "description": "系统异常或链接生成失败，资金结果须用原单号确认",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "MerchantId": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Merchant-Id",
        "description": "运营分配的商户号，1～64位字母、数字、下划线或短横线，区分大小写。"
      },
      "Timestamp": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Timestamp",
        "description": "13位Unix毫秒字符串，服务器允许前后5分钟时钟偏差。"
      },
      "Nonce": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Nonce",
        "description": "16～64位字母、数字、下划线或短横线；每次HTTP请求生成新值。"
      },
      "Signature": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Signature",
        "description": "小写64位HMAC-SHA256十六进制签名，密钥按原字符串UTF-8使用，不做Base64解码。"
      }
    },
    "schemas": {
      "Identifier": {
        "type": "string",
        "description": "区分大小写；1～64位字母、数字、下划线或短横线。",
        "pattern": "^[A-Za-z0-9_-]{1,64}$",
        "minLength": 1,
        "maxLength": 64
      },
      "Amount": {
        "type": "string",
        "description": "普通十进制金额字符串；禁止数字类型、负数、科学计数法。USDT/TRX最多6位小数，CNY最多2位；上下分必须大于0并满足运营配置的限额。",
        "pattern": "^(0|[1-9][0-9]{0,17})(\\.[0-9]{1,6})?$",
        "example": "100.00"
      },
      "Currency": {
        "type": "string",
        "description": "省略时使用商户默认币种；重试建议显式传入原币种。",
        "enum": ["USDT", "TRX", "CNY"]
      },
      "GameListRequest": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string",
            "description": "可选分类筛选。",
            "enum": ["HASH", "LOTTERY"]
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          }
        },
        "additionalProperties": false
      },
      "LaunchRequest": {
        "type": "object",
        "properties": {
          "username": {
            "$ref": "#/components/schemas/Identifier"
          },
          "gameId": {
            "type": "string",
            "description": "从游戏列表取得的实际gameId，禁止按示例硬编码。",
            "minLength": 1
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "amount": {
            "type": "string",
            "description": "可选，默认\"0\"仅取链接；大于0表示合并上分，必须同时提供transferNo。",
            "pattern": "^(0|[1-9][0-9]{0,17})(\\.[0-9]{1,6})?$",
            "example": "100.00",
            "default": "0"
          },
          "transferNo": {
            "type": "string",
            "description": "仅合并上分时必填；只取链接（amount=0）时不得携带。同商户下全局唯一，与独立上分接口共用。",
            "pattern": "^[A-Za-z0-9_-]{1,64}$",
            "minLength": 1,
            "maxLength": 64
          },
          "language": {
            "type": "string",
            "description": "须在游戏languages列表内。",
            "default": "zh-CN"
          },
          "device": {
            "type": "string",
            "description": "须在游戏devices列表内。",
            "enum": ["H5", "PC"],
            "default": "H5"
          },
          "returnUrl": {
            "type": "string",
            "description": "省略时使用商户配置。必须为HTTPS、无账号密码、端口443或不指定端口，域名与商户白名单精确匹配。",
            "format": "uri",
            "maxLength": 2048
          }
        },
        "additionalProperties": false,
        "required": ["username", "gameId"]
      },
      "BalanceRequest": {
        "type": "object",
        "properties": {
          "username": {
            "$ref": "#/components/schemas/Identifier"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          }
        },
        "additionalProperties": false,
        "required": ["username"]
      },
      "TransferRequest": {
        "type": "object",
        "properties": {
          "username": {
            "$ref": "#/components/schemas/Identifier"
          },
          "transferNo": {
            "$ref": "#/components/schemas/Identifier"
          },
          "amount": {
            "$ref": "#/components/schemas/Amount"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          }
        },
        "additionalProperties": false,
        "required": ["username", "transferNo", "amount"]
      },
      "TransferQueryRequest": {
        "type": "object",
        "properties": {
          "transferNo": {
            "$ref": "#/components/schemas/Identifier"
          }
        },
        "additionalProperties": false,
        "required": ["transferNo"]
      },
      "BetQueryRequest": {
        "type": "object",
        "properties": {
          "startTime": {
            "type": "integer",
            "format": "int64",
            "description": "窗口起点，Unix毫秒整数，包含此时刻。",
            "minimum": 0
          },
          "endTime": {
            "type": "integer",
            "format": "int64",
            "description": "窗口终点，Unix毫秒整数，不包含此时刻；必须大于startTime，跨度不超过86400000毫秒。",
            "minimum": 1
          },
          "timeType": {
            "type": "string",
            "description": "推荐使用更新时间同步结算和后续修正。",
            "enum": ["UPDATE_TIME", "BET_TIME"],
            "default": "UPDATE_TIME"
          },
          "username": {
            "$ref": "#/components/schemas/Identifier"
          },
          "gameId": {
            "type": "string",
            "description": "可选游戏ID筛选。"
          },
          "betId": {
            "type": "string",
            "description": "可选场馆注单ID筛选，按字符串保存。"
          },
          "currency": {
            "type": "string",
            "description": "可选币种精确筛选。"
          },
          "status": {
            "type": "string",
            "description": "可选注单状态筛选。",
            "enum": ["PENDING", "SETTLED", "CANCELED"]
          },
          "pageSize": {
            "type": "integer",
            "format": "int64",
            "description": "单页条数。",
            "minimum": 1,
            "maximum": 500,
            "default": 100
          },
          "cursor": {
            "type": "string",
            "description": "首屏不传；下一页原样使用nextCursor，并保持其他条件与pageSize不变。有效30分钟。"
          }
        },
        "additionalProperties": false,
        "required": ["startTime", "endTime"]
      },
      "Game": {
        "type": "object",
        "properties": {
          "gameId": {
            "type": "string",
            "description": "场馆游戏ID。"
          },
          "gameName": {
            "type": "string",
            "description": "游戏名称。"
          },
          "category": {
            "type": "string",
            "description": "",
            "enum": ["HASH", "LOTTERY"]
          },
          "status": {
            "type": "string",
            "description": "仅AVAILABLE可获取进入链接并投注。",
            "enum": ["AVAILABLE", "MAINTENANCE", "DISABLED"]
          },
          "currencies": {
            "type": "array",
            "items": {
              "type": "string",
              "description": ""
            },
            "description": "商户与游戏共同支持的币种交集。"
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string",
              "description": ""
            },
            "description": "支持的语言列表。"
          },
          "devices": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "",
              "enum": ["H5", "PC"]
            },
            "description": "支持的设备列表。"
          },
          "iconUrl": {
            "type": "string",
            "description": "图标地址，可为空。"
          }
        },
        "additionalProperties": false,
        "required": [
          "gameId",
          "gameName",
          "category",
          "status",
          "currencies",
          "languages",
          "devices",
          "iconUrl"
        ]
      },
      "GameListData": {
        "type": "object",
        "properties": {
          "games": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Game"
            },
            "description": "仅返回当前商户已授权的游戏；可能为空。"
          }
        },
        "additionalProperties": false,
        "required": ["games"]
      },
      "BalanceData": {
        "type": "object",
        "properties": {
          "username": {
            "type": "string",
            "description": ""
          },
          "currency": {
            "type": "string",
            "description": ""
          },
          "balance": {
            "type": "string",
            "description": "唯一可用余额，不含冻结余额。"
          },
          "queryTime": {
            "type": "integer",
            "format": "int64",
            "description": "查询时刻，Unix毫秒。"
          }
        },
        "additionalProperties": false,
        "required": ["username", "currency", "balance", "queryTime"]
      },
      "TransferData": {
        "type": "object",
        "properties": {
          "transferNo": {
            "type": "string",
            "description": "商户原始资金单号。"
          },
          "orderNo": {
            "type": "string",
            "description": "场馆资金订单ID，VT_前缀；作为字符串保存。"
          },
          "username": {
            "type": "string",
            "description": ""
          },
          "direction": {
            "type": "string",
            "description": "IN上分，OUT下分。",
            "enum": ["IN", "OUT"]
          },
          "currency": {
            "type": "string",
            "description": ""
          },
          "amount": {
            "type": "string",
            "description": "本次资金金额。"
          },
          "status": {
            "type": "string",
            "description": "资金最终处理状态；不能仅凭外层code=OK判断成功。",
            "enum": ["SUCCESS", "FAILED", "PENDING"]
          },
          "balanceBefore": {
            "type": "string",
            "description": "资金操作前的可用余额，未取得余额时为null。",
            "nullable": true
          },
          "balanceAfter": {
            "type": "string",
            "description": "资金操作成功后的可用余额，未成功记账时为null。",
            "nullable": true
          },
          "createdTime": {
            "type": "integer",
            "format": "int64",
            "description": "创建时刻，Unix毫秒。"
          },
          "completedTime": {
            "type": "integer",
            "format": "int64",
            "description": "完成时刻，Unix毫秒；待处理时可为null。",
            "nullable": true
          },
          "failureCode": {
            "type": "string",
            "description": "失败原因码，成功时为null。",
            "nullable": true
          },
          "failureReason": {
            "type": "string",
            "description": "失败说明，成功时为null。",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "required": [
          "transferNo",
          "orderNo",
          "username",
          "direction",
          "currency",
          "amount",
          "status",
          "balanceBefore",
          "balanceAfter",
          "createdTime",
          "completedTime",
          "failureCode",
          "failureReason"
        ]
      },
      "LaunchData": {
        "type": "object",
        "properties": {
          "username": {
            "type": "string",
            "description": ""
          },
          "gameId": {
            "type": "string",
            "description": ""
          },
          "currency": {
            "type": "string",
            "description": ""
          },
          "launchStatus": {
            "type": "string",
            "description": "只有READY才能打开gameUrl；该状态与transfer.status分别判断。",
            "enum": ["READY", "FAILED", "TRANSFER_FAILED", "TRANSFER_PENDING"]
          },
          "gameUrl": {
            "type": "string",
            "description": "单次进入链接，不要缓存或写入访问日志；未就绪时为null。",
            "nullable": true
          },
          "expiresIn": {
            "type": "integer",
            "format": "int64",
            "description": "READY时为300秒，否则为0。"
          },
          "transfer": {
            "$ref": "#/components/schemas/NullableTransferData"
          }
        },
        "additionalProperties": false,
        "required": [
          "username",
          "gameId",
          "currency",
          "launchStatus",
          "gameUrl",
          "expiresIn",
          "transfer"
        ]
      },
      "BetDetail": {
        "type": "object",
        "properties": {
          "roundNo": {
            "type": "string",
            "description": "期号。"
          },
          "blockNo": {
            "type": "string",
            "description": "区块高度，字符串。"
          },
          "playName": {
            "type": "string",
            "description": "玩法名称。"
          },
          "ruleId": {
            "type": "string",
            "description": "玩法ID。"
          },
          "betContent": {
            "type": "string",
            "description": "投注内容。"
          },
          "odds": {
            "type": "array",
            "items": {
              "type": "string",
              "description": ""
            },
            "description": "下注时冻结的实际赔率，各档顺序保留。"
          },
          "amountUnit": {
            "type": "string",
            "description": "单注金额。"
          },
          "multiple": {
            "type": "integer",
            "format": "int64",
            "description": "倍数。"
          },
          "betCount": {
            "type": "integer",
            "format": "int64",
            "description": "注数。"
          },
          "result": {
            "type": "object",
            "additionalProperties": true,
            "description": "结算后才返回，包含blockNo、blockHash；彩票另含numbers。游戏类型不同，结果字段可能不同。"
          }
        },
        "additionalProperties": false,
        "required": [
          "roundNo",
          "blockNo",
          "playName",
          "ruleId",
          "betContent",
          "odds",
          "amountUnit",
          "multiple",
          "betCount"
        ]
      },
      "BetRecord": {
        "type": "object",
        "properties": {
          "betId": {
            "type": "string",
            "description": "唯一场馆注单ID，VB_前缀；作为字符串保存。"
          },
          "version": {
            "type": "string",
            "description": "结算/修正版本，数字字符串；按同betId的更高版本覆盖。"
          },
          "username": {
            "type": "string",
            "description": ""
          },
          "gameId": {
            "type": "string",
            "description": ""
          },
          "gameName": {
            "type": "string",
            "description": ""
          },
          "currency": {
            "type": "string",
            "description": ""
          },
          "betAmount": {
            "type": "string",
            "description": "下注金额。"
          },
          "validBetAmount": {
            "type": "string",
            "description": "十进制金额字符串；结算前允许为null。",
            "nullable": true
          },
          "payoutAmount": {
            "type": "string",
            "description": "十进制金额字符串；结算前允许为null。",
            "nullable": true
          },
          "netProfitAmount": {
            "type": "string",
            "description": "十进制金额字符串；结算前允许为null。",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "",
            "enum": ["PENDING", "SETTLED", "CANCELED"]
          },
          "betTime": {
            "type": "integer",
            "format": "int64",
            "description": "下注时刻，Unix毫秒。"
          },
          "settledTime": {
            "type": "integer",
            "format": "int64",
            "description": "结算时刻，未结算为null。",
            "nullable": true
          },
          "updatedTime": {
            "type": "integer",
            "format": "int64",
            "description": "最后更新时刻，Unix毫秒。"
          },
          "gameDetail": {
            "$ref": "#/components/schemas/BetDetail"
          }
        },
        "additionalProperties": false,
        "required": [
          "betId",
          "version",
          "username",
          "gameId",
          "gameName",
          "currency",
          "betAmount",
          "validBetAmount",
          "payoutAmount",
          "netProfitAmount",
          "status",
          "betTime",
          "settledTime",
          "updatedTime",
          "gameDetail"
        ]
      },
      "BetQueryData": {
        "type": "object",
        "properties": {
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BetRecord"
            },
            "description": ""
          },
          "hasMore": {
            "type": "boolean",
            "description": "是否还有下一页。"
          },
          "nextCursor": {
            "type": "string",
            "description": "下一页游标，最后一页为null。",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "required": ["records", "hasMore", "nextCursor"]
      },
      "ErrorEnvelope": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "not": {
              "enum": ["OK"]
            },
            "description": "错误码。"
          },
          "message": {
            "type": "string",
            "description": "错误说明。"
          },
          "requestId": {
            "type": "string",
            "description": "排查问题时提供的请求编号。"
          },
          "data": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "通常为null；进入游戏异常时可能携带LaunchData，须继续检查transfer。"
          }
        },
        "additionalProperties": false,
        "required": ["code", "message", "requestId", "data"]
      },
      "GameListResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "",
            "enum": ["OK"]
          },
          "message": {
            "type": "string",
            "description": ""
          },
          "requestId": {
            "type": "string",
            "description": ""
          },
          "data": {
            "$ref": "#/components/schemas/GameListData"
          }
        },
        "additionalProperties": false,
        "required": ["code", "message", "requestId", "data"]
      },
      "BalanceResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "",
            "enum": ["OK"]
          },
          "message": {
            "type": "string",
            "description": ""
          },
          "requestId": {
            "type": "string",
            "description": ""
          },
          "data": {
            "$ref": "#/components/schemas/BalanceData"
          }
        },
        "additionalProperties": false,
        "required": ["code", "message", "requestId", "data"]
      },
      "TransferResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "",
            "enum": ["OK"]
          },
          "message": {
            "type": "string",
            "description": ""
          },
          "requestId": {
            "type": "string",
            "description": ""
          },
          "data": {
            "$ref": "#/components/schemas/TransferData"
          }
        },
        "additionalProperties": false,
        "required": ["code", "message", "requestId", "data"]
      },
      "LaunchResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "",
            "enum": ["OK"]
          },
          "message": {
            "type": "string",
            "description": ""
          },
          "requestId": {
            "type": "string",
            "description": ""
          },
          "data": {
            "$ref": "#/components/schemas/LaunchData"
          }
        },
        "additionalProperties": false,
        "required": ["code", "message", "requestId", "data"]
      },
      "BetQueryResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "",
            "enum": ["OK"]
          },
          "message": {
            "type": "string",
            "description": ""
          },
          "requestId": {
            "type": "string",
            "description": ""
          },
          "data": {
            "$ref": "#/components/schemas/BetQueryData"
          }
        },
        "additionalProperties": false,
        "required": ["code", "message", "requestId", "data"]
      },
      "NullableTransferData": {
        "type": "object",
        "properties": {
          "transferNo": {
            "type": "string",
            "description": "商户原始资金单号。"
          },
          "orderNo": {
            "type": "string",
            "description": "场馆资金订单ID，VT_前缀；作为字符串保存。"
          },
          "username": {
            "type": "string",
            "description": ""
          },
          "direction": {
            "type": "string",
            "description": "IN上分，OUT下分。",
            "enum": ["IN", "OUT"]
          },
          "currency": {
            "type": "string",
            "description": ""
          },
          "amount": {
            "type": "string",
            "description": "本次资金金额。"
          },
          "status": {
            "type": "string",
            "description": "资金最终处理状态；不能仅凭外层code=OK判断成功。",
            "enum": ["SUCCESS", "FAILED", "PENDING"]
          },
          "balanceBefore": {
            "type": "string",
            "description": "资金操作前的可用余额，未取得余额时为null。",
            "nullable": true
          },
          "balanceAfter": {
            "type": "string",
            "description": "资金操作成功后的可用余额，未成功记账时为null。",
            "nullable": true
          },
          "createdTime": {
            "type": "integer",
            "format": "int64",
            "description": "创建时刻，Unix毫秒。"
          },
          "completedTime": {
            "type": "integer",
            "format": "int64",
            "description": "完成时刻，Unix毫秒；待处理时可为null。",
            "nullable": true
          },
          "failureCode": {
            "type": "string",
            "description": "失败原因码，成功时为null。",
            "nullable": true
          },
          "failureReason": {
            "type": "string",
            "description": "失败说明，成功时为null。",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "required": [
          "transferNo",
          "orderNo",
          "username",
          "direction",
          "currency",
          "amount",
          "status",
          "balanceBefore",
          "balanceAfter",
          "createdTime",
          "completedTime",
          "failureCode",
          "failureReason"
        ],
        "nullable": true,
        "description": "合并上分的资金结果；仅取链接时为null。即使外层code非OK，也须检查原资金结果。"
      }
    }
  },
  "x-signature-vector": {
    "merchantId": "merchant_demo",
    "secret": "example_secret_not_a_real_key",
    "timestamp": "1792627200000",
    "nonce": "example_nonce_000000000001",
    "method": "POST",
    "path": "/openapi/v1/wallet/balance",
    "body": "{\"username\":\"player_001\",\"currency\":\"USDT\"}",
    "bodyHash": "f3d3c5f7599a92f9f1c0de9d851fd0da0edb5fb0897a5d2f1830bcb8f4faaeaa",
    "signText": "merchant_demo\n1792627200000\nexample_nonce_000000000001\nPOST\n/openapi/v1/wallet/balance\nf3d3c5f7599a92f9f1c0de9d851fd0da0edb5fb0897a5d2f1830bcb8f4faaeaa",
    "signature": "9753d768d3b57c2c7cfa2fb78b2d60f6ca0ae4e0434447ec8976ce9b6fee4fd7"
  },
  "x-error-codes": [
    [
      "AUTH_FAILED",
      "401 / 403",
      "认证、商户状态、来源IP或传输协议不允许。核对请求头、密钥、白名单。"
    ],
    [
      "REQUEST_EXPIRED",
      "401",
      "时间戳超过服务器前后5分钟范围；同步时钟后使用新timestamp/nonce重新签名。"
    ],
    [
      "REPLAY_REJECTED",
      "401",
      "nonce已使用。保留业务单号和业务参数，换本次HTTP请求的nonce重新签名。"
    ],
    [
      "RATE_LIMITED",
      "429",
      "达到商户配置的每分钟请求限制，遵守Retry-After: 60；资金请求不要换业务单号。"
    ],
    [
      "INVALID_ARGUMENT",
      "200 / 400",
      "字段类型、金额精度、时间范围或请求格式不正确；接口会拒绝未声明的JSON字段。"
    ],
    ["UNSUPPORTED_CURRENCY", "200", "场馆、商户或游戏未启用该币种。"],
    [
      "PLAYER_NOT_FOUND",
      "200",
      "余额查询时玩家不存在；下分时也可能作为订单failureCode返回。"
    ],
    [
      "TRANSFER_CONFLICT",
      "200",
      "原资金单号已用于不同的用户、币种、方向或金额，禁止重用此单号。"
    ],
    [
      "TRANSFER_NOT_FOUND",
      "200",
      "查询时暂未找到资金单；不等于确认失败，原请求可能仍在处理中。"
    ],
    ["GAME_NOT_FOUND", "200", "游戏不存在或当前商户未获授权。"],
    [
      "GAME_UNAVAILABLE",
      "200",
      "游戏维护或停用；已有成功上分不会因此自动退款。"
    ],
    [
      "GAME_LAUNCH_FAILED",
      "500",
      "链接生成失败；检查data.transfer或原资金单号后再获取链接。"
    ],
    [
      "INVALID_CURSOR",
      "200",
      "游标无效、过期，或商户/筛选条件/pageSize发生变化。"
    ],
    [
      "INTERNAL_ERROR",
      "500",
      "系统异常，保留requestId；资金操作按原transferNo查询确认。"
    ]
  ]
}
