{
  "openapi": "3.1.0",
  "info": {
    "title": "Operator Seamless Wallet Contract — Sandbox",
    "version": "0.1.0",
    "description": "Implemented by the OPERATOR, not this Provider. Every 200 response requires X-Wallet-Signature; see 单一钱包协议.md. not_found is query-only and authoritative."
  },
  "servers": [
    {
      "url": "https://sandbox-wallet.example"
    }
  ],
  "security": [
    {
      "OperatorId": [],
      "Timestamp": [],
      "Nonce": [],
      "Signature": []
    }
  ],
  "paths": {
    "/wallet/v1/balance": {
      "post": {
        "summary": "Wallet balance",
        "operationId": "balance",
        "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
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authenticated authoritative response; Provider validates identity and amount.",
            "headers": {
              "X-Wallet-Signature": {
                "required": true,
                "schema": {
                  "type": "string"
                },
                "description": "HMAC-SHA256 over response, request nonce, status and SHA256(raw body), LF-separated."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "playerId": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string",
                      "pattern": "^[A-Z]{3}$"
                    },
                    "balance": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "playerId",
                    "currency",
                    "balance"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/wallet/v1/debit": {
      "post": {
        "summary": "Wallet debit",
        "operationId": "debit",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authenticated authoritative response; Provider validates identity and amount.",
            "headers": {
              "X-Wallet-Signature": {
                "required": true,
                "schema": {
                  "type": "string"
                },
                "description": "HMAC-SHA256 over response, request nonce, status and SHA256(raw body), LF-separated."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionResponse"
                }
              }
            }
          }
        }
      }
    },
    "/wallet/v1/credit": {
      "post": {
        "summary": "Wallet credit",
        "operationId": "credit",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authenticated authoritative response; Provider validates identity and amount.",
            "headers": {
              "X-Wallet-Signature": {
                "required": true,
                "schema": {
                  "type": "string"
                },
                "description": "HMAC-SHA256 over response, request nonce, status and SHA256(raw body), LF-separated."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionResponse"
                }
              }
            }
          }
        }
      }
    },
    "/wallet/v1/refund": {
      "post": {
        "summary": "Wallet refund",
        "operationId": "refund",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authenticated authoritative response; Provider validates identity and amount.",
            "headers": {
              "X-Wallet-Signature": {
                "required": true,
                "schema": {
                  "type": "string"
                },
                "description": "HMAC-SHA256 over response, request nonce, status and SHA256(raw body), LF-separated."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionResponse"
                }
              }
            }
          }
        }
      }
    },
    "/wallet/v1/transactions/query": {
      "post": {
        "summary": "Wallet transactions/query",
        "operationId": "transactions_query",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authenticated authoritative response; Provider validates identity and amount.",
            "headers": {
              "X-Wallet-Signature": {
                "required": true,
                "schema": {
                  "type": "string"
                },
                "description": "HMAC-SHA256 over response, request nonce, status and SHA256(raw body), LF-separated."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "AdminToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "ADMIN_TOKEN; management network only."
      },
      "PlayerToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "One-hour player session, obtained using a one-time launch token."
      },
      "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"
      },
      "TrackingToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Application-specific tracking credential returned on submission."
      },
      "PortalCookie": {
        "type": "apiKey",
        "in": "cookie",
        "name": "zodiac_portal",
        "description": "HttpOnly Secure SameSite=Strict session. Every POST additionally requires X-CSRF-Token returned at login or /auth/me. Temporary-password accounts must change password first."
      }
    },
    "schemas": {
      "TransactionRequest": {
        "type": "object",
        "properties": {
          "transactionId": {
            "type": "string"
          },
          "originalTransactionId": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "playerId": {
            "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."
          },
          "kind": {
            "enum": [
              "debit",
              "credit",
              "refund"
            ]
          },
          "betId": {
            "type": "string"
          },
          "issueNo": {
            "type": "string"
          },
          "gameCode": {
            "const": "western_zodiac_live"
          }
        },
        "required": [
          "transactionId",
          "originalTransactionId",
          "playerId",
          "currency",
          "amount",
          "kind",
          "betId",
          "issueNo",
          "gameCode"
        ],
        "additionalProperties": false
      },
      "TransactionResponse": {
        "type": "object",
        "properties": {
          "transactionId": {
            "type": "string"
          },
          "playerId": {
            "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."
          },
          "status": {
            "enum": [
              "succeeded",
              "declined",
              "pending",
              "not_found"
            ]
          },
          "walletReference": {
            "type": "string"
          }
        },
        "required": [
          "transactionId",
          "playerId",
          "currency",
          "amount",
          "status"
        ],
        "additionalProperties": false
      }
    }
  }
}
